1

I'm trying to make a lookupfield-like in my application.

The intention is that the user click on a browse-button, and it pops-up a dialog(widget) with a grid(CGridView) inside. The user could select a row, and the 'Description' column is sent to a textField into my form.

I've already done this part by registering the following script in the form:

Yii::app()->clientScript->registerScript('scriptName', '
function onSelectionChange()
{
        var keys = $("#CGridViewUsuario > div.keys > span");

        $("#CGridViewUsuario > table > tbody > tr").each(function(i)
        {
                if($(this).hasClass("selected"))
                {
                        $("#Funcionario_UsuarioId").val($(this).children(":nth-child(1)").text());
                }
        });
}
');

And my widget:

            <?php $this->beginWidget('zii.widgets.jui.CJuiDialog', array(
                    'id'=>'mydialog',

                    'options'=>array(
                        'title'=>'Usuário',
                        'width' => 'auto',
                        'autoOpen'=>false,
                    ),
                ));

            $this->widget('zii.widgets.grid.CGridView', array(
                'dataProvider' => Usuario::model()->searchByLogin($model->UsuarioId),
                'id' => 'CGridViewUsuario',
                'filter' => Usuario::model(),
                'columns' => array(
                    'Login',
                    'Nome',
                ),
                'htmlOptions' => array(
                    'style'=>'cursor: pointer;'
                    ),                   
                'selectionChanged'=>'js:function(id){ onSelectionChange(); }',
            ));

            $this->endWidget('zii.widgets.jui.CJuiDialog');
        ?>

Now there are two tasks for me to do:

  • When the user clicks the browse button, the CGridView should appear with the filter already filled with the input he typed in the form.

  • Put the CGridView filters to work.

Not forgetting that, If all this runs successfully, when the user clicks on the save button, I'll have to save the corresponding ID of the lookupField in the model.

MMalke
  • 1,857
  • 1
  • 24
  • 35
  • have you tried anything? i think i can do this, but don't want to repeat something you have already tried – bool.dev Jun 22 '12 at 14:12
  • Only the snippet above, and changing the 'dataprovider' to $model->search(), and the 'filters' to $model – MMalke Jun 22 '12 at 17:05

1 Answers1

1

You can, simply provide a callback function for the dialog's open event, and in the callback function

  1. use jquery selectors to select the input filters(of the gridview) you want to select, and populate its values from whichever field in the form you want:

    $("#CGridViewUsuario .filters input[name='Userio[login]']").val($("#Funcionario_UsuarioId").val());
    // replace the names/ids to whatever you are using,
    // if you want to set multiple values, then you might have to run a loop or each() or something of that sort
    
  2. then call the server to update the gridview according to the values you populated, using jquery.yiigridview.js' $.fn.yiiGridView.update function:

    $.fn.yiiGridView.update("CGridViewUsuario", {
       data: $("#CGridViewUsuario .filters input").serialize()
    });
    

    you can see the jquery.yiigridview.js file in the generated html, or in your assets folder, and within that you'll find the $.fn.yiiGridView.update function.

To subscribe to the dialog's open event you can pass the function name to the 'open' option of the dialog's 'options' field:

$this->beginWidget('zii.widgets.jui.CJuiDialog', array(
                'id'=>'mydialog',

                'options'=>array(
                    'title'=>'Usuário',
                    // other options

                    'open'=>'js:dialogOpenCallback'
                ),
));

And you can define the function in your registerScript() call itself:

<?php
  Yii::app()->clientScript->registerScript('scriptName', '
    function onSelectionChange()
    {...}

    function dialogOpenCallback(event,ui){
       $("#CGridViewUsuario .filters input[name='Userio[login]']").val($("#Funcionario_UsuarioId").val());
       // replace the names/ids to whatever you are using,
       $.fn.yiiGridView.update("CGridViewUsuario", {
          data: $("#CGridViewUsuario .filters input").serialize()
       });
    }
   ');

Further you can change how you are calling your onSelectionChange() function:

'selectionChanged'=>'js:onSelectionChange'//'js:function(id){ onSelectionChange(); }',

and change your function signature: function onSelectionChange(id).

Almost forgot, change your dataprovider and filter of the gridview, to model instances, and not static instances.

bool.dev
  • 17,508
  • 5
  • 69
  • 93
  • if you think i have missed out anything let me know, and i'll clarify – bool.dev Jun 22 '12 at 17:04
  • I'm trying it right now. The model instance i'll have to use in the dataProvider and filter of the gridView... are they models of my foreign key? – MMalke Jun 26 '12 at 14:29
  • For now it's all going well. the filter is working but only if I use it to filter by Id's. I would like to filter for example by the Description field of the related model (Funcionario have a Usuario). – MMalke Jun 26 '12 at 14:34
  • ofcourse the dataProvider and filter will be of related model, because the grid is of the related model, i.e Usuario. For your second comment, does Usuario have a Description field? – bool.dev Jun 26 '12 at 14:40
  • ok, then you'll have to change a few things, first in your grid, you have to add that column, i.e, your column field for the grid should look like this: `'columns' => array( 'Login', 'Nome','Decription' ),` , then you populate the value, as i have done for Login – bool.dev Jun 26 '12 at 14:57
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/13059/discussion-between-bool-dev-and-mmalke) – bool.dev Jun 26 '12 at 15:02