Instantly share code, notes, and snippets.

Embed
What would you like to do?
<div>
<label for="sort-by">Sort by</label>
<select id="sort-by">
<option value="manual">Featured</option>
<option value="price-ascending">Price: Low to High</option>
<option value="price-descending">Price: High to Low</option>
<option value="title-ascending">A-Z</option>
<option value="title-descending">Z-A</option>
<option value="created-ascending">Oldest to Newest</option>
<option value="created-descending">Newest to Oldest</option>
<option value="best-selling">Best Selling</option>
</select>
</div>
<script>
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('#sort-by')
.val('{{ collection.sort_by | default: collection.default_sort_by | escape }}')
.bind('change', function() {
Shopify.queryParams.sort_by = jQuery(this).val();
location.search = jQuery.param(Shopify.queryParams).replace(/\+/g, '%20');
});
</script>
@carolineschnapp

This comment has been minimized.

Owner

carolineschnapp commented Jun 1, 2014

Hi @typeofgraphic, sort_by only works with those values:

  • manual
  • price-ascending
  • price-descending
  • title-ascending
  • title-descending
  • created-ascending
  • created-descending
  • best-selling
@carolineschnapp

This comment has been minimized.

Owner

carolineschnapp commented Jul 15, 2015

How do I change the default sorting order on the collection page, when the collection is sortable on the storefront? Example: By default, it shows the products A to Z, and I want to sort by publication date.

Answer

The type of ordering selected on the collection page in your admin becomes the default sort order on your storefront for said collection.

For example, if you order from A to Z in the admin, if you visit your collection page on your store front, the sort order will be from A to Z. From there, if you pick 'Featured' in the sort drop-down, you will see the Manual order of products as last set by yourself in your admin.

So, to change the default type of sort on your storefront, go to the admin page of your collection, and select a different type of sort.

If you're interested in changing the default order on your Catalog page, you will need to create a collection with handle “all”, and select a sort order for it.

The above is entirely done on the collection pages in your admin, and not in the theme.

@customstudio

This comment has been minimized.

customstudio commented Jul 17, 2015

Hi Caroline, thanks for the filtering code above. Do you know how I could set the default display order to be by vendor (as in this thread: https://ecommerce.shopify.com/c/ecommerce-design/t/sort-filter-sorting-by-vendor-and-type-161547) but still allow users the option of reordering?

@kristianbangsoe

This comment has been minimized.

kristianbangsoe commented Sep 21, 2015

The easy way to do this is by going to Online Store (The globe) / Navigation / and on the end of the links type ex. ?sort_by=best-selling or ?sort_by=title-ascending

@luiscielak

This comment has been minimized.

luiscielak commented Sep 28, 2015

@carolineschnapp What about setting the default sort for a collection based on a type? for example /collections/types?q=shirt

@bradmadiuk

This comment has been minimized.

bradmadiuk commented Jan 1, 2016

Thank you!

@gabebrown-freestyle

This comment has been minimized.

gabebrown-freestyle commented Jan 5, 2016

Hello, if we'd like to change the "Best Sellers" sort item to use $$ sold instead of units sold, how would we modify the search variable?

@benjaminsehl

This comment has been minimized.

benjaminsehl commented Aug 26, 2016

Hi, @carolineschnapp!

I've done the following so that I could display the items all at once instead of a drop-down:

<!-- /snippets/collection-sorting.liquid -->
<div class="form-horizontal">
  <div class="os_categoryFilterLinks">
    <ul>
      <li><a href="#sort" data-select="manual">{{ 'collections.sorting.featured' | t }}</a></li>
      <li><a href="#sort" data-select="best-selling">{{ 'collections.sorting.best_selling' | t }}</a></li>
      <li><a href="#sort" data-select="created-descending">{{ 'collections.sorting.date_descending' | t }}</a></li>
      <li><a href="#sort" data-select="price-ascending">{{ 'collections.sorting.price_ascending' | t }}</a></li>
      <li><a href="#sort" data-select="price-descending">{{ 'collections.sorting.price_descending' | t }}</a></li>
    </ul>
  </div>
</div>

<script>
  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]);
      }
    }
  }

    var $select = $('#SortBy');
    $('a[href="#sort"]').click(function () {
        $select.val( $(this).data('select') );
        event.preventDefault();
        Shopify.queryParams.sort_by = jQuery(this).data('select');
        location.search = jQuery.param(Shopify.queryParams);
    });

  $(function() {
    $('#SortBy')
      .val('{{ collection.sort_by | default: collection.default_sort_by }}')
      .bind('change', function() {
        Shopify.queryParams.sort_by = jQuery(this).val();
        location.search = jQuery.param(Shopify.queryParams);
      }
    );
  });
