Jump to content

Paginating search results with checkboxes


jacmaes
 Share

Recommended Posts

I have a series of videos, and the following search form (translated into English here) that allows to filter these videos on the frontend:

searchform.png.bcc90343b68bd5059960f073c2ee4559.png

I've built a few of these search forms, but only with text fields, selects and radio buttons. Here I'm using an array with checkboxes ("Level" field above), and it's causing me grief when I try to paginate these results. I've done a lot of searching in the forum and spent too many hours to try to get it to work. Here's how I'm building the selector:

<?php 
if(count($input->get)):

  // Level is an array. Code adapted from Ryan's snippet here:
  // https://processwire.com/talk/topic/3472-enable-pagination-for-search-results/?tab=comments#comment-38042
  if($input->get->level) {
    $level = array();
    foreach($input->get->level as $id) $level[] = (int) $id; // sanitize to INTs
    $level = implode('|', $level); // convert to 123|456|789 string, ready for selector
  }
  else {
    $level = '';
  }

$data = array(
    'training_type' => array('=', (int) $input->get->training_type),
    'duration' => array('=', (int) $input->get->duration),
    'level' => array('=', $level),
    'limit' => array('=', (int) $input->get->limit)
    );


    $selector = '';


    // iterate through the $data we made above to create a selector string
    foreach($data as $field => $a) {

      list($operator, $value) = $a;
      if(empty($value)) continue;

     // send value to the whitelist so that it can be used in pagination
    $input->whitelist($field, $value);

    //  append to our selector string
     $selector .= "$field$operator$value, ";
   }

$videos = $page->children("$selector");

When I hit search, I get the expected results. So far so good. The GET parameters are the following with the options selected in the screenshot above:

videos/?level[]=1476&level[]=1477&training_type=1473&duration=1485&limit=10

$selector echoes the following as the "level" field is an array with a pipe character:

level=1476|1477, training_type=1473, duration=1485, limit=10

Now, when paginating these results, the following page (page 2) shows these GET parameters:

videos/page2/?level=1476|1477&training_type=1473&duration=1486&limit=10

And I think that's where the problem lies. The "level" field is "lost" and I'm getting more results than expected on subsequent pages. If I manually add "page2" to the initial results in the URL, just to test, everything works fine:

videos/page2/?level[]=1476&level[]=1477&training_type=1473&duration=1486&limit=10

But how can I achieve this in code? Do I need to revert to "level[]=1475&level[]=1477" instead of "level=1476|1477" for the pagination to work correctly, and can you PHP gods illuminate me?

Any help would be really appreciated, really.

Link to comment
Share on other sites

@jacmaes you can simply add a new condition if the the GET var level is a string ? let's try :

    if($input->get->level && is_array($input->get->level)) { // level as array given
        $level = array();
        foreach($input->get->level as $id) $level[] = (int) $id; // sanitize to INTs
        $level = implode('|', $level); // convert to 123|456|789 string, ready for selector
    }
    elseif($input->get->level && is_string($input->get->level) && $input->get->level !== '') { // level as string given
        // can be optimized (sanitizer)
        $level = array();
        foreach(explode('|', $input->get->level) as $id) $level[] = (int) $id; // sanitize to INTs
        $level = implode('|', $level); // convert to 123|456|789 string, ready for selector
    }
    else {
        $level = '';
    }

 

 

  • Like 2
Link to comment
Share on other sites

As far I can see you handle only the array version of the get parameter 'level', but not the pipe separated version. I didn't tried it out, please check:
 

  if($input->get->level) {
	if (is_array($input->get->level)) {
		// Level is an array. Code adapted from Ryan's snippet here:
        // https://processwire.com/talk/topic/3472-enable-pagination-for-search-results/?tab=comments#comment-38042
        $level = array();
        foreach($input->get->level as $id) $level[] = (int) $id; // sanitize to INTs
        $level = implode('|', $level); // convert to 123|456|789 string, ready for selector
    } else $level = "$input->get->level";
  }
  else {
    $level = '';
  }

 

@flydev ?? ... one second quicker ?

  • Like 1
  • Haha 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...