title: How to implement Isotope with Pagination
body: <p>I am trying to implement isotope with pagination on my WordPress site (which obviously is a problem for most people). I've come up with a scenario which may work if I can figure a few things out.</p>
  
  <p>On my page, I have this part of my isotope script -
  </p>
  
  <pre><code>$('.goforward').click(function(event) {
      var href = $(this).attr('href');
      $('.isotope').empty();
      $('.isotope').load(href +".html .isotope &gt; *");
      $( 'div.box' ).addClass( 'isotope-item' );
      $container.append( $items ).isotope( 'insert', $items, true );
      event.preventDefault();
  });
  </code></pre>
  
  <p>Then I am using this pagination function which I modified from <a href="http://www.kriesi.at/archives/how-to-build-a-wordpress-post-pagination-without-plugin" rel="noreferrer">here</a> to have the 'goforward' class --
  </p>
  
  <pre><code>function isotope_pagination($pages = '', $range = 2)
  {  
       $showitems = ($range * 2)+1;  
  
       global $paged;
       if(empty($paged)) $paged = 1;
  
       if($pages == '')
       {
           global $wp_query;
           $pages = $wp_query-&gt;max_num_pages;
           if(!$pages)
           {
               $pages = 1;
           }
       }   
  
       if(1 != $pages)
       {
           echo "&lt;div class='pagination'&gt;";
           for ($i=1; $i &lt;= $pages; $i++)
           {
               if (1 != $pages &amp;&amp;( !($i &gt;= $paged+$range+1 || $i &lt;= $paged-$range-1) || $pages &lt;= $showitems ))
               {
                   echo ($paged == $i)? "&lt;a href='".get_pagenum_link($i)."' class='inactive goforward'&gt;".$i."&lt;/a&gt;":"&lt;a href='".get_pagenum_link($i)."' class='inactive goforward' &gt;".$i."&lt;/a&gt;";
               }
           }
           echo "&lt;/div&gt;\n";
       }
  }
  </code></pre>
  
  <p><strong>1st Problem</strong> - I'm having issues with the filtering/sorting. It filters fine for the first page, but doesn't sort. On the second page or any other page loaded it does not append/insert or even filter/sort when starting fresh on that page. Instead, when trying to do so it gives me this error --</p>
  
  <pre><code>Uncaught TypeError: Cannot read property '[object Array]' of undefined
  </code></pre>
  
  <p><strong>2nd Problem</strong> - When loading the page fragments, there's a delay and the current page is still visible before the next page fragment is loaded in its place.</p>
  
  <p>I know a lot of people have problems with isotope and pagination, usually, end up using infinite scroll even though isotope author does not recommend it.</p>
  
  <p>So my theory is loading content via load() and have a callback of some sort to only display filtered items.</p>
  
  <p>Any ideas on how to achieve this?</p>
  
  <p>My entire isotope script --- 
  </p>
  
  <pre><code>$(function () {
      var selectChoice, updatePageState, updateFiltersFromObject,
      $container = $('.isotope');
      $items = $('.item');  
  
      ////////////////////////////////////////////////////////////////////////////////////
      /// EVENT HANDLERS
      ////////////////////////////////////////////////////////////////////////////////////
          //////////////////////////////////////////////////////
          // Mark filtering element as active/inactive and trigger filters update
          $('.js-filter').on( 'click', '[data-filter]', function (event) {
            event.preventDefault();
            selectChoice($(this), {click: true});
            $container.trigger('filter-update');
          });
          //////////////////////////////////////////////////////
          // Sort filtered (or not) elements
          $('.js-sort').on('click', '[data-sort]', function (event) {
            event.preventDefault();
            selectChoice($(this), {click: true});
            $container.trigger('filter-update');
          });
          //////////////////////////////////////////////////////
          // Listen to filters update event and update Isotope filters based on the marked elements
          $container.on('filter-update', function (event, opts) {
            var filters, sorting, push;
            opts = opts || {};
            filters = $('.js-filter li.active a:not([data-filter="all"])').map(function () {
              return $(this).data('filter');
            }).toArray();
            sorting = $('.js-sort li.active a').map(function () {
              return $(this).data('sort');
            }).toArray();
            if (typeof opts.pushState == 'undefined' || opts.pushState) {
              updatePageState(filters, sorting);
            }
            $container.isotope({
              filter: filters.join(''),
              sortBy: sorting
            });
  
          });
          //////////////////////////////////////////////////////
          // Set a handler for history state change
          History.Adapter.bind(window, 'statechange', function () {
            var state = History.getState();
            updateFiltersFromObject(state.data);
            $container.trigger('filter-update', {pushState: false});
          });
          ////////////////////////////////////////////////////////////////////////////////////
          /// HELPERS FUNCTIONS
          ////////////////////////////////////////////////////////////////////////////////////
          //////////////////////////////////////////////////////
          // Build an URI to get the query string to update the page history state
          updatePageState = function (filters, sorting) {
            var uri = new URI('');
            $.each(filters, function (idx, filter) {
              var match = /^\.([^-]+)-(.*)$/.exec(filter);
              if (match &amp;&amp; match.length == 3) {
                uri.addSearch(match[1], match[2]);
              }
            });
            $.each(sorting, function (idx, sort) {
              uri.addSearch('sort', sort);
            });
            History.pushState(uri.search(true), null, uri.search() || '?');
          };
          //////////////////////////////////////////////////////
          // Select the clicked (or from URL) choice in the dropdown menu
          selectChoice = function ($link, opts) {
            var $group = $link.closest('.btn-group'),
                $li = $link.closest('li'),
                mediumFilter = $group.length == 0;
            if (mediumFilter) {
              $group = $link.closest('.js-filter');
            }
  
            if (opts.click) {
              $li.toggleClass('active');
            } else {
              $li.addClass('active');
            }
            $group.find('.active').not($li).removeClass('active');
            if (!mediumFilter) {
              if ($group.find('li.active').length == 0) {
                $group.find('li:first-child').addClass('active');
              }
              $group.find('.selection').html($group.find('li.active a').first().html());
            }
          };
          //////////////////////////////////////////////////////
          // Update filters by the values in the current URL
          updateFiltersFromObject = function (values) {
            if ($.isEmptyObject(values)) {
              $('.js-filter').each(function () {
                  selectChoice($(this).find('li').first(), {click: false});
              });
              selectChoice($('.js-sort').find('li').first(), {click: false});
            } else {
              $.each(values, function (key, val) {
                val = typeof val == 'string' ? [val] : val;
                $.each(val, function (idx, v) {
                  var $filter = $('[data-filter=".' + key + '-' + v + '"]'),
                      $sort = $('[data-sort="' + v + '"]');
                  if ($filter.length &gt; 0) {
                    selectChoice($filter, {click: false});
                  } else if ($sort.length &gt; 0) {
                    selectChoice($sort, {click: false});
                  }
                });
              });
            }
          };
          ////////////////////////////////////////////////////////////////////////////////////
          /// Initialization
          ////////////////////////////////////////////////////////////////////////////////////
          //////////////////////////////////////////////////////
          // Initialize Isotope
      $container.imagesLoaded( function(){
          $container.isotope({
              masonry: { resizesContainer: true },
              itemSelector: '.item',
              getSortData: {
                  date: function ( itemElem ) {
                      var date = $( itemElem ).find('.thedate').text();
                      return parseInt( date.replace( /[\(\)]/g, '') );
                  },
              area: function( itemElem ) { // function
                  var area = $( itemElem ).find('.thearea').text();
                  return parseInt( area.replace( /[\(\)]/g, '') );
              },
              price: function( itemElem ) { // function
                  var price = $( itemElem ).find('.theprice').text();
                  return parseInt( price.replace( /[\(\)]/g, '') );
              }
          }
      });
  
      var total = $(".next a:last").html();
      var pgCount = 1;
      var numPg = total;
      pgCount++;
  
      $('.goback').click(function() {
          $('.isotope').empty();
          $('.isotope').load("/page/&lt;?php echo --$paged;?&gt;/?&lt;?php echo $_SERVER["QUERY_STRING"]; ?&gt;.html .isotope &gt; *");
          $container.append( $items ).isotope( 'insert', $items, true );
          $( 'div.box' ).addClass( 'isotope-item' );
     });
  
     $('.goforward').click(function(event) {
         var href = $(this).attr('href');
         $('.isotope').empty();
         $('.isotope').load(href +".html .isotope &gt; *");
         $( 'div.box' ).addClass( 'isotope-item' );
         $container.append( $items ).isotope( 'insert', $items, true );
         event.preventDefault();
     });
  });
          //////////////////////////////////////////////////////
          // Initialize counters
          $('.stat-count').each(function () {
            var $count = $(this),
                filter = $count.closest('[data-filter]').data('filter');
            $count.html($(filter).length);
          });
          //////////////////////////////////////////////////////
          // Set initial filters from URL
          updateFiltersFromObject(new URI().search(true));
          $container.trigger('filter-update', {pushState: false});
        }); 
  });
  </code></pre>