History Autocomplete

You are viewing revision #3 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.

« previous (#2)

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.