Quick and dirty dropdown pagination in CakePHP

I’ve been slowly rebuilding my Moblog application using the CakePHP framework over the past year when I have the time and motivation. Over the past few evenings I’ve been refining a small element of my Moblog site which has started to dramatically increase user interaction with the site and allow old content to bubble back up to the top.

The Cake paginator helper works fine if you’re using basic anchor links to trigger sort options, but I wanted to use a dropdown select element so that the user can choose how to order the moblogs.

So I know this is most likely a horrible solution to the problem and certainly not very ‘cakey’, but it’s quick, dirty, and it works for what I need it to do.

In the view we need a valid form element, even though the javascript hijacks the onChange event and doesn’t actually post the result. At the moment this does mean that this doesn’t work without javascript but I plan on improving this soon by only using $paginator->sort links in the view, and replacing them with the form completely in javascript.

in the view:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

    $form->create('Moblog',array(
        'action'=>'index',
        'controller'=>'moblogs',
        'type'=>'get',
        'div'=>false
        )
    );
?>

    $form->input('order',array(
        'label'=>'sort:',
        'options'=>array(
            'modified'=>'recent activity',
            'id'=>'date added',
            'commented'=>'last commented',
            'moblogcommentcount'=>'most commented',
            'rand()'=>'random'
            ),
        'selected'=>$this->params['order'],
        'div'=>false                 
        )
    );
?>
$form->end('go');?>
In the jQuery we take whichever value was selected on change, build the relevant ‘paginator compatible’ url which the helper will use to return the required data on page load and then redirect the browser.

jQuery:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$('#MoblogOrder').change(function(){
    var url ='/moblogs/index';
    switch($('#MoblogOrder option:selected').val()){
        case'modified':
            url +='/page:1/sort:modified/direction:desc/';
            break;             
        case'id':
            url +='/page:1/sort:id/direction:desc/';
            break;
        case'commented':
            url +='/page:1/sort:commented/direction:desc/';
            break;
        case'moblogcommentcount':
            url +='/page:1/sort:moblogcommentcount/direction:desc/';
            break;
        case'rand()':
            url +='/page:1/order:rand()/';
            break;
        default: url +='/page:1/sort:modified/direction:desc/';
    }
    window.location= url;
}
In this particular example, I’m using a random order also, which needs to be an ‘order’ param instead of a ‘sort’, so in the controller I’m checking which params are being used, and setting a consistant order variable which is used in the view to maintain the selected state of the select element.

in the index method in the controller

1
2
3
4
5
6
7
8
9
function index(){
    if(isset($this->params['named']['sort'])){
        $this->params['order']=$this->params['named']['sort'];
    }elseif(isset($this->params['named']['order'])){
        $this->params['order']=$this->params['named']['order'];  
    }else{
        $this->params['order']='modified';
    }
}
If any Cake ninjas are reading this and have any suggestions, or better methods, please do leave a comment!

comments powered by Disqus