views:

763

answers:

6

I have created a small search and filter form method post in controller/index, which posts to it self the conditions and fields to paginate ( $this->paginate($conditions) )

However that is good for the first page, the subsequent pages the filer conditions are lost. pagination passArgs supports get variables well.

Is there an un complex way to pass the post conditions to the other paginated pages?

The method I have looked at is pass the $conditions in session , which isnt without complexity of assigning session and unset the session on submitting the form again (more refinements to the filter criteria by the user ) The other method is passing the $conditions as serialized string url_encode as an get parameter.

Is there an good cake way to do this more like passArgs, sessions and url encode do not look like cake style.

Thanks

A: 

Is there an un complex way to pass the post conditions to the other paginated pages?

Nope.

Is there an good cake way to do this more like passArgs, sessions and url encode do not look like cake style.

There is only one way, no matter, cake or not cake.

  1. Search must be done using GET method.

  2. Parameters being passed via QUERY STRING.

So, make your search form with method="GET" and then use http_build_query() to assemble a query string and use it to make links to other pages.

Being a little curious, you can see an example right here on SO:

http://stackoverflow.com/questions/tagged?tagnames=php&page=5&sort=newest&pagesize=50
Col. Shrapnel
Thanks a lot, this looks the right way
openprojdevel
+1  A: 

If it was me I would run with your idea of saving the stuff into the session. Then I would add a page dimension to the session, to store each page, thus allowing users to go back and forth with ease.

$this->Session->write('Search.page.1.params',$params);
$this->Session->write('Search.page.2.params',$params2);

In order to do it in a Cake way, you'd probably want to write your own Pagination helper, or plugin. Which you could then use more effectivly in your controllers as

$this->MyPages->paginate('MyModel');

I suppose, this functionality would also give you the option to allow your users to 'Save my search' if they wanted to, as you could dump the session params into a SavedSearch model or similar.

Don't forget to $this->Session->destroy() before starting a new search though!

DavidYell
Just for more info which could be helpful for other, following is an code snippet googled for session based paginationif(!empty($this->data)) { Sanitize::clean($this->data); $searchkey = $this->Session->read('Search.searchkey'); if(empty($searchkey)) { $this->Session->write('Search.searchkey', $this->data['Search']['searchkey']); } if($this->data['Search']['searchkey'] != $this->Session->read('Search.searchkey')) { $this->Session->delete('Search.searchkey'); $this->Session->write('Search.searchkey', $this->data['Search']['searchkey']); } }
openprojdevel
+1  A: 

You can also use the Post/Redirect/Get design pattern pattern to solve this, allowing users to bookmark URLs of searches (without them expiring as a session would) and keeping URLs looking friendly. For example:

function index($searchTerms = null) {
    // post/redirect/get
    if (isset($this->data['SearchForm'])) {
        $this->redirect(array($this->data['SearchForm']['search_terms']));
    }
    // your normal code here.
}

The search form data POSTs to /controller/action but the user is redirected and instead GETs /controller/action/search+terms where the terms are passed into the action as a parameter (ie. $searchTerms).

If you simply change the form submission method to GET you will instead see something like: /controller/action?data[SearchForm][search_terms]=search+terms

deizel
+1  A: 
openprojdevel
A: 

Thanks for this. Works perfect for me. Searches have to be done via GET, no question. To handle the parameters the same way, regardless whether they come from the search form or the pagination link, this is the right way.

christian
A: 

However that is good for the first page, the subsequent pages the filer conditions are lost.

I had the very same problem and searched for a way get pagination to work. In my case I had to paginate according to a selection in a radio button group. I ended up with using one action in the controller as a kind of dispatcher. From this action (let's call it search), which receives its input via post-method, I dispatch into searchByName via a call to $this->redirect('searchByName'.'/YOUR_SEARCH_PARAMETER:' . $YOUR_SEARCH_VALUE);

Using the syntax above it means that searchByName is an action residing in the same controller as search.

Is there an un complex way to pass the post conditions to the other paginated pages?

It took me some time to find that out, but I am a cake noobie. The good thing with this setup is, that you can now make your pagination settings in the "sub-actions" (like searchByName) on an individual basis.

In order to keep your app lean, you can call *$this->render('/path/relative/to/views/YOUR_VIEW_NAME')* as last statement in every sub-action. In the best case one view is all you need then.

Is there an good cake way to do this more like passArgs, sessions and url encode do not look like cake style.

My solution rewrites the post params into what is known in cake as named parameters. These are accessible in views and controllers via $this->params['named'][$param]. As the pagination links are formatted the same way, I think I am not so far off in terms of style. But as I am a cake noobie...

Benjamin.

benjamin