title: Isotope Filter, Sort, Search and Url Hash
body: <p>I'm using Isotope to sort, filter and search a page of products. So far so good.
  I'm stuck on a couple of areas. I've not been able to find an example online with the exact combination of features I require so need some help.</p>
  
  <p>In a nutshell I have multiple select dropdowns filtering products, select price sort order and a quick search input field. All work but I have some needed amends. </p>
  
  <p>TO DO:</p>
  
  <p>Search doesn't work after filtering. I need it to work with the filters.</p>
  
  <p>Addition of sort by 'Sale' and 'New In' on the price select dropdown.</p>
  
  <p>Addition of URL hash listener to create links for filtering i.e link to New In sorted first.</p>
  
  <p><a href="http://isotope.metafizzy.co" rel="nofollow noreferrer">Isotope website</a></p>
  
  <p><a href="https://codepen.io/desandro/pen/jubmr" rel="nofollow noreferrer">Select Example</a></p>
  
  <p><a href="https://codepen.io/desandro/pen/vErxXj" rel="nofollow noreferrer">URL Hash example</a></p>
  
  <p><a href="https://codepen.io/desandro/pen/wfaGu" rel="nofollow noreferrer">Quick search example</a></p>
  
  <p>My current JS for filtering and sorting:</p>
  
  <pre><code>        $(document).ready(function(){
  
  // quick search regex
  var qsRegex;
  var filterValue;
  // init Isotope
  var $grid = $(".grid").isotope({
    itemSelector: ".grid-item",
    layoutMode: "fitRows",
    getSortData: {
      price: '.t-price parseInt',
      category: '[data-category]',
    },
    filter: function() {
      var $this = $(this);
      var searchResult = qsRegex ? $this.text().match(qsRegex) : true;
      var selectResult = filterValue ? $this.is(filterValue) : true;
      return searchResult  &amp;&amp; selectResult;
    }
  });
  
        // bind filter on select change
  //$(".filter-select").on("change", function() {
         // get filter value from option value
   // filterValue = $(this).val();
    //console.log(filterValue);
    //$grid.isotope();
  //});
  
  
  // store filter for each group
  var filters = {};
  
  $('.filter-select').on( 'change', function( event ) {
    var $select = $( event.target );
    // get group key
    var filterGroup = $select.attr('value-group');
    // set filter for group
    filters[ filterGroup ] = event.target.value;
    // combine filters
    var filterValue = concatValues( filters );
    // set filter for Isotope
    $grid.isotope({ filter: filterValue });
  });
  
  // flatten object by concatting values
  function concatValues( obj ) {
    var value = '';
    for ( var prop in obj ) {
      value += obj[ prop ];
    }
    return value;
  }
  
  
  
  $('#price-sort').on( 'change', function() {
            var type = $(this).find(':selected').attr('data-sorttype');
            console.log(type);
      var sortValue = this.value;
        if(type=='ass'){$grid.isotope({ sortBy: sortValue , sortAscending: false});}
            else{$grid.isotope({ sortBy: sortValue , sortAscending: true});}
     $grid.isotope({ sortBy: sortValue });
    });
  
  
    // change is-checked class on buttons
    $('#price-sort').on( 'change', function() {
      var sortByValue = this.value;
        console.log(sortByValue);
      $grid.isotope({ sortBy: sortByValue});
    });
  
  
  // use value of search field to filter
  var $quicksearch = $(".quicksearch").keyup(
    debounce(function() {
      qsRegex = new RegExp($quicksearch.val(), "gi");
      $grid.isotope();
    })
  );
  // debounce so filtering doesn't happen every millisecond
  function debounce(fn, threshold) {
    var timeout;
    return function debounced() {
      if (timeout) {
        clearTimeout(timeout);
      }
      function delayed() {
        fn();
        timeout = null;
      }
      setTimeout(delayed, threshold || 100);
    };
  }
  
  
    });
  </code></pre>
  
  <p>HTML:</p>
  
  <pre><code>    &lt;div id="sort-filter"&gt;
          &lt;div id="sort"&gt;
                          &lt;select id="price-sort" class="select-css form-control long"&gt;
                  &lt;option selected disabled class="s-title"&gt; Sort &lt;/option&gt;
                  &lt;option data-sorttype="dec" value="price"&gt;£ Low To High&lt;/option&gt;
                  &lt;option data-sorttype="ass" value="price"&gt;£ High To Low&lt;/option&gt;
  
              &lt;/select&gt;
  
          &lt;/div&gt;
          &lt;div class="filters"&gt;
                      &lt;select class="filter-select select-css short" value-group="sizes" id="sizes"&gt;
                      &lt;option selected disabled class="s-title"&gt; Size &lt;/option&gt;
                        &lt;option value="*"&gt;All&lt;/option&gt;
                        &lt;option value=".XS"&gt;XS&lt;/option&gt;
                        &lt;option value=".S"&gt;S&lt;/option&gt;
                        &lt;option value=".M"&gt;M&lt;/option&gt;
                        &lt;option value=".L"&gt;L&lt;/option&gt;
                        &lt;option value=".XL"&gt;XL&lt;/option&gt;
                        &lt;option value=".XXL"&gt;XXL&lt;/option&gt;
                      &lt;/select&gt;
      &lt;/div&gt;
      &lt;/div&gt;
  
  &lt;div class="container"&gt;
  
      &lt;ul class="grid cs-style-3"&gt;
          &lt;div class="grid-sizer"&gt;&lt;/div&gt;
  
              &lt;li class="grid-item XS Male Beige Bags Mint"&gt;
                  &lt;a href="link" class="animsition-link" data-animsition-out-class="fade-out-left-lg"&gt;
                      &lt;figure style="background-image: URL(image.jpg);"&gt;
                          &lt;img src="/image2.jpg" alt="hat sale item"&gt;
                  &lt;/figure&gt;
                  &lt;div id="pro-deets"&gt;
                  &lt;h3&gt;hat sale item&lt;/h3&gt;
                          &lt;span id="price" class="holderpage"&gt;
                              £&lt;span class="price t-price"&gt;3&lt;/span&gt;
  
                          &lt;/span&gt;
                  &lt;/div&gt;&lt;/a&gt;
              &lt;/li&gt;
  
              &lt;li class="grid-item L Female Brown Tops Worn"&gt;
                  &lt;a href="link" class="animsition-link" data-animsition-out-class="fade-out-left-lg"&gt;
                      &lt;figure style="background-image: URL(image.jpg);"&gt;
                          &lt;img src="/image2.jpg" alt="product no sale no new"&gt;
                  &lt;/figure&gt;
                  &lt;div id="pro-deets"&gt;
                  &lt;h3&gt;product no sale no new&lt;/h3&gt;
                          &lt;span id="price" class="holderpage"&gt;
                              £&lt;span class="price t-price"&gt;40&lt;/span&gt;
  
                          &lt;/span&gt;
                  &lt;/div&gt;&lt;/a&gt;
              &lt;/li&gt;
  
              &lt;li class="grid-item L Female Brown Tops Worn New" data-category="New"&gt;
                  &lt;a href="link" class="animsition-link" data-animsition-out-class="fade-out-left-lg"&gt;
                      &lt;figure style="background-image: URL(image.jpg);"&gt;
                          &lt;img src="/image2.jpg" alt="Skirt"&gt;
                  &lt;/figure&gt;
                  &lt;div id="pro-deets"&gt;
                  &lt;h3&gt;Skirt&lt;/h3&gt;
                          &lt;span id="price" class="holderpage"&gt;
                              £&lt;span class="price t-price"&gt;10&lt;/span&gt;
  
                          &lt;/span&gt;
                  &lt;/div&gt;&lt;/a&gt;
              &lt;/li&gt;
  
              &lt;li class="grid-item XS Male Beige Bags Mint Sale" data-category="Sale"&gt;
                  &lt;a href="link" class="animsition-link" data-animsition-out-class="fade-out-left-lg"&gt;
                      &lt;figure style="background-image: URL(image.jpg);"&gt;
                          &lt;img src="/image2.jpg" alt="Jacket"&gt;
                  &lt;/figure&gt;
                  &lt;div id="pro-deets"&gt;
                  &lt;h3&gt;Jacket&lt;/h3&gt;
                          &lt;span id="price" class="holderpage"&gt;
                              £&lt;span class="price sale"&gt;30&lt;/span&gt;
                              &lt;span class="price"&gt;£&lt;span class="t-price"&gt;20&lt;/span&gt;&lt;/span&gt;
                          &lt;/span&gt;
                  &lt;/div&gt;&lt;/a&gt;
              &lt;/li&gt;
  
          &lt;/ul&gt;
          &lt;/div&gt;  
  </code></pre>