Jump to content
jacmaes

Paginating search results with checkboxes

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.

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By creativejay
      I will preface this by saying I have checked (multiple times) per template (both parent and child, to be totally sure) that they are set to allow pagination.
      What's happening is that my first page of results keeps displaying, despite /page2/ being in the URL. The pagination markup also indicates I am still on page one. This is happening across multiple types of paginated pages.
      $pagination = $pager->render($results, $poptions); The options are just markup...
      $poptions = array( 'numPageLinks' => 5, 'listClass' => 'uk-pagination', 'linkMarkup' => "<a href='{url}'>{out}</a>", 'currentItemClass' => 'uk-active', 'separatorItemLabel' => '<span>&hellip;</span>', 'separatorItemClass' => 'uk-disabled', 'currentLinkMarkup' => "<span>{out}</span>", 'nextItemLabel' => '<i class="uk-icon-angle-double-right"></i>', 'previousItemLabel' => '<i class="uk-icon-angle-double-left"></i>', 'nextItemClass' => '', // blank out classes irrelevant to Uikit 'previousItemClass' => '', 'lastItemClass' => '', ); In the header, I call for the module and the options include:
      $pager = $modules->get('MarkupPagerNav'); include_once("pagination.inc"); Aside from the usual "check that you allowed pagination" advice, what issue might these symptoms indicate?
    • By ottogal
      Hello all,
      using PW 3.0.148 with the regular site profile for a blog, I got an an empty pagination output when I had a Toggle field in the selector.
      The Toggle Fieldtype was introduced with https://processwire.com/blog/posts/pw-3.0.139/ .
      The selector resulting in empty pagination:
      $posts = $pages->find("parent=blog, sort=-date, limit=10, toggle_field=0"); It worked well, when I replaced the Toggle field with a Checkbox field:
      $posts = $pages->find("parent=blog, sort=-date, limit=10, checkbox_field=0"); So the prerequisites for the pagination to work are given.
      The settings for the Toggle field were:
      Formatted value: Integer Label Type: Yes/No Input Type: Toggle buttons Default selected option: No Thanks for any hints!
    • By christophengelmayer
      Hi everyone,
      I'm working on a CLI script that renders paginated pages.
      Therefore I iterate trough paginated pages and set the page number and render the result.
      My problem is, after calling the render function for the first time, the output doesn't change even if I change the page number.
       
      DEMO:
      I'm using a template that renders a pagination of its children:
      <?php echo $page->children("limit=3")->render(); ?> I can view the paginated results in the Browser:
      /page-rendering-pagination/ /page-rendering-pagination/page2 /page-rendering-pagination/page3 ... When trying to render the different pages using the API I always get the first result, even if I change the page Number.
      <?php namespace ProcessWire; include('./index.php'); wire('input')->setPageNum(1); $p = wire('pages')->get('/page-rendering-pagination'); var_dump($p->render()); // renders first three items wire('input')->setPageNum(2); var_dump($p->render()); // also renders the first three items Am I missing something? Is there some kind of caching mechanism that I'm not aware of?
      Thanks for your help.
    • By cboetens
      Hi guys
      So I'm building a little search index for a client with this recipe I've found on the ProcessWire Recipes website (more info: https://processwire-recipes.com/recipes/set-up-search-index-with-fieldtypecache/)
      I've followed the exact steps in the recipe and the script appears to be working, except for Profields: Repeater Matrix. 🙄
      This is the code I've got so far:
      <?php include('includes/header.php') ?> <?php $q = $sanitizer->selectorValue($input->get->q); if($q) { $results = $pages->find('search_cache%='. $q); } else { $results = new stdClass(); $results->count = 0; } ?> <section class="partners-block-consul mb-5"> <div class="container"> <div class="row"> <div class="col-sm-10 offset-sm-1"> <div class="partners-head sec-p-lg"> <?php if($page->headline) { ?> <h1 class="highlight"><?= $page->headline ?></h1> <?php } ?> <div class="cms text-left"> <p>Er werden <?= $results->count ?> resultaten gevonden.</p> <?php if($results->count > 0){ ?> <ul> <?php foreach($results as $result){ if($result->template->name == "faq_item") { $category = $pages->get("id=".$result->faq_category); $parent_template = $category->rootParent(); ?> <li><?= $result->title ?> - <a href="<?= $parent_template->url . $category->name . "/"; ?>" title="<?= $result->title ?>"><?= $labels->read_more ?></a></li> <?php } elseif($result->template->name == "faq_category") { $parent_template = $result->rootParent(); $faqCategoryUrl = $parent_template->url . $result->name . "/"; ?> <li><?= $result->title ?> - <a href="<?= $faqCategoryUrl; ?>" title="<?= $result->title ?>"><?= $labels->read_more ?></a></li> <?php } else { ?> <li><?= $result->title ?> - <a href="<?= $result->url; ?>" title="<?= $result->title ?>"><?= $labels->read_more ?></a></li> <?php } ?> <?php } ?> </ul> <?php } ?> </div> </div> </div> </div> </div> </section> <?php include('includes/cta.php'); ?> <?php include('includes/footer.php'); ?> In the ProcessWire admin the "search_cache" field is being build as follows (see image 1).


      Then, the field 'search_cache' is being used on the following templates (see image 2 and 3). So, let's say I'm searching the word 'kinderen', which should get a hit on the template 'Kind', the script isn't returning this page as one of the hits (the result should return 'migraine').
       

      If someone has any idea why the script is not looking for the data that is being put in the field "Profields: Repeater Matrix", he/ she would be my personal hero! 🤗
      Greetings
      Cédric
       


    • By dragan
      Quick question: Is it possible to use PW's pagination for other things than PageArrays? i.e. query custom database tables and paginate the results? Has anyone ever tried it?
×
×
  • Create New...