You are viewing revision #2 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version or see the changes made in this revision.
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.
problem with $this
Hi,
Thanks for the inspiring article.
The
public function activeTextFieldHistory
should 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 context
Did 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...
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.