What for? ΒΆ
In application development we often have to choose how to mange recurrent values.
For example, a field color for a cloath. You cannot leave free text, because there whould be too much typos, but you cannot enumerate all possibility because they are a lot and sometime there are new colors.
Often you can solve with a foreign field, with an interface for add a new color. That's great if adding new color is a quite rare operation, if it happens too often and if the users are too stupid for remember how to add a color, it can be odd.
I propose an half way solution: a free text with autocomplete based on history values.
We will use CJuiAutoComplete, what we need is a efficient way for perform searches.
Add this to your components/extensions:
class SearchAction extends CAction
{
public $model;
public $attribute;
public $criteria=array('limit'=>5);
public function run()
{
$criteria=new CDbCriteria($this->criteria);
$criteria->addCondition("{$this->attribute} IS NOT NULL AND {$this->attribute} LIKE :param");
$criteria->group=$this->attribute;
$criteria->order="COUNT({$this->attribute}) desc";
$criteria->params[':param']='%'.$_GET['term'].'%';
$results=array();
foreach (CActiveRecord::model($this->model)->findAll($criteria) as $record)
$results[]=$record->{$this->attribute};
echo CJSON::encode($results);
}
}
Now we can configure a search action in our controller like that:
public function actions()
{
return array(
'searchCompany'=>array(
'class'=>'SearchAction',
'model'=>'Request',
'attribute'=>'company',
)
);
}
You can pass additional configuration for the search (e.g, some more condition limiting the search in a project/group, sorting or whatever else) using the property $criteria.
Now you can create your search textfield as:
<?php $this->widget('zii.widgets.jui.CJuiAutoComplete',
array('model'=>$model,
'attribute'=>'company',
'htmlOptions'=> array('maxlength'=>300, 'class'=>'text'),
'sourceUrl'=>'searchCompany'));?>
This method is quite efficient and usually customer like it, because is based on the laziness of the users.
User Contributed Notes 2
problem with $this
Hi,
Thanks for the inspiring article.
The
public function activeTextFieldHistoryshould bepublic static function activeTextFieldHistory, right?I used a similar code: I created a static function in my GxHtml class (extends CHtml, like your ZHtml class). In this function I call
~~~
$this->widget(...);
~~~
which produces the error
Using $this when not in object contextDid your code above work without this error?
Solved: Instead of
~~~
$this->widget(...);~~~
the following worked:
~~~
$w = new CWidget;
$w->widget(...);
~~~
Security issue
It appears that this stuff is quite unsafe, in fact it expose the whole database to be queried out, a malicious user can simply change the search url to:
And get all the username, then the same with passwords end enjoy the combinations.
I have updated the tutorial in order to use an action configurable, for fix the paramter that is supposed to be searched...
Leave a comment
If you have any questions, please ask in the forum instead.
Join the conversation to share a note.