CJuiAutoComplete HowTo

Hi there,

until now i used the CAutocomplete to display one value and submit another like shown in

Cookbook 25

Now this widget is deprecated and we all have to use CJuiAutocomplete, but i can’t figure out how!

Please can someone explain me how to do the same as in Cookbook 25 ?

Thanks a lot.

take a look here

Hope that help.

No that doesn’t help, because it only shows how to fill the field. I saw it before.

What i need is, that the field is filled with a string like "Firstname, Lastname" and the ID of this selection is submitted.

Oh sorry for misunderstood, again you can try two link below:

1/ Set up your autocomplete options (focus and select)

Look here

2/ Script of focus and select:

see more focus and select here

Hope that help!

No example for me?

Take a look

I am sorry could not give you full example code 'cause i have no time now. Still doing project. But have source link then keep read and practice is a better way than :)

Perhaps this example can help you out.

/Tommy

CAutoComplete had/has a usefull attribute "methodChain",

does anybody have a clue how to get this functionality with the CJuiAutocomplete?

thanks for trying to help.

@daonhack: we have had this link before, but i am realy new to this (working with CJuiAutocomplete).

@tri: i tried this example before, but the id doesn’t get posted, and if i change the value in this array to the id i need for post, it is shown in autocomplete-field after selection. i’d like to get the value shown in the autocomplete-field and the ID set in an hiddenfield or else on selecting an entry in the autocomplete-field.

@mdomba: yes, this is what i am searching for too :o)

Method chain has not hiers in CJuiAutocomplete, maybe we should ask in feature request.

I had to workaround it by hardcoding "autocomplete(call)".

Anyway, if you need methodChain for attach a function at the select, you can use the option ‘select’, is implemented by jquery.

how would i have to use the option select?

i tried it the following way, but it didn’t work …




$this->widget('zii.widgets.jui.CJuiAutoComplete', array(

    'name'=>'test1',

    'value'=>'test21',

    'source'=>$this->createUrl('jui/autocompleteTest'),

    // additional javascript options for the autocomplete plugin

    'options'=>array(

        'showAnim'=>'fold',

        'select'=>'alert("hello"); return true;'

    ),

    'cssFile'=>false,

));



and if i get the list by following code, how do i get the ID in the widget to set it into a hidden-fields value?




$arr = array();

foreach($models as $model) {

    $arr[] = array(

        'label'=>$model->some_attr,  // label for dropdown list          

        'value'=>$model->some_attr,  // value for input field          

        'id'=>$model->id,            // return value from autocomplete

        );      

}

echo CJSON::encode($arr);



I have this example




'select'=>"js:function(event, ui) {

  $('#".CHtml::activeId($model, 'some_attribute')."').val(ui.item.id);

  $.ajax({

    url: 'some_secondary_lookup_action',

    data: {id: ui.item.id},

    success: function(html) { $('#some_echoed_result').html(html);}

  });

}



/Tommy

ok, i’ll try it tonight at home and tell you if it did work :)

thank you all

ok, here the resolution for the problem:

in _form.php i did following:




<?php echo $form->hiddenField($model,'user_id',array()); ?>


$this->widget('zii.widgets.jui.CJuiAutoComplete', array(

    'model'=>$model,

    'attribute'=>'username',

    'source'=>$this->createUrl('jui/autocompleteTest'),

    // additional javascript options for the autocomplete plugin

    'options'=>array(

        'showAnim'=>'fold',

        'select'=>"js:function(event, ui) {

                                          $('#User_user_id').val(ui.item.id);

                                        }"

    ),

    'cssFile'=>false,

));



in JuiController.php i did following in actionAutocompleteTest():




$arr = array();

foreach($models as $model) {

    $arr[] = array(

        'label'=>$model->some_attr,  // label for dropdown list          

        'value'=>$model->some_attr,  // value for input field          

        'id'=>$model->id,            // return value from autocomplete

        );      

}

echo CJSON::encode($arr);



I can’ t get my sample to work :o .

  1. Did you enclose your _form.php with enableAjaxValidation at true ?
  1. in actionAutocompleteTest() did you use it together with some test like
  1. I suppose no call to $this->render(’… is necessary and that CJSON::encode($arr) does the trick ?

Any answer is much appreciated :) !

1.) no, i didn’t enable AjaxValidation

2.) no, i did no tests at all, but i should do and i don’t think the problem is here

3.) yes, you are right. no rendering needed. only echoing by "echo CJSON::…"

I prepared a farm test here

The callback doesn’t seem to be fired

And when I press the button: this is what appear from the JSON return


Array ( [r] => site/autoCompleteTest )

Array ( [Countries_id] => [Countries] => Array ( [cname] => afg ) [yt0] => Start Search )

afg=keyword

[{"label":"Afghanistan","value":"1","id":"1"}]



Which is correct but doesn’t fill back the field.

Any suggestion ?

I have a question, is there a way to update the value of the autoComplete input field on select ?

For example, on an autoComplete Suburb field which contains suburb, postcode, I want only suburb to show up after an option is selected.

I tried to set the value to only show suburb in the select event but it didn’t work, it always go back to the full string of suburb & postcode.

I reopen the discussion about method chain.

If is possible to use a custom seletc without it, it is not possible (at least, I couldn’t) to stylize properly the items, like in this example.

The only way I found is to implement the method chain in CJuiAutoComplete, it is quite simple as this class has less than 40 lines of code, I just copied all and added 2 small changes:

Here my solution:




<?php




Yii::import('zii.widgets.jui.CJuiInputWidget');


class FJuiAutoComplete extends CJuiInputWidget

{

        public $source = array();

        public $sourceUrl;

/* first change */  

      public $methodChain = null;


        public function run()

        {

                list($name,$id)=$this->resolveNameID();


                if(isset($this->htmlOptions['id']))

                        $id=$this->htmlOptions['id'];

                else

                        $this->htmlOptions['id']=$id;


                if(isset($this->htmlOptions['name']))

                        $name=$this->htmlOptions['name'];


                if($this->hasModel())

                        echo CHtml::activeTextField($this->model,$this->attribute,$this->htmlOptions);

                else

                        echo CHtml::textField($name,$this->value,$this->htmlOptions);


                if($this->sourceUrl!==null)

                        $this->options['source']=CHtml::normalizeUrl($this->sourceUrl);

                else

                        $this->options['source']=$this->source;


                $options=CJavaScript::encode($this->options);

/*second change*/

                $js = "jQuery('#{$id}').autocomplete($options){$this->methodChain};";


                $cs = Yii::app()->getClientScript();

                $cs->registerScript(__CLASS__.'#'.$id, $js);

        }

}




To developers: do you consider this solution valid, and will you include in future release of the framework? It really gives more possiblity of usage for the JuiAutoComplete

Hi, that worked very well for me. I made an addition and maybe someone may find it useful.


    'options'=>array(

        'showAnim'=>'fold',

        'select'=>"js:function(event, ui) {

                                          $('#User_user_id').val(ui.item.id);

                                        }",

        'change'=>"js:function(event, ui) {

                                          if (!ui.item) {

                                             $('#User_user_id').val('');

                                          }

                                        }",

    ),

The idea is that if the user changes the value, I delete the the id. For example, if there is a user called ‘John Smith’ with an Id = 24, the widget will return the id if ‘John Smith’ is selected from the list, but if is changed to ‘John Smithson’, then the Id will come blank.

I am still testing it but it has worked so far