Filtering a collection with more than one product tag drop-down

Caution

This is an advanced tutorial and is not supported by Shopify. Knowledge of web design languages such as HTML, CSS, Javascript and Liquid is required. We suggest hiring a Shopify Expert if you are not comfortable proceeding with the following tutorial.

Note

In this tutorial, you will show how to use multiple select elements (drop-downs) to filter a collection.

You can preview the demo here.

Refresher on how subcategories work in Shopify

To filter collections by color, size, or vendor, one must use product tags.

Subcategories 1

The URL below filters the Women collection with product tag “Dresses”.

/collections/women/dresses

The URL below filters the Women collection with product tag “Dresses”, “Black” and “Between $40 and $60”.

/collections/women/dresses+black+between-40-and-60

Your mission

Your goal is to break down the collection's tags by category, to present a series of “shop by” filters on your collection page, like “shop by color”, “shop by vendor”, “shop by price” etc.

Whenever you need a “shop by” drop-down on a collection page, you need to handle things with product tags.

Instead of lumping together all product tags in the collection, you will break them down into categories.

Caution

In Shopify, there is no such thing as a product tag category. All product tags are on an equal footing. Product tags are not set to describe any particular facet of a product. Hence, to break down a collection's tags into categories, you will need to hard-code each list of tags.

Adding the code

  1. From your Shopify admin, click Online Store, and then click Themes (or press G W T).

  2. Find the theme you want to edit, click the ... button, and then click Edit HTML/CSS.

  3. Click Templates then collection.liquid to open it in the online code editor.

  4. Click on collection.liquid to open your collection template in the online code editor.

  5. Locate the code in collection.liquid that lists the product tags in your collection — if such code is used! Replace all of it with this one:

    
    <ul class="clearfix filters">
      <li class="clearfix filter">
        {% assign tags = 'Red, Green, Blue' | split: ',' %}
        <label>Shop by color</label>
        <select class="coll-filter">
          <option value="">All</option>
          {% for t in tags %}
          {% assign tag = t | strip %}
          {% if current_tags contains tag %}
          <option value="{{ tag | handle }}" selected>{{ tag }}</option>
          {% elsif collection.all_tags contains tag %}
          <option value="{{ tag | handle }}">{{ tag }}</option>
          {% endif %}
          {% endfor %}
        </select>
      </li>
      <li class="clearfix filter">
        {% assign tags = 'Small, Medium, Large' | split: ',' %}
        <label>Shop by size</label>
        <select class="coll-filter">
          <option value="">All</option>
          {% for t in tags %}
          {% assign tag = t | strip %}
          {% if current_tags contains tag %}
          <option value="{{ tag | handle }}" selected>{{ tag }}</option>
          {% elsif collection.all_tags contains tag %}
          <option value="{{ tag | handle }}">{{ tag }}</option>
          {% endif %}
          {% endfor %}
        </select>
      </li>
     <li class="clearfix filter">
        {% assign tags = 'Cotton, Leather, Polyester' | split: ',' %}
        <label>Shop by material</label>
        <select class="coll-filter">
          <option value="">All</option>
          {% for t in tags %}
          {% assign tag = t | strip %}
          {% if current_tags contains tag %}
          <option value="{{ tag | handle }}" selected>{{ tag }}</option>
          {% elsif collection.all_tags contains tag %}
          <option value="{{ tag | handle }}">{{ tag }}</option>
          {% endif %}
          {% endfor %}
        </select>
      </li>
    </ul>
    
    

You can add up to three filters to your collection page.

In the above code, there are three filters, feel free to remove one or two.

You will need to edit 2 lines of code for each filter:

  • The Shop By heading, e.g. <p>Shop by material</p>.

  • The list of tags you want to use for that filter (replace Cotton, Leather, Polyester with a comma-separated list of product tags. Each filter can use any number of tags.), e.g:

{% assign tags = 'Cotton, Leather, Polyester' | split: ',' %}

Product tags are case-sensitive

Make sure that the tags you list are exactly in the same case as the ones used in your shop. The product tag Blue is not the same as the product tag blue.

You will need some JavaScript now

