Jump to content
Federico

[Solved] Pagination out of search form results: How to start from first page

Recommended Posts

Hello PW community,

I've a search form which return selected items with pagination. Everything works fine, also the pagination display correctly all results through pages.

The issue is given only for selected results pagination as the latter does not start from page 1 but it revert back results from the current page (e.g. if you are in page 3, and submit a result from selects form, than all related items are displayed - not starting from page 1 but from page 3, which means something a fake "no results").

This is the classic function of render pager:

echo $works->renderPager(array('arrayToCSV' => false));

Any idea? Thanks!

 

Edit: I've also tried the "start=0" within the selectors, however it Always re-start from page 1 and stick to that, regardless. So no more option to move to page 2, 3, ....

Share this post


Link to post
Share on other sites

Submit the form against the url without any pagination segments. Eg. action="/search/", instead of action="."

Share this post


Link to post
Share on other sites

Thank you for the tip, I've tried the following combinations within the action="" brackets, with no luck (results from the search form should be displayed in the same page as per the form, page named "example"):

"/example/"

"/example"

"/"

"?"

"/?"

"?/"

""

 

All the above options brings back either an error for the pagination module, or filtered items but not starting from page 1

Share this post


Link to post
Share on other sites

Maybe you could show us a bit more code / information. It's not that easy debug by guesswork.

Share this post


Link to post
Share on other sites

I am basically call the pagination as a function, passing it the search form selectors as argument :

function pagination($selector) {
	$works = wire('pages')->find($selector);
	if(count($works)) {
		echo $works->renderPager(array('arrayToCSV' => false));
	}
}

the search form is essentially as described in a previous post: 

So maybe this issue is caused by the pagination function, as I am echoing it in the search form page as:

<?php pagination($selector); ?>

but i cannot figure it out why it doesn't restart from page 01 when user submit a search form..

Share this post


Link to post
Share on other sites

this is how i did it using functions:

 function paginateItems($items) {
        $items_pp = 5;
		$start = (wire('input')->pageNum - 1) * $items_pp;
		$total = count($items);
		$items = $items->slice($start, $items_pp);
		$a = new PageArray();
		foreach($items as $unused) $a->add(new Page());
		$a->setTotal($total);
		$a->setLimit($items_pp);
		$a->setStart($start);
		$items->data('paging', $a);
		return $items;
	}

	function renderPager($items) {
		$options = array(
		    'nextItemLabel' => 'Next &raquo;</i>',
		    'previousItemLabel' => "&laquo; Previous",
		    'listMarkup' => "<ul class='pagination'>{out}</ul>",
		    'itemMarkup' => "<li class='{class}'>{out}</li>",
		    'linkMarkup' => "<a href='{url}'><span>{out}</span></a>",
		    'currentItemClass' => 'active'
		);

		$out = '<ul class="pagination">';
		$out .= $items->renderPager($items, $options);
		$out .= '</ul>';
		return $out;
	}

in the template:

$a = $items->data('paging');
echo renderPager($a);

 

Share this post


Link to post
Share on other sites

Thank you for sharing this, it looks interesting. Sorry for my layman point of view, but what exactly $items as argument retains? I guess the pages with specific template, isn't it?

And when it comes to pass $selector as argument, which contains the submitted search form values, where should be located? Many thanks!

Share this post


Link to post
Share on other sites
6 hours ago, Federico said:

I am basically call the pagination as a function, passing it the search form selectors as argument :


function pagination($selector) {
	$works = wire('pages')->find($selector);
	if(count($works)) {
		echo $works->renderPager(array('arrayToCSV' => false));
	}
}

 

I think this is wrong - you don't want to be doing another $pages->find() inside your pagination function (I don't think you need to execute your pagination in a function, TBH).

The basic flow of your search template should be:

// sanitize and build your $selector from $input->get()
// ...

// find your search results
$results = $pages->find($selector);

// output your search results
foreach($results as $result) {
    //...
}

// render your pagination from the $results PageArray
echo $results->renderPager(array('arrayToCSV' => false));

 

  • Like 1

