Question

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.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top