Create a gist now

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.

Show comment
Hide comment
@carolineschnapp

carolineschnapp 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
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.

Show comment
Hide comment
@carolineschnapp

carolineschnapp 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.

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.

Show comment
Hide comment
@customstudio

customstudio 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?

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.

Show comment
Hide comment
@kristianbangsoe

kristianbangsoe 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

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.

Show comment
Hide comment
@luiscielak

luiscielak Sep 28, 2015

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

@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.

Show comment
Hide comment
@bradmadiuk

bradmadiuk Jan 1, 2016

Thank you!

Thank you!

@gabebrown-freestyle

This comment has been minimized.

Show comment
Hide comment
@gabebrown-freestyle

gabebrown-freestyle 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?

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.

Show comment
Hide comment
@benjaminsehl

benjaminsehl 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?!

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.

Show comment
Hide comment
@marcobiedermann

marcobiedermann 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.

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.

Show comment
Hide comment
@Timbodas

Timbodas 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.

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.

Show comment
Hide comment
@Mobashir1995

Mobashir1995 Jul 31, 2017

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

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

@IonDaLion

This comment has been minimized.

Show comment
Hide comment
@IonDaLion

IonDaLion Oct 23, 2017

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

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.

Show comment
Hide comment
@james-zedd

james-zedd 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}`;
});

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.

Show comment
Hide comment
@zomars

zomars 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>

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.

Show comment
Hide comment
@eannehope12

eannehope12 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

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

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