Vigilante

What are the methods to sort/filter $pages query in front end?

Recommended Posts

This is a pretty typical thing. Open a page, it does a $pages query, finds 112 things and I list them on the page. There is pagination too, 20 per page.

I want a sort dropdown box so the visitor can change alpha sort or whatever other sorts and filters I eventually use.

My first thought is to just refresh the page with a url query like "page/?sort=az" and then adjust the query in the template code. But to do this, it will require a page refresh, which means the sort box goes back to its default, and not sure how it effects pagination.

If I do a page refresh, I'll have to keep the sort settings in the session or something, to make sure I always apply correct sort on page load.

But at the same time, I've already got the $pages array, it would be much nicer to shuffle it and update the page without a page refresh, rather than run the query over and over again.

But then again, the pagination buttons already cause page refreshes, so that is already happening anyway, unless I convert the pagination buttons to also be no-refresh somehow.

 

I figure this is a very common problem, to paginate results and give users a sorting/filtering option. What is the common methods for handling it? Session, url query, ajax? If I just add the sort to the url query, how do I make that work in the pagination links?

Share this post


Link to post
Share on other sites

The beauty of Processwire is that it doesn't predefine output of content, so there's no reason why you couldn't create a template that returns JSON and call it using an ajax request from the HTML template that you want to update.

It does mean two templates for one page, although using URL segments it might be possible to have a single template that can return either HTML or JSON depending on the value of the URL segment, although you could do that with parameters as well.

 

Share this post


Link to post
Share on other sites

Well, today you'd use lazy-loading techniques (load 20 items on load, and then 20 more with "show more" etc.), therefore eliminating the need for classic pagination, or show the current page-set in the URL.

With endless scrolling and pagination, you could try something like this: https://elkfox.github.io/Ajaxify/ 
Ajaxination - Normal pagination style but load the page without reloading, uses push states.

 

  • Like 1

Share this post


Link to post
Share on other sites
14 hours ago, dragan said:

Well, today you'd use lazy-loading techniques (load 20 items on load, and then 20 more with "show more" etc.), therefore eliminating the need for classic pagination, or show the current page-set in the URL.

With endless scrolling and pagination, you could try something like this: https://elkfox.github.io/Ajaxify/ 
Ajaxination - Normal pagination style but load the page without reloading, uses push states.

 

That's cool but seems to be a Shopify plugin.

I would prefer the endless click one to load more, but that does mean it's not so easy to bookmark or link to page 4 or 18. To come back to the page only to have to click 'more' 6 more times is annoying without very robust URL hashing techniques. It's overkill for this project.

So I'll stick to either classic page-refresh pagination, or an ajax based no-refresh pagination as long as the URL works for it.

Share this post


Link to post
Share on other sites
14 hours ago, Pixrael said:

you can use https://processwire.com/docs/tutorials/how-to-use-url-segments/ 

you will get page/a-z instead of page/?sort=az ..using this segments you can search, filter, sort the pages results and update too the "sort box" (select, radio buttons, tabs, any) by this value

I wonder if segments are the best in my case given that it could potentially have more than just alpha sort. 

Right now I'm only sorting a list of companies, so alpha sort is probably all I'll need. But on the same site will be a catalog of products, and of course that could have a dozen different sortable/filterable values. I don't want URLs like page/a-z/blue/under-100/newest/....  The classic URL properties would work best I think. Plus segments are not really hackable. In the above URL, what if they don't sort by under-100 and that part is missing? I would have to test every segment to figure out which filter it is, in what order. 

Share this post


Link to post
Share on other sites
On 11/30/2017 at 2:57 PM, Vigilante said:

My first thought is to just refresh the page with a url query like "page/?sort=az" and then adjust the query in the template code. But to do this, it will require a page refresh, which means the sort box goes back to its default, and not sure how it effects pagination.

The sort box will go back to the default/first option, unless you program some basic logic to make it selected.  Something like this should work:

<?php
$sort = $input->get->string('sort'); // sanitize url variable shorthand
?>

<select name="sort">
  <option value=""></option>
  <option value="title" <?php if($sort=="title"): ?>selected<?php endif; ?>>Title (Asc)</option>
  <option value="-title" <?php if($sort=="-title"): ?>selected<?php endif; ?>>Title (Desc)</option>
  <option value="price" <?php if($sort=="price"): ?>selected<?php endif; ?>>Price (Asc)</option>
  <option value="-price" <?php if($sort=="-price"): ?>selected<?php endif; ?>>Price (Desc)</option>
</select>

 

  • Like 1

Share this post


Link to post
Share on other sites
12 hours ago, Jonathan Lahijani said:

The sort box will go back to the default/first option, unless you program some basic logic to make it selected.  Something like this should work:

Yes, not sure why I didn't realize that before.

 

Well for now I'm doing full page refreshes, it's ok for this particular site, but I would like to explore the ajax no-refresh solutions that can keep URLs in tact and support back/forward actions.

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 louisstephens
      I have done a bit of searching, but I can not seem to find an actual answer. I have a list of services as child pages under "Services". I can output the services just fine, but I cant wrap my head around how to group them "alphabetically" like:
      Services A - Service "A" 1 - Service "A" 2 - Service "A" 3 B - Service "B" 1 - Service "B" 2 - Service "B" 3 C - Service "C" 1 - Service "C" 2 - Service "C" 3 Has anyone achieved this type of functionality before?
    • By nickngqs
      How do you guys sort according to the order of page listing?

      My template is sort order none, so I assume it would return according to order of page listing.
    • By j00st
      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.
    • By rolisx
      Hi all!
      I have a little problem here. I want to sort a list of addresses by streetname and then by number. First, I just had a field "prod_objekt" (address) containing both and then have a foreach loop like this: $pages->get('/produzenten/')->prod_repeater->sort('prod_objekt') as $produzent. Unfortunately, this would not sort by streetnumber if I had the same streetname but multiple numbers.
      Now, I thought I could sort by two fields. prod_object (adress) first and then by prod_hausnummer (streetnumber). But I just don't know the code for it. I tried this: $pages->get('/produzenten/')->prod_repeater->sort('prod_objekt.prod_hausnummer') as $produzent, but it wouldn't work.
      Any ideas on how to solve this?
      Thanks for your help
      Roli
    • By celfred
      Hello,
      I'm facing an issue with my page fieldtype. Pages appear in the order they were created although I'd like to see them sorted in alphabetical order (by title). The pages are well-sorted in my tree, but in that particular Page fieldtype (on another page), I can't find any place where I would decide on what field I can sort them. Am I missing something here ?
      Let me know if I'm not clear enough in my explanations.
      Thanks in advance for a clue