Share this post


Link to post
Share on other sites

I've get rid of the pagination function and did echo directly in template, which is actually even better in terms of simplification.

echo $results->renderPager(array('arrayToCSV' => false));

However the issue is still there, if I am going to page 3 and then filter results from that page, then again I get correctly the results but they are hidden as they are not numerically enough to have at least 3 pages to show (and so the pagination disappear). The only way to make sure I see filtered results is by submitting the selection only from page 1.

Share this post


Link to post
Share on other sites
21 minutes ago, Federico said:

if I am going to page 3 and then filter results from that page

Not sure what you mean by filtering results from that page. You mean you do a new search, right? You have a search form that you include as part of your search results template, and then when you have done a search and are viewing page 3 of the results you do a new search from the search form - is that it?

When you have done that second search, what is the URL in your browser address bar?

Might help too if you post the whole contents of your search template.

Share this post


Link to post
Share on other sites

These are the passages that lead to the issue:

__.com/en/works/    this is the page that host all paginated items. So you can go back and forth through pagination and everything works just fine. In this website section, which contain also the search form, I've implemented the search engine that bring search form result values in the same page.

If you go to page 3 or 4 or 5 (for instance), and than you decide to filter items by picking some selects in the search form and submit them (while in page greater than 1), than search results items are retrieved keeping the current page (e.g. page 3 o 4 o 5 depending in which page I was when submitting the form), instead of returning items starting from page 1

So if you submit search form values while in page 3 (__.com/en/works/page3), you might even get results but they will be not visible as they might be not enough to reach page 3 (__.com/en/works/page3?expertise%5B%5D=value01  instead of start over __.com/en/works/?expertise%5B%5D=value01)

Share this post


Link to post
Share on other sites

Page numbers are really just input variables, so you will have to make sure that the action part of the search form is the search page itself - what us your search form action URL?

Share this post


Link to post
Share on other sites

Since the search form has to bring search results in the same page, the form action is simply action="" 

If I insert anything else, the form will redirect to other page (es search.php) which does not serve this case. Other options have been tested but no luck..

Share this post


Link to post
Share on other sites

your search action should be to the search page, e,g, <?=$pages->get("template=search")->url?>

that's why you are experiencing those issues you reported.

  • Like 1

Share this post


Link to post
Share on other sites

Thank you Macrura,

by inserting the php variable inside the action brackets did the trick. So here's the bottom line, for those that might experience the same issue:

<form name='search' id='yourID' method='get' role='form' action="<?=$pages->get("template=YOURTEMPLATE")->url?>">
.....form values....
</form>

Thank you!

regards

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 snobjorn
      I have a website with multiple content types that I want to be accessible through search. I really like the live search on processwire.com, that sorts content types while typing. I tried to find the code to recreate this, with no luck. Does anyone know if this is jquery, specific jquery plugins, json/xml cached files, and what kind of PHP code is used? Any tip that point me in the right direction would be much apperciated.
      The search result listing seems fairly easy to create with sorting through parameters.
    • 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 Anders
      I want to allow full text search on my site. There is a very nice solution that comes right out of the box:
      $selector = "title|body~=$q, limit=50"; This works, but to make it even better I would want to give higher weight to pages where the search term occurs in the title, than if it just occurs in the body. After all, a page with the title "Wine from France" is probably the best match for the search "france wine". How do I accomplish this in ProcessWire?
      I can see three possible paths, but I am not very fond of any of them:
      Do a direct SQL query, circumventing the API, along these lines. But I would prefer to abstract away the database layout if at all possible. Use something like ElasticSearch, but to be honest that would be to complicated to set up and maintain in the long run. Make multiple lookups, first for matches in the title, then for matches in the body, and merge and sort in PHP. My suspicion is that this would get complicated quite quickly. For instance, how do you deal with a page that has two of the three search terms in the title and the third in the body? Is there a magic option four I should look into? Or are any of the above options better than the others? Any input is welcome!
    • 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 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...