Wednesday, October 1, 2008

Re: Pagination of search results

Thanks for your input Martin, but I ended up going a slightly
different way...

Basically I decided to use a custom named parameter which in the end
looks pretty tidy. So if anyone is interested, this is what I did:

In my news controller:
function admin_index() {
$options['conditions'] = array();

if (isset($this->passedArgs['q'])) {

$input = $this->passedArgs['q'];

App::import('Sanitize');
$q = Sanitize::escape($input);

$options['conditions'] = array(
"MATCH(News.title,News.body)
AGAINST('$q' IN BOOLEAN MODE)"
);
}

$this->News->recursive = 0;
$this->set(array('news' => $this->paginate('News',
$options['conditions'])));
}

The top of my view file looks like this:
<?php $paginator->options(array('url' => $this->passedArgs)); ?>
<div class="news index">
<h2><?php __('News');?></h2>
<?php echo $form->create('news', array('type' => 'get', 'controller'
=> 'admin/news', 'action' => 'results'));
echo $form->input('q', array('label' => '', 'size' => '35'));?>
<input type="submit" value="Search" /></form>
<?php if (isset($this->params['named']['q'])) {
echo "<h2>Search Results for <strong>".$this->params['named']['q']."</
strong></h2>";
}
?>

It basically submits the form to another controller function called
"admin_results". This function is very simple and just grabs the "q"
variable from the query string and converts it to a named parameter:
function admin_results() {
if (($this->params['url']['q']) <> NULL) {
$input = $this->params['url']['q'];
App::import('Sanitize');
$q = Sanitize::escape($input);
$this->redirect(array('action'=>'admin_index'.'/q:'.$q), null,
true);
}
$this->redirect(array('action'=>'admin_index'), null, true);
}

That's pretty much it, works like a charm. Not sure if it's the most
elegant way. If I knew of a way to get the named param into the url
straight out of the form I could skip the "admin_results" redirect
function.

-Brett

On Sep 19, 11:37 pm, "martin.westin...@gmail.com"
<martin.westin...@gmail.com> wrote:
> Like you say this has been discussed quite a bit before.
> The way I was advised to do this (which works really well) is to
> "POST" (or GET) thesearchto a proxy-action that creates a nice url
> that paginator will play nice with and redirects you to ourresults.
>
> Example:
> function lookup()
> {
>     if ( !empty($this->params['url']['q']) )
>     {
>         $param = $this->params['url']['q'];
>         $this->redirect('lookupResults/'.$param);
>         return;
>     }else{
>         // do something else here
>     }
>
> }
>
> This function would look for a GET parameter called q and redirect you
> to /controller/lookupResults/test or something similar. This will then
> be able to play nice with paginator if you add this to your view:
> $paginator->options(array('url' => $this->passedArgs));
>
> your next button would go to: /controller/lookupResults/test/page:2
>
> double07 wrote:
> > Hi all,
>
> > I know there's a lot of info around on this already but I haven't been
> > able to solve this issue myself.
>
> > I'm just setting up a simplesearchwhich will trawl through the
> > titles and bodies of news items.
>
> > I borrowed some code from the bakery here:
> >http://bakery.cakephp.org/articles/view/paginating-with-fulltext-sear...
>
> > I made a few minor changes but it's more or less the same
>
> > in my news controller:
> > function admin_search() {
> >    $this->News->recursive = 1;
> >         $conditions = array();
>
> >            if (isset($this->params['url']['q'])) {
>
> >                    $input = $this->params['url']['q'];
>
> >                    App::import('Sanitize');
> >                    $q = Sanitize::escape($input);
>
> >                    $options['conditions'] = array("MATCH(News.title,News.body)
> > AGAINST('$q' IN BOOLEAN MODE)");
>
> >            }
>
> >            $this->set(array('results' => $this->paginate('News',
> > $options['conditions'])));
>
> >            }
>
> > In the bakery article they just had:
> > $this->set(array('results' => $this->paginate('News', $options)));
> > But that wouldn't work for me?
>
> > So according to the manual to pass the query string to the paginator I
> > just put this line of code at the top of my view:
> > <?php $paginator->options(array('url' => $this->passedArgs)); ?>
>
> > So it works as in it returns the first page ofresults(via /admin/
> > news/search?q=test) but when I hover over the next/back/page number/
> > filter links it doesn't pass on thesearchquery string it just looks
> > like:
> > /admin/news/search/page:2
>
> > If I manually enter a query string it works perfectly i.e. /admin/news/
> >search/page:2?q=test
>
> > Any ideas why the querystring isn't being used by the paginator?
>
> > TIA.
>
> > -Brett.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to cake-php+unsubscribe@googlegroups.com
For more options, visit this group at http://groups.google.com/group/cake-php?hl=en
-~----------~----~----~----~------~----~------~--~---

No comments: