Note: CAutoComplete is deprecated since Yii 1.1.3. Consider using CJuiAutoComplete.
Have you ever wanted to use an auto-complete field to look up a user or some other data, but want the database ID of that user or data returned as well so that you can more easily perform some function when the form is submitted? Thanks to Yii's CAutoComplete widget and jQuery's Autocomplete plugin, it's really quite simple.
In overview, assuming that you are looking up and retrieving your data set for the autocomplete widget from a database, there are basically three steps:
While not all features and options are explored, here is a sample of how to implement the above steps.
In your controller, create a new action to handle autocomplete lookup queries, like so:
//Action public function actionAutoCompleteLookup() { if(Yii::app()->request->isAjaxRequest && isset($_GET['q'])) { /* q is the default GET variable name that is used by / the autocomplete widget to pass in user input */ $name = $_GET['q']; // this was set with the "max" attribute of the CAutoComplete widget $limit = min($_GET['limit'], 50); $criteria = new CDbCriteria; $criteria->condition = "name LIKE :sterm"; $criteria->params = array(":sterm"=>"%$name%"); $criteria->limit = $limit; $userArray = User::model()->findAll($criteria); $returnVal = ''; foreach($userArray as $userAccount) { $returnVal .= $userAccount->getAttribute('name').'|' .$userAccount->getAttribute('user_id')."\n"; } echo $returnVal; } }
There are a few things to notice here:
Now, in your view file, embed the following code within your form:
$this->widget('CAutoComplete', array( //name of the html field that will be generated 'name'=>'user_name', //replace controller/action with real ids 'url'=>array('controller/action'), 'max'=>10, //specifies the max number of items to display //specifies the number of chars that must be entered //before autocomplete initiates a lookup 'minChars'=>2, 'delay'=>500, //number of milliseconds before lookup occurs 'matchCase'=>false, //match case when performing a lookup? //any additional html attributes that go inside of //the input field can be defined here 'htmlOptions'=>array('size'=>'40'), 'methodChain'=>".result(function(event,item){\$(\"#user_id\").val(item[1]);})", )); <?php echo CHtml::hiddenField('user_id');
Take note of the methodChain attribute being used. MethodChain essentially appends (or chains) a javascript method to the end of the AutoComplete javascript code that will be generated. This particular method is the result method, which fires when an autocomplete item is selected. The code inside of the result function basically references the hidden field that was defined and assigns the 2nd part (part after the pipe) of the selected autocomplete data to that field.
Now that the basics are out of the way, review the documentation for Yii's CAutoComplete widget and jQuery's Autocomplete plugin to find more ways to customize and use autocomplete functionality in your Yii project.
Total 5 comments
This class is deprecated since Yii 1.1.3. Consider using CJuiAutoComplete. There is a implementation solutions.
its very useful
hi, i want to have two autocomplete fields in the same form, The second field should depend on first field's value.
i tried to do this:
view:
first field controller action:
second field conroller action:
the $_POST['city_id] didn't work..
please help.
you must add the action ' autoCompleteLookup ', to the controller's accessRules function.
My dear friends, width a couple more of study hours I find out how to it, I mean how to format the dropdown list of results. It turns out that … her … it is quite easy!
Just for the sake of letting you understand what I want, I'll drop a line or two about it. I would like that the result terms in the autocomplete dropdown list would show a small image along side with some text (searched for).
My first attempt was to add a small image to the $returnVal variable in the actionAutoCompleteLookup action in my controller like this:
foreach($isssArray as $iss) { $returnVal .= '
'.' '.$iss->getAttribute('name').'|'.$iss->getAttribute('id')."\n";
}
This worked exactly the way I wanted but when the user selected one item in the drop down list it would show in the textbox with all the html of the image. So clearly I would need some sort of a way to separate the image from the searchable text.
It turns out that the widget already as this concept developed is just a matter of knowing how to use it!
There is a small change needed to be made in the returnVal shown above:
foreach($isssArray as $iss) { $returnVal .= $iss->getAttribute('name').'|'.$iss->getAttribute('id').'|'.'
'."\n";
}
This way the returned variable will be an array with 3 positions: 0=name (the field searched); 1=id of the register; 2=the image
Now is just a matter of telling the widget how to use this 3 elements of the result array!
This is done using the function formatItem (what a clever name, hugh!?).
'formatItem'=>"function(result, i, num, term) {return result[2] +' '+ result[0]; }", 'methodChain'=>".result(function(event,item){\$(\"#Project_charitableOrganizationId\").val(item[1]);})",
As you can see, formatItem uses the position 2 and 0 of the returnValue (image folloed by the text) and methodChain defines the Id of the user selected row in the dropdown list.
Sorry for the long post, hope this will eventually help someone out there.
Best regards, Rui Isidro
Leave a comment
Please login to leave your comment.