You are viewing revision #1 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.
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.
Add this to an CHtml extension:
class ZHtml extends CHtml
{
public function activeTextFieldHistory($model, $attribute, $htmlOptions=null)
{
$mod=$model;
$attr=$attribute;
self::resolveNameID($mod,$attr,$htmlOptions);
$route=array('/site/search', 'model'=>get_class($model), 'attribute'=>$attr);
if (isset($htmlOptions['filter']))
{
$route['filter']=$htmlOptions['filter'];
unset($htmlOptions['filter']);
}
$this->widget('zii.widgets.jui.CJuiAutoComplete',
array('model'=>$model,
'attribute'=>$attr,
'htmlOptions'=>$htmlOptions,
'sourceUrl'=>$route));
}
}
You can pass additional configuration for the search (e.g, some more condition limiting the search in a project/group, sorting or whatever else)
And add this to your SiteController:
public function actionSearch()
{
$model=$_GET['model'];
$attribute= $_GET['attribute'];
$param=addslashes($_GET['term']);
$results=array();
$criteria=new CDbCriteria;
$criteria->condition="$attribute IS NOT NULL AND $attribute LIKE '%$param%' ";
if (isset($_GET['filter']))
$criteria->condition.=' AND '.$_GET['filter'];
$criteria->group=$attribute;
$criteria->order="COUNT($attribute) desc";
$criteria->limit=5;
$records=CActiveRecord::model($model)->findAll($criteria);
foreach ($records as $record)
$results[]=$record->$attribute;
echo CJSON::encode($results);
}
Now you can create your search textfield as:
ZHtml::activeTextFieldHistory($model, 'color');
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.