</script>

Unfortunately, while the URL resolves correctly, my collection isn't sorting! Help?!

@marcobiedermann

This comment has been minimized.

marcobiedermann commented Feb 23, 2017

This could be easily implemented with some newer APIs and ES2015 syntax. No need for jQuery:

document.querySelector('#sort-by').addEventListener('change', function() {
  const urlSearchParams = new URLSearchParams(window.location.search);

  urlSearchParams.set(this.name, this.value);

  window.location = `?${urlSearchParams}`;
});

I like to use the latest web techniques and use some build tool like babel to transpile it for older browsers. Also check for URLSearchPrams support. If not, load a shim.

@Timbodas

This comment has been minimized.

Timbodas commented Jun 23, 2017

Hi Caroline, I used your first code and it worked perfectly, however, I would like to align right. Right now, it's aligning left. I don't know anything about code or CSS. Please help. Thanks.

@Mobashir1995

This comment has been minimized.

Mobashir1995 commented Jul 31, 2017

What should I need to do, if I want to do it with ajax...
Thanks for any suggestion.

@IonDaLion

This comment has been minimized.

IonDaLion commented Oct 23, 2017

Hey guys, is there a way to change the font of the text inside the drop down?
Thanks!

@james-zedd

This comment has been minimized.

james-zedd commented Apr 24, 2018

Hey all. This is a great code and I'm thankful for everyone's contribution.

I tried installing this on a new Shopify theme built with Slate, and I ran into some problems with the original code. I then swapped the JS with what @marcobiedermann posted but I had to add "sort_by" to the last line to make it work properly.

After a few tries and some help with the code, here is what I am using in my <script> tag that is working. Thanks again everyone for your contributions!

document.querySelector('#sort-by').addEventListener('change', function() {
  const urlSearchParams = new URLSearchParams(
    window.location.search.indexOf("sort_by") > -1
    ? window.location.search.replace(/sort_by/gi,"")
    : window.location.search
  );

  urlSearchParams.set(this.name, this.value);

  window.location = `?sort_by${urlSearchParams}`;
});
@zomars

This comment has been minimized.

zomars commented May 14, 2018

I've took your code @james-zedd and made it so it renders the current selected option:

<div id="sort-by-container"></div>
<script>
  var currentURL = new URL(window.location);
  var currentParams = currentURL.searchParams.get('sort_by');
  var urlSearchParams = new URLSearchParams(
    window.location.search.indexOf("sort_by") > -1
    ? window.location.search.replace(/sort_by/gi,"")
    : window.location.search
  );

  var render = function (template, node) {
    node.innerHTML = template;

    node.querySelector('#sort-by').addEventListener('change', function() {
      urlSearchParams.set(this.name, this.value);
      window.location = `?sort_by${urlSearchParams}`;
    });
  };

  var SortOptions = [{
    label: 'Featured',
    value: 'manual'
  }, {
    label: 'Price: Low to High',
    value: 'price-ascending'
  }, {
    label: 'Price: High to Low',
    value: 'price-descending'
  }, {
    label: 'A-Z',
    value: 'title-ascending'
  }, {
    label: 'Z-A',
    value: 'title-descending'
  }, {
    label: 'Oldest to Newest',
    value: 'created-ascending'
  }, {
    label: 'Newest to Oldest',
    value: 'created-descending'
  }, {
    label: 'Best Selling',
    value: 'best-selling'
  }];

  var template = `
    <div>
      <label for="sort-by">Sort by</label> 
      <select id="sort-by">
        ${SortOptions.map((item) =>
          `<option value="${item.value}" ${currentParams === item.value ? 'selected' : ''}>${item.label}</option>`
        ).join('')}
      </select>
    </div>
  `;

  render(template, document.querySelector('#sort-by-container'));
</script>
@eannehope12

This comment has been minimized.

eannehope12 commented Jul 20, 2018

Hi
Attached is a screenshot of my current set-up for Shopify. I am having trouble figuring out what to get rid of, and where to add this dropdown code. Currently, it sorts by tag, which is what we don't want. Any help appreciated!
screen shot 2018-07-20 at 12 48 02 pm

@RoohBear

This comment has been minimized.

RoohBear commented Oct 6, 2018

I was able to add this without much difficulty using the Radiance theme. Thank you!

Got any ideas on how I can make the items show up in RANDOM order first? Because I have 9000 different items, it's always the first 30 or so that get the most exposure which isn't fair... I want a random product list THEN let the user do a sort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment