Using filters with CGridView and CArrayDataProvider

You are viewing revision #7 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.

« previous (#6)next (#8) »

  1. Model
  2. Controller
  3. View

Using filters on CGridView with CActiveDataProvider is easy, but with CArrayDataProvider it is a bit tricky.

To use the filters you have to create a separate model class. I used some code from the following forum topic: link

Note: Normally, when you have an array of CModels, you should use CActiveDataProvider instead!

Here is some example code:

Model

Copy and include this class into your application.

<?php

/**
 * Filterform to use filters in combination with CArrayDataProvider and CGridView
 * @see http://www.yiiframework.com/wiki/232/using-filters-with-cgridview-and-carraydataprovider/
 */
class FiltersForm extends CFormModel
{
	/**
	 * @var array filters, key => filter string
	 */
	public $filters = array();

	/**
	 * Override magic getter for filters
	 * @param string $name
	 */
	public function __get($name)
	{
		if (!array_key_exists($name, $this->filters)) {
			$this->filters[$name] = '';
		}
		return $this->filters[$name];
	}

	/**
	 * Override magic setter for filters
	 * @param string $name
	 * @param mixed $value
	 */
	public function __set($name, $value)
	{
		$this->filters[$name] = $value;
	}

	/**
	 * Filter input array by key value pairs
	 * @param array $data rawData
	 * @return array filtered data array
	 */
	public function filter(array $data)
	{
		foreach ($data AS $rowIndex => $row) {
			foreach ($this->filters AS $key => $searchValue) {
				if (!empty($searchValue)) {
					$compareValue = null;

					if ($row instanceof CModel) {
						if (isset($row->$key) == false) {
							throw new CException("Property " . get_class($row) . "::{$key} does not exist!");
						}
						$compareValue = $row->$key;
					} elseif (is_array($row)) {
						if (!array_key_exists($key, $row)) {
							throw new CException("Key {$key} does not exist in array!");
						}
						$compareValue = $row[$key];
					} else {
						throw new CException("Data in CArrayDataProvider must be an array of arrays or an array of CModels!");
					}

					if (stripos($compareValue, $searchValue) === false) {
						unset($data[$rowIndex]);
					}
				}
			}
		}
		return $data;
	}

}

(By @KonApaz) If you want to apply full comparisons (>, <, >=, <=, =) use this

if (substr($searchValue, 0, 2) == '<=') {
    if ($compareValue > substr($searchValue, 2)) {
        unset($data[$rowIndex]);
    }
} else if (substr($searchValue, 0, 2) == '>=') {
    if ($compareValue < substr($searchValue, 2)) {
        unset($data[$rowIndex]);
    }
} else if ($searchValue[0] == '<') {
    if ($compareValue >= substr($searchValue, 1)) {
        unset($data[$rowIndex]);
    }
} else if ($searchValue[0] == '>') {
    if ($compareValue <= substr($searchValue, 1)) {
        unset($data[$rowIndex]);
    }
} else if (stripos($compareValue, $searchValue) === false) {
    unset($data[$rowIndex]);
}

Controller

// Create filter model and set properties
$filtersForm=new FiltersForm;
if (isset($_GET['FiltersForm']))
    $filtersForm->filters=$_GET['FiltersForm'];

// Get rawData and create dataProvider
$rawData=User::model()->findAll();
$filteredData=$filtersForm->filter($rawData);
$dataProvider=new CArrayDataProvider($filteredData);

// Render
$this->render('index', array(
    'filtersForm' => $filtersForm,
    'dataProvider' => $dataProvider,
));

View

$columns = array(
	array(
		'header'=>CHtml::encode('Name'),
		'name'=>'username',
	),
	array(
		'header'=>CHtml::encode('Organisation'),
		'name'=>'organisation',
	),
);

$this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'area-grid',
    'dataProvider'=>$dataProvider,
    'columns'=>$columns,
    'filter'=>$filtersForm,
));
19 0
29 followers
Viewed: 92 835 times
Version: Unknown (update)
Category: How-tos
Written by: marcovtwout
Last updated by: yugene
Created on: Sep 12, 2011
Last updated: 10 years ago
Update Article

Revisions

View all history

Related Articles