Thank you! Your feedback has been delivered
Thank you! Your feedback has been sent

jQuery Isotope with BBQ Hash History - highlight the active category link when clicking the back button

Hi,

I try to achieve a very simple tutorial combining the excellent jQuery isotope plugin and jQuery BBQ plugin for all the people (like me) who are not jQuery expert. Indeed, the David Desandro BBQ tutorial is very complex for us because the example page mixt the two plugins with a lot of Isotope options the most of us don’t need.

So, my example page contain the basic Isotope settings for animations, filtering and menu item highlighting. The combination of the two plugins works well, but I cannot figure out how to get the active category link to highlight when clicking the back button.

Here is the HTML code:

<div id=\"wrapper\">

<div id=\"sidebar\">

<ul class=\"nav\">
<li><a href=\"#filter=*\" class=\"selected\">All</a></li>
<li><a href=\"#filter=.red\">Red</a></li>
<li><a href=\"#filter=.orange\">Orange</a></li>
<li><a href=\"#filter=.yellow\">Yellow</a></li>
<li><a href=\"#filter=.green\">Green</a></li>
<li><a href=\"#filter=.blue\">Blue</a></li>
<li><a href=\"#filter=.black\">Black</a></li>
</ul>

</div>

<div id=\"gallery\">

<div class=\"box red\" style=\"background-color:red;\"></div>
<div class=\"box orange\" style=\"background-color:orange;\"></div>
<div class=\"box yellow\" style=\"background-color:yellow;\"></div>
<div class=\"box green\" style=\"background-color:green;\"></div>
<div class=\"box blue\" style=\"background-color:blue;\"></div>
<div class=\"box black\" style=\"background-color:black;\"></div>
<div class=\"box blue\" style=\"background-color:blue;\"></div>
<div class=\"box green\" style=\"background-color:green;\"></div>
<div class=\"box red\" style=\"background-color:red;\"></div>
<div class=\"box black\" style=\"background-color:black;\"></div>
<div class=\"box green\" style=\"background-color:green;\"></div>
<div class=\"box orange\" style=\"background-color:orange;\"></div>            

</div>

</div>

and here is the script:

$(document).ready(function(){
  // cache container
  var $container = $(\'#gallery\');
  // initialize isotope
  $container.isotope({
    // options
    filter: \'*\',
    animationOptions: {
      duration: 750,
      easing: \'linear\',
      queue: false
    }
});


// FILTER

$(\'ul.nav a\').click(function(){
  var selector = $(this).attr(\'data-filter\');
  $container.isotope({ 
  filter: selector 
  });
  return false;
});


// HIGHLIGHT SELECTED MENU ITEM

  var $optionSets = $(\'ul.nav\'),
  $optionLinks = $optionSets.find(\'a\');

  $optionLinks.click(function(){
    var $this = $(this);
    // don\'t proceed if already selected
    if ( $this.hasClass(\'selected\') ) {
      return false;
    }
  var $optionSet = $this.parents(\'ul.nav\');
  $optionSet.find(\'.selected\').removeClass(\'selected\');
  $this.addClass(\'selected\'); 
});


// HASH HISTORY WITH JQUERY BBQ

$(\'ul.nav a\').click(function(){
  // 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 );
  // set hash, triggers hashchange on window
  $.bbq.pushState( option );
  return false;
});

$(window).bind( \'hashchange\', function( event ){
  // get options object from hash
  var hashOptions = $.deparam.fragment();
  // apply options from hash
  $container.isotope( hashOptions );
})
  // trigger hashchange to capture any hash data on init
  .trigger(\'hashchange\');

});

I post the same question on Stackoverflow. Here is the link.

Any help would be appreciated.

Cheers

Gilles (from Belgium)

User Gravatar

gillesvk

Posted Jul 28 2013 14:42 UTC

$10


  • Assigned To guyisra
  • Solved
  • javascript
    jquery
    isotope
  • 3111 Views

8 Replies


Looking at the isotope BBQ page, you seem to be missing some functions

I have managed to fix it is a working version

 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\');
      }

      $(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
            // apply defaults where no option was specified
            options = $.extend( {}, hashOptions);
        // apply options from hash
       $(\'#gallery\').isotope( options );
        // save 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 = $(\'ul.nav\').find(\'a[href=\"#\' + hrefValue + \'\"]\');
            $(\'.selected\').removeClass(\'selected\');
            changeSelectedLink( $selectedLink );
          }
        })


        // trigger hashchange to capture any hash data on init
        .trigger(\'hashchange\');

This is a jsfiddle I\'ve made for this with your code. it is working note that .selected as font-size:20px, since you didnt include your css

User Gravatar

guyisra

Posted Jul 28 2013 16:39 UTC

oops, here is the link here, can\'t edit answers..

User Gravatar

guyisra

Posted Jul 28 2013 16:40 UTC

Hi Guy,

Thirst of all, thank you for your fast answer.

The code works but there is still a little problem when I open the page with FireFox and IE:

The last selected item stays highlighted when I click the back button. So I have 2 highlighted items in the same time.

Secondly, as I said, your jsfiddle code works (you add the code hereabove to the original code I posted) but I think we can now delete some part of the original code I posted. This is actually the hard part of the Isotope BBQ tutorial page from David Desandro website. What can I keep and what can I delete? I would like a clean code as simple as possible fitting exactly my needs.

I wrote a new jsfiddle. Here is the link.

Cheers

Gilles

User Gravatar

gillesvk

Posted Jul 29 2013 1:37 UTC

I have deleted some unused code here

this is a minimum as it can get, here is why (based on the order of the code):

  1. First you create and initialize isotope on a container

  2. then you set a click event on any links (a tags) in ul.nav

  3. Now it gets tricky - To use hash BBQ, you need to store objects, so you need to convert the hash (stuff after the question mark in the url) to an object that will be stored in the via option = $.deparam(href, true); and then store it $.bbq.pushState(option);

  4. declare a function that will take an element and add .selected to it and remove it from the others

  5. here comes another tricky part: the html5 history and the bbq plugin (which uses it) respond to events when clicking back and forward in the browser. In this case, the event is hashchange. So you need to bind the window to that event and when the event occurs you need to grab the url, find the hashes from it, convert it from objects (which is how $.deparam grabs it) into a regular text variable and then make isotope filter by it and highlight the correct color accordingly. Once that is done, you need to trigger hashchange so it will continue normally.

This is pretty much as simple as it gets, using the BBQ plugin. You would notice that in the isotope example, there is a lot more than this since it also creates squares randomly, etc.

User Gravatar

guyisra

Posted Jul 29 2013 6:48 UTC

Solution

This didn't solve your task? Get your own custom solution.

Quick fix - I wrote that hash is what comes after the question mark. Obvisouly, it what comes after the hash (#) mark in the url

User Gravatar

guyisra

Posted Jul 29 2013 6:51 UTC

Thank you Guy for the clean code and the explanations.

There is still a little problem when I open the jsfiddle with FireFox and IE (no broblem with Chrome). The last selected item stays highlighted when I click the back button. So I have 2 highlighted items in the same time.

Any ideas on how to fix that ?

Gilles

User Gravatar

gillesvk

Posted Jul 29 2013 23:48 UTC

the problem happens in a:focus in the css

when clicking on a link, that link is focused, when clicking back, that link is still focused, and so the style remains.

If a:focus is a must have, you can also unfocus, or blur, the other links with blur()

remove that attribute or add blur after removeClass and it works fine

see this fiddle. I\'ve colored the a:focus. You can see that the link retains the focus color. The focus disappears when you click anywhere on the screen (on jsfiddle its on the iframe) or use blur to remove the focus

This probably happens due to the differences in the implementation in chrome, ff and ie.. (probably in opera and others as well)

User Gravatar

guyisra

Posted Jul 30 2013 10:57 UTC

Thank you very much Guy. This question is now solved. I set the last reply but one as the correct answer because it is the important part.

Gilles

User Gravatar

gillesvk

Posted Jul 30 2013 15:38 UTC

Add a reply

By posting a reply on CodersClan you agree to our Terms & Conditions