It's very possible that your theme is already using JavaScript to handle whatever product tag drop-down you already had in your collection template. Remove that JavaScript and replace it with:

<script>
  /* Product Tag Filters - Good for any number of filters on any type of collection page.
     Give you product tag filter select element a class of coll-filter.
     Give your collection select a class of coll-picker.
     Brought to you by Caroline Schnapp. */
  Shopify.queryParams = {};
  if (location.search.length) {
    for (var aKeyValue, i = 0, aCouples = location.search.substr(1).split('&'); i < aCouples.length; i++) {
      aKeyValue = aCouples[i].split('=');
      if (aKeyValue.length > 1) {
        Shopify.queryParams[decodeURIComponent(aKeyValue[0])] = decodeURIComponent(aKeyValue[1]);
      }
    }
  }
  jQuery('.coll-picker').change(function() {
    if (jQuery(this).val()) {
      location.href = '/collections/' + jQuery(this).val();
    }
    else {
      location.href = '/collections/all';
    }
  });
  var collFilters = jQuery('.coll-filter');
  collFilters.change(function() {
    delete Shopify.queryParams.page;
    var newTags = [];
    collFilters.each(function() {
      if (jQuery(this).val()) {
        newTags.push(jQuery(this).val());
      }
    });
    {% if collection.handle %}
    var newURL = '/collections/{{ collection.handle }}';
    if (newTags.length) {
      newURL += '/' + newTags.join('+');
    }
    var search = jQuery.param(Shopify.queryParams);
    if (search.length) {
      newURL += '?' + search;
    }
    location.href = newURL;
    {% else %}
    if (newTags.length) {
      Shopify.queryParams.constraint = newTags.join('+');
    }
    else {
      delete Shopify.queryParams.constraint;
    }
    location.search = jQuery.param(Shopify.queryParams);
    {% endif %}
  });
</script>

If there was no JavaScript to begin with, just add that code at the very bottom of your collection.liquid template.

That JavaScript really needs to go in the collection.liquid template. It cannot be moved to an external .js.liquid file.

Styling the filters

Add this CSS at the bottom of your collection.liquid template:

<style>
/* some default styles */
.filters { list-style-type: none; }
.filter { float: left; margin-right: 15px; }
.filter label { display: block; margin: 10px 0; }
.filter select { max-width: 200px; }
</style>

First Bonus

To also present a collection filter to jump between all collections in your store, add this filter:

<li class="clearfix filter">
  <label>Shop by category</label>
  <select class="coll-picker">
    <option value="all">All</option>
    {% for c in collections %}
    {% unless c.handle == 'all' %}
    {% if collection.handle == c.handle %}
    <option value="{{ c.handle }}" selected>{{ c.title }}</option>
    {% else %}
    <option value="{{ c.handle }}">{{ c.title }}</option>
    {% endif %}
    {% endunless %}
    {% endfor %}
  </select>
</li>

The JavaScript we presented previously will be able to handle that additional filter.

To hand-pick your collections, create a Collections menu on your Navigation page, populate it with links to collections, and use the following alternate code:

<li class="clearfix filter">
  <label>Shop by category</label>
  <select class="coll-picker">
    <option value="all">All</option>
    {% for link in linklists.collections.links %}
    {% assign c = link.object %}
    {% if collection.handle == c.handle %}
    <option value="{{ c.handle }}" selected>{{ c.title }}</option>
    {% else %}
    <option value="{{ c.handle }}">{{ c.title }}</option>
    {% endif %}
    {% endfor %}
  </select>
</li>

Second Bonus

You can use the same technique to decide which product tags will be displayed on each collection page. Say, you want to list some tags on collection A page, but wish to list other tags on collection B page.

To control what product tags are shown in each collection, create a an alternate collection template for each collection you have, and add one or more filter to it.

Don't forget to assign each special collection template to their respective collection. There will be a Template drop-down on the collection page where you will be able to assign the collection template to your collection.

Use the same JavaScript again — the one we presented previously.

Demo Store

http://satterfield-pfeffer5655.myshopify.com/collections/all

Want to discuss this page?

Visit the Shopify Community