WordPress.org

Forums

WordPress, Jquery BBQ, and Isotope (6 posts)

  1. bbart10
    Member
    Posted 2 years ago #

    Looking for help in integrating jquery bbq into my wordpress site. The site itself already utilizes Isotope as a portfolio sorter.
    The goal in the end is to be able to link to specific filtered item, not just the portfolio page. For example if I was on an about us page and I wanted to link to a specific category it wouldnt just take me to the portfolio page where everything is unfiltered but to the filter point.
    Jquery bbq seems to be my best bet using the hash history for me to be able to link to the specific filter states.
    Does anybody have any experience with anything, or is anything unclear.
    Looking for some guidance on how to incorporate jquery BBQ.

  2. ElwoodP
    Member
    Posted 2 years ago #

    Hi bbart10,
    I've just integrated jQuery BBQ onto a site to achieve what you describe. There is an example of BBQ itnegration with Isotope here:
    http://isotope.metafizzy.co/demos/hash-history.html
    and a tutorial here:
    http://isotope.metafizzy.co/docs/hash-history-jquery-bbq.html

    I didn't find the tutorial totally usefull though since it doesn't cover how to update the Navigation. I ended up stripping the javascript out of the example page (inline at the bottom of the page):

    $(function(){
    
          var $container = $('#container'),
              // object that will keep track of options
              isotopeOptions = {},
              // defaults, used if not explicitly set in hash
              defaultOptions = {
                filter: '*',
                sortBy: 'original-order',
                sortAscending: true,
                layoutMode: 'masonry'
              };
    
          // add randomish size classes
          $container.find('.element').each(function(){
            var $this = $(this),
                number = parseInt( $this.find('.number').text(), 10 );
            if ( number % 7 % 2 === 1 ) {
              $this.addClass('width2');
            }
            if ( number % 3 === 0 ) {
              $this.addClass('height2');
            }
          });
    
          var setupOptions = $.extend( {}, defaultOptions, {
            itemSelector : '.element',
            masonry : {
              columnWidth : 120
            },
            cellsByRow : {
              columnWidth : 240,
              rowHeight : 240
            },
            getSortData : {
              symbol : function( $elem ) {
                return $elem.attr('data-symbol');
              },
              category : function( $elem ) {
                return $elem.attr('data-category');
              },
              number : function( $elem ) {
                return parseInt( $elem.find('.number').text(), 10 );
              },
              weight : function( $elem ) {
                return parseFloat( $elem.find('.weight').text().replace( /[\(\)]/g, '') );
              },
              name : function ( $elem ) {
                return $elem.find('.name').text();
              }
            }
          });
    
          // set up Isotope
          $container.isotope( setupOptions );
    
          var $optionSets = $('#options').find('.option-set'),
              isOptionLinkClicked = false;
    
          // switches selected class on buttons
          function changeSelectedLink( $elem ) {
            // remove selected class on previous item
            $elem.parents('.option-set').find('.selected').removeClass('selected');
            // set selected class on new item
            $elem.addClass('selected');
          }
    
          $optionSets.find('a').click(function(){
            var $this = $(this);
            // don't proceed if already selected
            if ( $this.hasClass('selected') ) {
              return;
            }
            changeSelectedLink( $this );
                // get href attr, remove leading #
            var href = $this.attr('href').replace( /^#/, '' ),
                // convert href into object
                // i.e. 'filter=.inner-transition' -> { filter: '.inner-transition' }
                option = $.deparam( href, true );
            // apply new option to previous
            $.extend( isotopeOptions, option );
            // set hash, triggers hashchange on window
            $.bbq.pushState( isotopeOptions );
            isOptionLinkClicked = true;
            return false;
          });
    
          var hashChanged = false;
    
          $(window).bind( 'hashchange', function( event ){
            // get options object from hash
            var hashOptions = window.location.hash ? $.deparam.fragment( window.location.hash, true ) : {},
                // do not animate first call
                aniEngine = hashChanged ? 'best-available' : 'none',
                // apply defaults where no option was specified
                options = $.extend( {}, defaultOptions, hashOptions, { animationEngine: aniEngine } );
            // apply options from hash
            $container.isotope( options );
            // save options
            isotopeOptions = hashOptions;
    
            // if option link was not clicked
            // then we'll need to update selected links
            if ( !isOptionLinkClicked ) {
              // iterate over options
              var hrefObj, hrefValue, $selectedLink;
              for ( var key in options ) {
                hrefObj = {};
                hrefObj[ key ] = options[ key ];
                // convert object into parameter string
                // i.e. { filter: '.inner-transition' } -> 'filter=.inner-transition'
                hrefValue = $.param( hrefObj );
                // get matching link
                $selectedLink = $optionSets.find('a[href="#' + hrefValue + '"]');
                changeSelectedLink( $selectedLink );
              }
            }
    
            isOptionLinkClicked = false;
            hashChanged = true;
          })
            // trigger hashchange to capture any hash data on init
            .trigger('hashchange');
    
        });

    I then removed a few setup bits since I already had isotope working and changed a couple of IDs and classes to match my markup. Ended up with this:

    jQuery(function($){
    
          var $container = $('#containerp'),
              // object that will keep track of options
              isotopeOptions = {},
              // defaults, used if not explicitly set in hash
              defaultOptions = {
                filter: '*',
                sortBy: 'original-order',
                sortAscending: true,
                layoutMode: 'masonry'
              };
    
           var $optionSets = $('#projects').find('#filterNav'),
              isOptionLinkClicked = false;
    
          // switches selected class on buttons
          function changeSelectedLink( $elem ) {
            // remove selected class on previous item
            $elem.parents('#filterNav').find('.selected').removeClass('selected');
            // set selected class on new item
            $elem.addClass('selected');
          }
    
          $optionSets.find('a').click(function(){
            var $this = $(this);
            // don't proceed if already selected
            if ( $this.hasClass('selected') ) {
              return;
            }
            changeSelectedLink( $this );
                // get href attr, remove leading #
            var href = $this.attr('href').replace( /^#/, '' ),
                // convert href into object
                // i.e. 'filter=.inner-transition' -> { filter: '.inner-transition' }
                option = $.deparam( href, true );
            // apply new option to previous
            $.extend( isotopeOptions, option );
            // set hash, triggers hashchange on window
            $.bbq.pushState( isotopeOptions );
            isOptionLinkClicked = true;
            return false;
          });
    
          var hashChanged = false;
    
          $(window).bind( 'hashchange', function( event ){
            // get options object from hash
            var hashOptions = window.location.hash ? $.deparam.fragment( window.location.hash, true ) : {},
                // do not animate first call
                aniEngine = hashChanged ? 'best-available' : 'none',
                // apply defaults where no option was specified
                options = $.extend( {}, defaultOptions, hashOptions, { animationEngine: aniEngine } );
            // apply options from hash
            $container.isotope( options );
            // save options
            isotopeOptions = hashOptions;
    
            // if option link was not clicked
            // then we'll need to update selected links
            if ( !isOptionLinkClicked ) {
              // iterate over options
              var hrefObj, hrefValue, $selectedLink;
              for ( var key in options ) {
                hrefObj = {};
                hrefObj[ key ] = options[ key ];
                // convert object into parameter string
                // i.e. { filter: '.inner-transition' } -> 'filter=.inner-transition'
                hrefValue = $.param( hrefObj );
                // get matching link
                $selectedLink = $optionSets.find('a[href="#' + hrefValue + '"]');
                changeSelectedLink( $selectedLink );
              }
            }
    
            isOptionLinkClicked = false;
            hashChanged = true;
          })
            // trigger hashchange to capture any hash data on init
            .trigger('hashchange');
    
        });

    Hope that helps. I'm no javascript expert but this seems to work.

  3. mixette
    Member
    Posted 1 year ago #

    Hi,

    I'm also using BBQ hash and isotope, with the above script, but I've got a problem with the urls.
    If you navigate through the testsite you'll see what I mean: http://46.18.32.129/~ftwee/

    When I'm on a "normal" wordpres page in my website (eg url http://46.18.32.129/~ftwee/contact/ ) and I click on one of the isotope filters (eg #filter=.producten), the url of the page I was on is kept and the filter is added to the url:

    http://46.18.32.129/~ftwee/contact/#filter=.producten

    That's not correct because the root of my site is http://46.18.32.129/~ftwee/ so the page producten should be:
    http://46.18.32.129/~ftwee/#filter=.producten

    So what comes before the # is not updated. I can't find a solution to this.

  4. ElwoodP
    Member
    Posted 1 year ago #

    Hi Mixette,

    If I understand you correctly all you need to do is add the path to the page with Isotope before the filter in your link.

    So your code:
    <a href="#filter=.producten">Over ons</a>

    should be:
    <a href="http://46.18.32.129/~ftwee/#filter=.producten">Over ons</a>

  5. ElwoodP
    Member
    Posted 1 year ago #

    By the way I think adding a path before the filter probably won't work on your homepage (the page with isotope on). You will probably have to load a separate menu on the homepage to other pages.

    One option would be to use a plugin like this to load a different menu on your homepage:
    http://wordpress.org/plugins/menu-items-visibility-control/

  6. samwightwick
    Member
    Posted 1 year ago #

    Hi guys

    I have a new theme and pretty much have this working, but I always have to click my filters twice for them to work

    eg
    Clicking the design filter produces this url
    http://wpiso.dev/#/%23filter=.category-design

    Clicking again, it works and uses this url
    http://wpiso.dev/#filter=.category-design

    I can tell whats wrong, but not sure how to correct it!
    thanks

Topic Closed

This topic has been closed to new replies.

About this Topic