Yii – CAutoComplete

20.03.2011

Использование CAutoComplete в Yii

В своем последнем проекте столкнулся с необходимостью сделать автодополнение слов в строке поиска. Эти слова кэшируются в БД во время поиска, следовательно при вводе поискового запроса происходит выбор из базы кэшированных слов и автодополнение в случае совпадения.

Итак, приступим - основная таблица, по которой происходит поиск - phones, таблица для autocomplete - cachequery. Структура баз данных (чисто переменные, всё просто) -

CacheQuery:

* @property integer $id

* @property string $query

Где, $id - идентификатор, $query - кэшированный запрос;

Phones:

* @property integer $id

* @property string $category

* @property string $phone

* @property string $email

* @property string $title

* @property string $address

* @property string $description
Тут всё ясно: идентификатор, сатегория(рубрика), телефон, e-mail, название, адрес и описание.

В поиске участвуют: категория, телефон, название, адрес и описание. Перейдем к контроллерам.

PhonesController:
экшен для autocomplete

 

public function actionAutoComplete() {  
 
  if(Yii::app()->request->isAjaxRequest && isset($_GET['q'])) {
 
    $criteria = new CDbCriteria;
 
    $criteria->condition = "query LIKE :tquery";
 
    $criteria->params = array(":tquery"=>'%'.$_GET['q'].'%');
 
    if (isset($_GET['limit']) && is_numeric($_GET['limit'])) {
 
      $criteria->limit = $_GET['limit'];
 
    }
 
    $queries = Cachequery::model()->findAll($criteria);
 
    $resStr = '';
 
    foreach($queries as $tmpquery) {
 
      $resStr .= $tmpquery->query."\n";
 
    }
 
    echo $resStr;
 
  }
 
}

 

Более подробное описание в на сайте yii, ссылка внизу. Но некоторые моменты затрону: формируем критерий поиска в базе Cachequery:

 

$criteria->condition = "query LIKE :tquery";
 
// определяем поле для поиска - query
 
$criteria->params = array(":tquery"=>'%'.$_GET['q'].'%');
 
//  $_GET['q'] - переменная, содержащая символы, введенные пользователем
 
$queries = Cachequery::model()->findAll($criteria);
 
// сам запрос к таблице

 

Кроме этого необходимо учитывать что в базу с запросами нужно записывать только уникальные запросы, т.е. в экшен, где происходит поиск в конец дописываем:

 

$cachequery = Cachequery::model()->find('query=:query',array(':query'=>$_POST['searchField']));
 
if(!$cachequery) {
 
  $newQuery = new Cachequery();
 
  $newQuery->query = $_POST['searchField'];
 
  $newQuery->save();
 
}

 

Кстати, для добавления можно придумать кое-что интереснее:

 

$sql = 'INSERT INTO cache_query (query)
 
VALUES(:query)
 
ON DUPLICATE KEY UPDATE query=:query';

 

Или даже так:

$sql = 'INSERT IGNORE INTO cache_query SET query=:query';

После всего этого не забываем добавить в accessRules():

array('allow', 'actions'=>array('index', 'AutoComplete','contact','login','logout','captcha')...

Ну и теперь представление:

 

widget('CAutoComplete', array(
 
  'name'=>'searchField',
 
  'url'=>array('phones/AutoComplete'), // маршрут до экшена autocomplete
 
  'value'=>'введите название, адрес или телефон',
 
  'max'=>10,
 
  'minChars'=>2,
 
  'delay'=>0,
 
  'matchCase'=>false,
 
  'htmlOptions'=>array('size'=>'40'),
 
));

 

Хотел бы добавить - можно использовать CActiveForm, или же для автодополнения - СJuiAutoComplete, алогритм одинаковый.
Ссылки:
API - CAutoComplete
Хорошая статья - Yii PHP фреймворк: создаем поле с автозаполнением

blog comments powered by Disqus
Наверх