Yii 1.1: datafilter

Search and filtration capabilities for data grids
9 followers

This extension can be used to add search and filtration capabilities to data grids.

Resources

Documentation

Requirements

  • Tested on Yii 1.0.8

Installation

  • Extract the release file under protected/extensions

Note

Documentation updated for version 0.2. Documentation for version 0.1 can be found in CDataFilter.php.

Usage

Inside controller:

public function actionAdmin()
    {
        $this->processAdminCommand();
 
        $criteria=new CDbCriteria;
 
        //filters group for Group, City, Country, group object created explicitly
        $fromGroup = new CFilterGroup('Filter', array('cssClass'=>'dataFilterBlock'));
        $fromFilterOptions = array('emptyValue'=>'All', 'specialOptions'=>array('null'=>'None'));
 
        //filters group for Group and City without autosubmit, used custom view
        $filterNoAutoGroup = new CFilterGroup('Filter (no autosubmit)',
            array('view'=>'application.views.user.dataFilterGroupWithSubmit'));
 
        $filters = new CDataFilter(User::model());
        $filters->addFilter(new CFilterSearch('userFieldsSearch'), 'Search');
        $filters->addFilter(new CFilterDropdown('Group', $fromFilterOptions), $fromGroup);
        $filters->addFilter(new CFilterDropdown('Country', $fromFilterOptions), $fromGroup);
        $filters->addFilter(new CFilterDropdown('City', $fromFilterOptions), $fromGroup);
 
        $filters->addFilter(new CFilterDropdown('activeDropFilter',
            array('displayName'=>'Active')),
            //group is given as name (string), not as object
            //this filter will be joined to 'Filter' group, because group with same name already exists
            'Filter'
        );
 
        // two filters without autosubmit
        // submit button is placed in custom view (see views/user/dataFilterGroupWithSubmit.php)
        $filters->addFilter(new CFilterDropdown('groupFilter2',
                array('displayName'=>'Group', 'emptyValue'=>'All', 'specialOptions'=>array('null'=>'None'),
                    'autoSubmit'=>false)
            ), $filterNoAutoGroup
        );
        $filters->addFilter(new CFilterDropdown('countryFilter2',
                array('displayName'=>'Country', 'emptyValue'=>'All', 'specialOptions'=>array('null'=>'None'),
                    'autoSubmit'=>false)
            ), $filterNoAutoGroup
        );
 
        // two link filters, all users is a default filter (highlighted if no other filters applied)
        $filters->addFilter(new CFilterLink('activeFilter', 'All Users', 'all', true), 'Show');
        $filters->addFilter(new CFilterLink('activeFilter', 'Active Users', 'active'), 'Show');
 
        $filters->applyCriteria($criteria);
 
        $pages=new CPagination(User::model()->count($criteria));
        $pages->pageSize=self::PAGE_SIZE;
        $pages->applyLimit($criteria);
 
        $sort=new CSort('User');
        $sort->applyOrder($criteria);
 
        $models=User::model()->findAll($criteria);
 
        $this->render('admin',compact(
            'models', 'pages', 'sort', 'filters'
        ));
    }

Model should provide following methods:

  • getDataFilterOptions($filterName) for CFilterDropdown and CFilterLink
  • getDataFilterSearchFields($filterName) for CFilterSearch
  • applyDataFilterCriteria(&$criteria, $filterName, $filterValue) for CFilterDropdown and CFilterLink
  • applyDataSearchCriteria(&$criteria, $filterName, $searchField, $serachValue) for CFilterSearch

Inside model:

