Creating Filter Links in cakePHP

This is a short tutorial on how you can create reusable filter links, when you have lists of data that your users may only want to view a specific subset of.

So that this can easily be reused on multiple pages, the best method is to include it in a custom helper. I use a file called GeneralHelper.php for this type of functionality.

Orders-SPIRE-Fulfilment

Helper

<?php
class GeneralHelper extends AppHelper{
    public function filterLink($options = array()) {
        $return = '';
        $i = 0;
        $count = count($options);
        foreach ($options as $text => $link) {
            $class = '';
            if ($i == 0) {
                $class = ' first';
            }
            if ($i == $count - 1) {
                $class = ' last';
            }
            $current_url = $this->params->here;
            $link_url = $this->Html->url(array('action'=>$this->params->action,$link['filter_tag']=>$link['filter']));
            if ($link_url == $current_url) {
                $return .= '<span>'.$text.'</span>';
            }else{
                $return .= '<span>'.$this->Html->link($text,$link_url).'</span>';
            }
            $i++;
        }
        return $return;
    }
}
?>

This method takes an array, containing the details for each link. You can specify the text, filter tag and filter name for each. When a link is clicked your controller needs to detect these named parameters and only return the required data, this can be achieved with a simple switch statement.

Controller

<?php
switch (@$this->request->named['type']) {
    case 'all':
        $this->paginate = array(
            'conditions' => array(
                'Order.account_id' => $account_id
            ),
            'limit' => 10
        );
        break;
    case 'sent':
        $this->paginate = array(
            'conditions'=>array(
                'Order.status'=>'3',
                'Order.account_id' => $account_id
            ),
            'limit' => 10
        );
        break;
    default:
        $this->paginate = array(
            'conditions'=>array(
                'Order.status <'=>'3',
                'Order.account_id' => $account_id
            ),
            'limit' => 10
        );
        break;
}
$orders = $this->paginate();
$this->set(compact('orders'));
?>

Now when you go to the URL “www.example.com/controller/action/type:sent” for example, only records which have a status of 3 will be returned. All that is left to do now is use your new helper in the view.

View

<?php
$filterOptions = array(
    __('All') => array(
        'filter_tag' => 'type',
        'filter' => 'all'
    ),
    __('Pending') => array(
        'filter_tag' => NULL,
        'filter' => NULL
    ),
    __('Dispatched') => array(
        'filter_tag' => 'type',
        'filter' => 'sent'
    )
);
?>
<div><?php echo $this->General->filterLink($filterOptions); ?></div>

The first part of this is an array to define the data for your filter links, then it is simply a case of using the helper to render the menu links. If you want to show more than just a vertical list, a little css is required (I borrowed the cakePHP default styles for pagination).

CSS

.filter {
    background: #fff;
    color: #ccc;
    margin: 1em 0;
    clear: both;
    text-align: right;
}
.filter .current, .filter a {
    text-decoration: none;
    padding: 5px 8px;
    display: inline-block;
}
.filter > span {
    display: inline-block;
    border: 1px solid #ccc;
    border-left: 0;
}
.filter > span:hover {
    background: #efefef;
}
.filter .first {
    border-left: 1px solid #ccc;
    -webkit-border-radius: 4px 0 0 4px;
    -moz-border-radius: 4px 0 0 4px;
    -ms-border-radius: 4px 0 0 4px;
    -o-border-radius: 4px 0 0 4px;
    border-radius: 4px 0 0 4px;
}
.filter .last {
    -webkit-border-radius: 0 4px 4px 0;
    -moz-border-radius: 0 4px 4px 0;
    -ms-border-radius: 0 4px 4px 0;
    -o-border-radius: 0 4px 4px 0;
    border-radius: 0 4px 4px 0;
}
.filter .current {
    background: #efefef;
    color: #c73e14;
}

If you found this useful, a tweet or a comment would be appreciated.

One thought on “Creating Filter Links in cakePHP

  • September 13, 2013 at 6:07 pm
    Permalink

    Awesome article. Thanks for sharing. I did notice that line 20 in the helper did not work for me. I had to change it from:
    $return .= ”.$this->Html->link($text,$link_url).”;
    to:
    $return .= ”.$this->Html->link($text,array(‘action’ => $this->params->action, $link[‘filter_tag’]=>$link[‘filter’], ‘full_base’ => false)).”;

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *