Creating an instant search box for the CListView
Published on 1/14/2011
We have our index page, with a CListView displaying a list of items, in this case contacts.
We want a single “instant” search box, that will filter the contacts list instantly.
Your index.php view page should look something like this:
<?php
$this->breadcrumbs=array(
'Contacts',
);
$this->menu=array(
array('label'=>'Create Contact', 'url'=>array('create')),
array('label'=>'Manage Contact', 'url'=>array('admin')),
);
//this adds a javascript event listener to the search box that will query the server with each keystroke. yw0 is the id of the clistview. q is the id of the text input box:
Yii::app()->clientScript->registerScript('search', "
$('input#q').keyup(function(){
$.fn.yiiListView.update('yw0', {
data: $(this).serialize()
});
return false;
});
");
?>
<h1>Contacts</h1>
<!-- add a search box: -->
<input type="text" id="q" name="q" />
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
)); ?>
Change your actionIndex function in your ContactController to look something like this:
public function actionIndex() {
$model = new Contact($scenario='search');
$model->unsetAttributes();
$model->first_name = $_GET['q'];
//add the ->search() call:
$this->render('index',array('dataProvider'=>$model->search()))
}
Now when you type in the field, it should filter the contacts by their first name.
Improvements:
- change onkeyup so it fires with a few characters and after a small delay
- add a new search() function that will search several attributes at once using “OR” instead of “AND”. This can be done in the compare() function with the 4th argument.
- Some heavy caching on the server so that the database is not overwhelmed.