Shopify collections typically come with sorting and filtering options - but only on the collection page itself. But what about everywhere else? What if you want to sort and filter outside of these collections? THEN WHAT?!
While it’s easy to output products from collections to a custom template using the loop {% for product in collection.title.products %} there is no simple way to leverage shopify’s built-in sorting and filter options for this scenario, because as we know, these only work on the collection’s own page - and nowhere else. We have devised a way around this however. Lucky for you!
In this tutorial we will build a custom page that contains a grid of products from a collection, and use the list.js plugin to apply dynamic ajax-based sorting to it.
The first thing we need is a select menu that contains the sorting options (which we copied from a typical shopify collection template). We then output the products from our collection into a 4 column grid. For simplicity we’re using a bootstrap grid here.
<div class="container">
<div class="row">
<div class="col-4">
<select class="sort custom-select">
<option>Sort By</option>
<option value="manual">Featured</option>
<option value="best-selling">Best selling</option>
<option value="title-ascending">Alphabetically, A-Z</option>
<option value="title-descending">Alphabetically, Z-A</option>
<option value="price-ascending" selected="selected">Price, low to high</option>
<option value="price-descending">Price, high to low</option>
<option value="created-ascending">Date, old to new</option>
<option value="created-descending">Date, new to old</option>
</select>
</div>
</div>
<div id="products" class="row">
{% for product in collection.demo.products %}
<div class="product col-3">
<img src="{{ product.featured_image | product_img_url: 'grande' }}" alt="{{ product.title | escape }}" />
<div class="title">{{ product.title }}</div>
</div>
{% endfor %}
</div>
</div>
Which gives us this...
***NOTE*** The default sorting here is in alphabetical order.
Now we add the list.js plugin to our page and initialize it with this javascript code
var options = {
valueNames: [
{ attr: 'src', name: 'image' },
'title'
]
};
var productList = new List('products', options);
Next, we define our list productList, passing in the products ID as the first parameter (this is the ID of our product grid). We also add some options so that we can define the components of each product in the list (the plugin needs this to know how to output the products correctly each time it sorts them). The valueNames JSON object contains the image and title information needed.
The final part we need is to actually trigger the sorting when a sorting option is selected from the menu. This is the code we need to do that...
$('.sort').change(function () {
var criteria = this.value;
$.ajax({
url: '/collections/demo?sort_by=' + criteria,
type:'GET',
success: function(data) {
productList.clear();
$(data).find('ul.grid--view-items li').each(function() {
var image = $(this).find('grid-view-item__image');
var title = $(this).children('.grid-view-item').attr('data-title');
productList.add({
image: image,
title: title
});
});
}
});
});
When a sorting option is selected, we make an AJAX call to parse the full HTML of the collection page, sorted with the specific sorting option selected. We are able to do this because when Shopify sorts a collection, it gives it a specific sort_by parameter in the URL:
https://[URL of your store]/collections/[collection handle]/?sort_by=[type]
Which means that we can make an AJAX call to our collection, passing in the sorting type name in the URL and we can then parse the HTML for the sorted collection to grab the data needed. First, we empty the previous list using the clear() method. Then we loop through all products inside the HTML data, and for each product we assign its image and title data to variables which we then use to add the new products to the list.
The list.js plugin does the rest and injects new elements inside our list element using the exact same structure we started out with. This means that every time we choose a sorting option, we are dynamically pinging the Shopify collection page, grabbing the sorted product data and then applying it to our page all in real time at the click of a menu.
This is a truly bespoke feature to solve a problem that there has been no solution to until this point (at least until such time as Shopify itself provides one). From here you can further explore the other features that the list.js plugin provides, such as filtering product types or tags and searching based on product titles. The sky is the limit! This is simply the beginning of what you could accomplish with this little trick, now it’s your turn to implement and build from there!