This plugin is a fork of Jose Diaz-Gonzalez’s Filter component, which is something of a fork of James Fairhurst’s Filter Component, which is in turn a fork by Maciej Grajcarek, which is ITSELF a fork from Nik Chankov’s code. Chad Jablonski then added RANGE support with a few bug fixes. jmroth pointed out a pretty bad redirect issue and “fixed it”. Then Jose Diaz-Gonzalez took everyone’s changes, merged them together, and updated the Component to be a bit more 1.3 compliant.
That’s a lot of forks…
This also contains a view helper made by Matt Curry.
This also uses a behavior adapted from work by Brenton to allow for HasAndBelongsToMany and HasMany relationships.
This works for all relationships.
- Clone from github : in your plugin directory type
git clone git://github.com/josegonzalez/cakephp-filter-plugin.git filter
- Add as a git submodule : from your app/ directory type
git submodule add git://github.com/josegonzalez/cakephp-filter-plugin.git plugins/filter
- Download an archive from github and extract the contents into
/plugins/filter
- Include the component in your controller (AppController or otherwise)
var $components = array('Filter.Filter');
- Use something like the following in your index
function index() {
$this->paginate = $this->Filter->paginate;
$posts = $this->paginate();
$this->set(compact('posts'));
}
- Finished example:
<?php
class PostsController extends AppController {
var $components = array('Filter.Filter');
function index() {
$this->paginate = $this->Filter->paginate;
$posts = $this->paginate();
$this->set(compact('posts'));
}
}
?>
In order for this to work in 1.2, you need to have the following in your controller:
<?php
class PostsController extends AppController {
var $components = array('Filter.Filter');
function index() {
$this->paginate = $this->Filter->paginate;
$filterOptions = $this->Filter->filterOptions;
$posts = $this->paginate();
$this->set(compact('filterOptions', 'posts'));
}
}
?>
And then merge the $filterOptions variable on anything pagination uses. It can be set globally using PaginatorHelper::options() as follows (in the view):
<?php $paginator->options($filterOptions); ?>
By setting the $paginate
variable for your controller, the Filter component merges those into it’s own rules before processing incoming information.
<?php
class PostsController extends AppController {
var $name = 'Posts';
var $components = array('Filter.Filter');
var $paginate = array('contain' => array('Comment'), 'limit' => 5);
function index() {
$this->paginate = $this->Filter->paginate;
$posts = $this->paginate();
$this->set(compact('posts'));
}
}
?>
You can merge in things to the paginate array before any pagination happens if necessary.
<?php
class PostsController extends AppController {
var $name = 'Posts';
var $components = array('Filter.Filter');
function index() {
$this->paginate = array_merge($this->Filter->paginate,
array('contain' => array('Comment'), 'limit' => 5)
);
$posts = $this->paginate();
$this->set(compact('posts'));
}
}
?>
Use the helper In between the row with all the column headers and the first row of data add:
<?php echo $this->Filter->form('Post', array('name')) ?>
The first parameter is the model name. The second parameter is an array of fields. If you don’t want to filter a particular field pass null in that spot.
Create your own form however you want. Below is such an example.
<?php echo $this->Form->create('Post', array('action' => 'index', 'id' => 'filters')); ?>
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<th><?php echo $this->Paginator->sort('Post.name'); ?></th>
<th class="actions">Actions</th>
</tr>
<tr>
<th><?php echo $this->Form->input('Post.name'); ?></th>
<th>
<button type="submit" name="data[filter]" value="filter">Filter</button>
<button type="submit" name="data[reset]" value="reset">Reset</button>
</th>
</tr>
</thead>
<tbody>
// loop through and display your data
</tbody>
</table>
<?php echo $this->Form->end(); ?>
<div class="paging">
<?php echo $this->Paginator->prev('<< '.__('previous', true), array(), null, array('class' => 'disabled')); ?>
<?php echo $this->Paginator->numbers(); ?>
<?php echo $this->Paginator->next(__('next', true).' >>', array(), null, array('class' =>' disabled')); ?>
</div>
Add Behavior to model (only necessary for HABTM and HasMany):
<?php
class Post extends AppModel {
var $name = 'Post';
var $actsAs = 'Filter.Filter';
}
?>
These different initialization options are combined in the setup array. Defaults are shown below.
<?php
class PostsController extends AppController {
var $name = 'Posts';
var $components = array('Filter.Filter' => array(
'actions' => array('index'),
'defaults' => array(),
'fieldFormatting' => array(
'string' => "LIKE '%%%s%%'",
'text' => "LIKE '%%%s%%'",
'datetime' => "LIKE '%%%s%%'"
),
'formOptionsDatetime' => array(),
'paginatorParams' => array(
'page',
'sort',
'direction',
'limit'
),
'parsed' => false,
'redirect' => false,
'useTime' => false,
'separator' => '/',
'rangeSeparator' => '-',
'url' => array(),
'whitelist' => array()
));
}
?>
- actions: Array of actions upon which this component will act upon.
- defaults: Holds pagination defaults for controller actions. (syntax is
array('Model' => array('key' => 'value')
) - fieldFormatting: Fields which will replace the regular syntax in where i.e. field = ‘value’
- formOptionsDatetime: Formatting for datetime fields (unused)
- paginatorParams: Paginator params sent in the URL
- parsed: Used to tell whether the data options have been parsed
- redirect: Used to tell whether to redirect so the url includes filter data
- useTime: Used to tell whether time should be used in the filtering
- separator: Separator to use between fields in a date input
- rangeSeparator: Separator to use between dates in a date range
- url: Url variable used in paginate helper (syntax is
array('url' => $url)
); - whitelist: Array of fields and models for which this component may filter
- Better code commenting – Done, left to help enforce the habit
Support DatetimeDoneSupport URL redirects and parsingDoneRefactor datetime filtering for rangesDoneAllow the action to be configurableDoneSupport jQuery DatepickerOutside scope- Support Router prefixes, plugins, and named parameters in a “scope” instead of “actions” key.
- Expand hasMany and hasAndBelongsToMany support. Refactor behavior to conform with established practices.