Jump to content
j00st

Pagination & GET results

Recommended Posts

Hi all,

I've set up a filter on my product-page, which I then use to...filter my products!
– I've got pagination set up, and 30 items per page.
– When I active the filter it works perfectly (in my opinion).

 

Here's what I'm struggling with though:
When I'm on another page (filtered as well/or the total overview) and I put my GET request in for the filter,
it gives back the result, but still with the page-number there. In some cases, this is no problem – like a A-Z or Z-A filter,
but others (say, per location) I might have less pages.

Visual/code ref: (I DO have 3 pages of authors, but I don't have 3 pages from London)

url: books/page3?author=ascending
url: books/page3?studio=london

 

The current setup for my pages that get rendered are as follows:

$allbooks = $pages->find("template=book, sort=$sort, $q, $tagged, $select_studio, start=0, limit=$limit");

As you can see I have the start=0 in there, but I read that's for the start of the pagination, not so much where it'll drop me in the search results.
$q, $tagged and $select_studio are all empty values, unless they're returned from the GET request

To repeat it, in it's most simplest form:

When I click a filter, and a GET request is done, I want to 'reset' the page-number to 0, and get my results...

Perhaps I'm missing something obvious, but I'd be really grateful to have your input.

Share this post


Link to post
Share on other sites

Maybe u can try putting "./" in your filter form action link

./?studio=london

<a href="./?studio=london">London</a>

 

  • Like 1

Share this post


Link to post
Share on other sites
$allbooks = $pages->find("template=book, sort=$sort, $q, $tagged, $select_studio, limit=10");

if ($input->get()->count() && !$allbooks->count() && $input->pageNum > 0) {
	$url = $page->url([
	      'http' => true,
	      'pageNum' => 0,
	      'data' => $input->get()->getArray()
	    ]);

			$session->redirect($url);
}

Not tested and may result in redirection loop, but just an idea. 

Tested, it works. 

  • Like 1

Share this post


Link to post
Share on other sites
13 hours ago, lokomotivan said:

Maybe u can try putting "./" in your filter form action link


./?studio=london

<a href="./?studio=london">London</a>

 

This. You can just use the page->url for the action of your form. No get param needed here.

Share this post


Link to post
Share on other sites
10 hours ago, Zeka said:

$allbooks = $pages->find("template=book, sort=$sort, $q, $tagged, $select_studio, limit=10");

if ($input->get()->count() && !$allbooks->count() && $input->pageNum > 0) {
	$url = $page->url([
	      'http' => true,
	      'pageNum' => 0,
	      'data' => $input->get()->getArray()
	    ]);

			$session->redirect($url);
}

Not tested and may result in redirection loop, but just an idea. 

Tested, it works. 

Thats not really needed for this problem. Why complicate things unessecary? This wont work when using a get param to filter result with i paginated results. Ones you can add with using input whitelist.

Share this post


Link to post
Share on other sites

@lokomotivan @Soma That's indeed a nice, fast, and easy way to get it working!
Unfortunately I've made my form & GET setup a bit to complicated – so if I want to do this, I'll have to restructure everything, which I'd rather not of course. But I'll definitely keep it in mind for the next Filter-run!!

So, now I'm working with @Zeka's code...I think I understand what's happening, but I'm having some issues with implementation.
For example, I've replaced:

if ($input->get()->count() && !$allbooks->count() && $input->pageNum > 0) {

with the following:

if (count($_GET) > 0 && $input->pageNum > 1){

...as I got an error on $input->get()->count() (...and I don't know why).
The !$allbooks->count() is to verify there's actually books in there, right? So I SHOULD put that one in there...

So far I've been using $input->get->(name of what I'm getting) so;
- $input->get->studio
- $input->get->title
- $input->get->author

When I use Zeka's code in the URL 'data' element, I get the following error:

Parse error: syntax error, unexpected '' (T_STRING), expecting ']' in /Users/JCN/Dropbox/Websites/publicationstudio/site/assets/cache/FileCompiler/site/templates/header.inc on line 268

As the $input->get()->count() also didn't work for me, I'm wondering if I'm missing something obvious, or if it has something to do with my settings?
If I remove the line with 'data' it works fine – but of course isn't filtering anything 😛 as it'll go to page 0 of allbooks, unfiltered.

Perhaps it's also useful to show how I have these $input->get->x set up in relation to my $allbooks:

if($input->get->author === 'ascending'){
    $sort = 'author';
}elseif($input->get->author === 'descending'){
    $sort = '-author';
}elseif($input->get->title === 'ascending'){
    $sort = 'title';
}elseif($input->get->title === 'descending'){
    $sort = '-title';		
}else{
    $sort = 'sort';
}

Looking forward to hearing your take on this!!

Share this post


Link to post
Share on other sites

Ah, and I completely overlooked you comment @Soma...
 

Quote

Thats not really needed for this problem. Why complicate things unessecary? This wont work when using a get param to filter result with i paginated results. Ones you can add with using input whitelist.

"This won't work when using a get param" 🤔

Does what I said above still make sense then?

Share this post


Link to post
Share on other sites

Make sure you have a filter form that action url is the $page->url. 

I don't know what the problem is really but it's all getting too complicated for what it really can be (dead simple).

Example filter form for a paginated result list :

<?php namespace ProcessWire;

$filter = "";

$form = $modules->InputfieldForm;
$form->attr("action", $page->url);
$form->attr("method", "get");

// select with sort options
$f = $modules->InputfieldSelect;
$f->attr("name", "sort");
$f->label = "Sort";
$f->addOptions(array(
	"-title" => "descending",
	"title" => "ascending"
));
$form->add($f);

// submit button
$f = $modules->InputfieldSubmit;
$f->attr("name", "filter");
$form->add($f);

// process form
if(count($input->get)){
    // processes and populates form fields
	$form->processInput($input->get);
	
	// if sort is not empty
	if($form->get("sort")->value) {
		// build filter and add to whitelist so it gets picked up by pagination
		$input->whitelist("sort", $sanitizer->selectorValue($form->get("sort")->value));
		$filter .= ",sort=" . $input->whitelist("sort");
	}
}

$result = $pages->find("template=basic-page, limit=2{$filter}");

$content .= "<h2>Show Results</h2>";

if(!$result->count) {
	$content .= "<p>no results</p>";
} else {
	foreach($result as $res){
		$content .= "<p>$res->title<br>$res->url</p>";
	}
	$content .= $result->renderPager();
}

$content .= $form->render();

 

  • Like 6

Share this post


Link to post
Share on other sites

Thanks @Soma
I'm going to go through your code – as you said, should be able to do this 'dead simple' 🙂

Probably made it too difficult for myself along the way, so I'll have a look, and will sort this out.

Thanks for all the input everyone!

Share this post


Link to post
Share on other sites

I have a similar issue, what I basically need is to reset the URL-segments, i.e. go back to the baseURL(?) without /page2 or above whenever the get variables change. Because when I'm on /page2 I and switch the search term, it won't find anything because the results I would get are not enough to require a pagination. 

You would think that something like this would be dead simple, but it's not. I don't even know what I exactly need to change. linkMarkup? urlSegment? pageNum? 

So here's how I tried to solve this now

if ($session->what != $what || $session->letter != $letter) {
     $input->setPageNum(0);
}
$session->letter = $letter;
$session->what = $what;

I tried many different API commands, but they all won't work. 

Please help!

Share this post


Link to post
Share on other sites

Step 1: Change your form element’s action attribute to <?php echo $page->url; ?>
Step 2: There is no step 2.

 

edit: sorry, I didn’t read the whole thread either. This same answer had actually been posted by Soma two posts ago.

  • Like 2

Share this post


Link to post
Share on other sites
18 hours ago, Jan Romero said:

Step 1: Change your form element’s action attribute to <?php echo $page->url; ?>
Step 2: There is no step 2.

 

edit: sorry, I didn’t read the whole thread either. This same answer had actually been posted by Soma two posts ago.

true. I missed that somehow, was more focused on the code. Anyways, that did the trick, thanks a lot, indeed dead simple 😄

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 Flashmaster82
      Hi, i need some help with the filtering based on the Skyscrapers demo/func. I´m not that great with php so be patient.
      My structure looks like this
      Youtube videos > Youtube channel > Video
      on the video template (youtube_channel_video) i have multiple drop down fields and other fields that i would like to filter on the front end. I also have other pages that need this functions with search/filter etc but with different filters.
       
      This is the code i have in my search-form.php. Right now i experimenting with the field/option (category) that every video have in their template. The first filter (youtube_channel) works but im trying to get the category filter to work.
      <div id='skyscraper-search' class='uk-panel uk-panel-box xuk-panel-box-primary uk-margin-bottom'> <h3 class='h3'>Youtube videos</h3> <form class='uk-form uk-form-stacked' method='get' action='<?php echo $config->urls->root?>search/'> <div class='row'> <label class='uk-form-label' for='search_keywords'>Keywords</label> <div class='uk-form-controls'> <input type='text' class='uk-form-width-large' name='keywords' id='search_keywords' value='<?php if($input->whitelist('keywords')) echo $sanitizer->entities($input->whitelist('keywords')); ?>' /> </div> </div> <div class='col-6'> <div class='row'> <label class='uk-form-label' for='youtube_channel'>Youtube channel</label> <div class='uk-form-controls'> <select id='youtube_channel' name='youtube_channel' class='uk-form-width-large'> <option value=''></option> <?php // generate the youtube_channel options, checking the whitelist to see if any are already selected foreach($pages->find("template=youtube_channel_page") as $youtube_channel) { $selected = $youtube_channel->name == $input->whitelist->youtube_channel ? " selected='selected' " : ''; echo "<option$selected value='{$youtube_channel->name}'>{$youtube_channel->title}</option>"; } ?> </select> </div> </div> </div> <div class='col-6'> <div class='row'> <label class='uk-form-label' for='category'>Category</label> <div class='uk-form-controls'> <select id='category' name='category' class='uk-form-width-large'> <option value=''></option> <?php // generate the category options, checking the whitelist to see if any are already selected foreach($pages->find("template=youtube_channel_video") as $category) { $selected = $category->youtube_video_category == $input->whitelist->youtube_video_category ? " selected='selected' " : ''; echo "<option$selected value='{$category->youtube_video_category}'>{$category->youtube_video_category->title}</option>"; } ?> </select> </div> </div> </div> <div class='uk-margin-top'> <button type='submit' id='search_submit' class='uk-button uk-button-primary' name='submit' value='1'> <i class='uk-icon-search'></i> Search </button> </div> </form> </div>  
      This is my search.php
      <?php namespace ProcessWire; $selector = ''; $summary = array( "title" => "", "youtube_channel" => "", "category" => "", "country" => "", ); if($input->get('youtube_channel')) { $youtube_channelName = $sanitizer->pageName($input->get('youtube_channel')); $youtube_channel = pages("/youtube-videos/$youtube_channelName/"); if($youtube_channel->id) { $selector .= "parent=$youtube_channel, "; $summary['youtube_channel'] = $youtube_channel->title; $input->whitelist('youtube_channel', $youtube_channel->name); } } foreach(array('category') as $key) { if(!$value = $input->get($key)) continue; else { $value = (int) $value; $selector .= "$key=$value, "; $summary[$key] = $value; $input->whitelist($key, $value); } } if($input->get('keywords')) { $value = $sanitizer->selectorValue($input->get('keywords')); $selector .= "title|body|category%=$value, sort=title"; $summary["keywords"] = $sanitizer->entities($value); $input->whitelist('keywords', $value); } $videos = findSkyscrapers($selector); $browserTitle = 'Youtube video search - '; foreach($summary as $key => $value) { if($value) { $key = ucfirst($key); $browserTitle .= ucfirst($key) . ": $value, "; } else { unset($summary[$key]); } } region('browserTitle', rtrim($browserTitle, ', ')); region('content', files()->render('./includes/search-summary.php', array('items' => $summary)) . renderSkyscraperList($videos) );  
      This is my skyscraper-list-item.php file
       
      <?php echo " <div class='col-12 col-sm-12 col-md-6 col-lg-6 col-xl-4 col-xxl-4 col-xxxl-4 bmar10'> <div class='youtube_search_holder'> <a data-fancybox data-autoclose='true' data-width='1500' data-height='844' data-height='360' href='{$skyscraper->youtube}autoplay=1'> <div class='youtube_thumbnail_placeholder'><img src='{$skyscraper->youtube_thumbnail->url}' class='youtube_thumbnail_image w-100'> <div class='playicon'></div></div></a> <div class='youtube_search_thumbnail_content'> <div class='h6 text-uppercase green tmar3 title'><a href='{$skyscraper->parent->channel_url}' target='_blank' title='{$skyscraper->parent->title}'>{$skyscraper->parent->title}</a></div><div class='text-uppercase white h3 limit'><a href='{$skyscraper->youtube}' data-fancybox data-width='1500' data-height='844' data-height='360'>{$skyscraper->title}</a></div> <div class='h5 text-uppercase gray date'>{$skyscraper->youtube_video_publishdate}</div> <span class='white h7'> {$skyscraper->youtube_video_category->title} {$skyscraper->countries->title} {$skyscraper->competition->title} {$skyscraper->competition->parent->parent->title} {$skyscraper->armwrestler_competition_gender->title} {$skyscraper->armwrestler_arm->title} {$skyscraper->armwrestler_age_category->title} {$skyscraper->competition_weight_class->title} {$skyscraper->competition_video_match->title} {$skyscraper->videotags} </span> </div></div></div> "; ?> This is the front end right now (no styling 🙂

      In the category filter, right now there is multiple categories with the same name, i would also like to restrict it to just one result per category.
      Please help!
    • By jacmaes
      I have a series of videos, and the following search form (translated into English here) that allows to filter these videos on the frontend:

      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.
    • By Bacelo
      Hi there,
      I have a bit of trouble on filtering correctly some event pages by some selectors...
      I do have the following 2 date fields:
      - start date (fieldname = date)
      - end date (fieldname = enddate)

      Some events are a single day event (only start date) - some are a multi day event (end date).
      Past single day events should not show up.
      Current multi day events should show up (even if start day is in the past, but end date is future).
      So I have the following selector:
      if ($standort == '') { $termine = $page->children("sort=date, limit=10, (date>=today, enddate=''), (enddate>=today)"); } else { $termine = $page->children( "(standort_reference~=$standort), (standort_alle=1), (date>=today, enddate=''), (enddate>=today), sort=date, limit=10"); } This selector
      $termine = $page->children("sort=date, limit=10, (date>=today, enddate=''), (enddate>=today)"); works fine, but the follwing does not work (all past entries are also shown):
      $termine = $page->children( "(standort_reference~=$standort), (standort_alle=1), (date>=today, enddate=''), (enddate>=today), sort=date, limit=10"); I have no clue what I'm missing - any ideas?
×
×
  • Create New...