// Returns list of searchable fileds for DataFilter widget
    public function getDataFilterSearchFields($filterName)
    {
        switch ($filterName) {
            case 'userFieldsSearch': //filter name
                return array(
                    'df_users.id'=>'User ID', //field name => display name
                    'df_users.name'=>'Name',
                    'df_users.username'=>'Username',
                );
        }
    }
 
    // Applies search criteria enterd using DataFilter widget
    public function applyDataSearchCriteria(&$criteria, $filterName, $searchField, $searchValue)
    {
        if($filterName == 'userFieldsSearch') {
            $localCriteria = new CDbCriteria;
            $localCriteria->condition = ' '.$searchField.' LIKE "%'.$searchValue.'%" ';
            //$localCriteria->condition = ' '.$searchField.' LIKE "%:searchValue%" ';
            //$localCriteria->params = array(':searchValue'=>$searchValue); //"'%1%'" //".$searchValue."
            $criteria->mergeWith($localCriteria);
        }
    }
 
    // Returns options for DataFilter widget
    public function getDataFilterOptions($filterName)
    {
        switch ($filterName) {
            case 'Group':  //filter name
            case 'groupFilter2':
                // data from database
                $groups = Group::model()->findAll();
                return CHtml::listData($groups, 'id', 'name');
            case 'Country':
            case 'countryFilter2':
                $countries = Country::model()->findAll();
                return CHtml::listData($countries, 'id', 'name');
            case 'City':
                $criteria = new CDbCriteria;
                $country = Yii::app()->request->getParam('countryFilter');
                // city filter depends from country filter
                if (isset($country) && !empty($country)) {
                    $criteria->condition = ' countries_id = :country';
                    $criteria->params = array(':country'=>$country);
                }
                $cities = City::model()->findAll($criteria);
                return CHtml::listData($cities, 'id', 'name');
           case 'activeDropFilter':
                // static data (not from database)
                $options = array(
                    array('id'=>'', 'name'=>'All'),
                    array('id'=>0, 'name'=>'Not active'),
                    array('id'=>1, 'name'=>'Active'),
                );
                return CHtml::listData($options, 'id', 'name');
        }
    }
 
    // Applies filter criteria enterd using DataFilter widget
    public function applyDataFilterCriteria(&$criteria, $filterName, $filterValue)
    {
        if($filterName == 'Group' || $filterName == 'groupFilter2') {
            $localCriteria = new CDbCriteria;
            CDataFilter::setCondition('user_groups_id', $filterValue, $localCriteria);
            $criteria->mergeWith($localCriteria);
        }
 
        if($filterName == 'Country' || $filterName == 'countryFilter2') {
            $localCriteria = new CDbCriteria;
            //'null' value is a spectial option for coutryFilter
            if ($filterValue != 'null') {
                $localCriteria->select = 'df_users.*';
                $localCriteria->join =
                    'INNER JOIN `df_cities` cities
                    ON (`df_users`.`cities_id`=cities.`id`)
                    AND (cities.countries_id = :countryID) ';
                $localCriteria->params = array(':countryID'=>$filterValue);
                //$localCriteria->group = ' df_users.id ';
            } else {
                $localCriteria->condition = ' cities_id is null ';
            }
            $criteria->mergeWith($localCriteria);
        }
 
        if($filterName == 'City') {
            $localCriteria = new CDbCriteria;
            CDataFilter::setCondition('cities_id', $filterValue, $localCriteria);
            $criteria->mergeWith($localCriteria);
        }
 
        if($filterName == 'activeFilter') {
            if ($filterValue !== 'active') return;
            $localCriteria = new CDbCriteria;
            CDataFilter::setCondition('is_active', 1, $localCriteria);
            $criteria->mergeWith($localCriteria);
        }
 
        if($filterName == 'activeDropFilter') {
            $localCriteria = new CDbCriteria;
            CDataFilter::setCondition('is_active', $filterValue, $localCriteria);
            $criteria->mergeWith($localCriteria);
        }
 
    }

Inside view:

<?php $this->widget('CDataFilterWidget',array('filters'=>$filters)); ?>
 
OR
 
// enable ajax filtering / searching - '#updateData' selector will be replaced
<?php $this->widget('CDataFilterWidget',array('filters'=>$filters,
       'ajaxMode'=>true, 'updateSelector'=>'#updateData')); ?>

Change Log

October 17, 2009 (v0.3)

  • fixed bug: wrong CFilterBase::applyCriteria declaration (reported by PHP when E_STRICT is enabled)

September 18, 2009 (v0.3)

  • CDataFilterWidget: options to generate submit and reset buttons
  • CDataFilter: option to store filter state to the session
  • Demo app: added a tab 'Users(no autosubmit)' - demo for Reset / Submit and store to session
  • Demo App: text descriptions for each demo tab
  • Fixed: Did not work on servers where appplication work not in root folder (added normalizeUrl() for form action)

September 4, 2009 (v0.2)

  • Demo application (including demo for ajax mode)
  • Ability to turn of autosubmit (submit after changed) for dropdown filters
  • Filter's form configuration - ability to set action, method and options
  • Filters group can be configured to use custom view
  • Filters can be grouped together
  • New filter type - CFilterLink - outputs a set of links to filter table data
  • Fixed: zero values treated as default and empty. Now zero values can be used as filters values.
  • Refactoring - base class for filter and subclasses for different filter types CFilterDropdown for dropdown filters, CFilterSearch - for search

July 18, 2009

  • Initial release.

Total 1 comment

#1389 report it
duplabe at 2009/08/14 09:21am
not integer values

Hi!

It's a really great ext, save for me a lot of work :)

I have a question: Why have to use int values in the drop down lists?

Leave a comment

Please to leave your comment.

Create extension
  • Yii Version: 1.1
  • License: New BSD License
  • Developed by: seb
  • Category: User Interface
  • Votes: +3
  • Downloaded: 2,322 times
  • Created on: Jul 18, 2009
  • Last updated: Oct 17, 2009