27 August 2008

show/hide element using unobtrusive javascript

"Unobtrusive" javascript is all the rage these days, so I had to give it a go. The idea is, instead of sprinkling bits of javascript inside onclick and onmousemove and friends within your HTML, you use a class name or id to identify elements that will need some event handlers attached. Later, your javascript takes care of adding event handlers. Result: cleaner HTML, more control over javascript.

I was about to implement for the n-teenth time a little show/hide link pair when I realised, this is always the same, onclick this and onclick that; there must be a better way.

Enter Unobtrusive Javascript!!

<span style="color:blue" id="show_hidablestuff">show</span>
<span style="color:blue" id="hide_hidablestuff">hide</span>
<p id="hidablestuff" class="hidable">Now you can see this hidable stuff</p>

"Look, ma, no javascript!". I want to hide hidablestuff, so I give it a class name "hidable". There is no CSS associated with this class name, it's just a hook for javascript later on. Its corresponding show/hide links are related via their ids - show_hidablestuff and hide_hidablestuff. The script will calculate these ids in order to find their elements in the document.

The magic is here:

var initialiseShowHideTrigger = function(h) {
  var show_trigger = $("show_" + h.id); // assume the show trigger has the same id
                                        // as the target with "show_" prepended

  var hide_trigger = $("hide_" + h.id); // similarly for hide trigger

  show_trigger.onclick = function() { // add onclick handler to
    h.show();                         // show the target element,
    show_trigger.hide();              // hide the show trigger,
    hide_trigger.show();              // and show the hide trigger
  }

  hide_trigger.onclick = function() { // add onclick handler to
    h.hide();                         // hide the target element,
    show_trigger.show();              // show the show trigger,
    hide_trigger.hide();              // and hide the hide trigger
  }

  hide_trigger.onclick();             // trigger the hide trigger so initially
                                      // the target is hidden
}

// here we search for all elements with classname "hidable", and invoke
// initialiseShowHideTrigger on each. Call this from body.onload(), or
// from a script at the bottom of your page (after everything is loaded)
var initialiseShowHideTriggers = function() {
  $A(document.getElementsByClassName('hidable')).each(function(h) {
    initialiseShowHideTrigger(h);
  });
}

I plan to do a lot more of this.

4 comments:

  1. This is cool...I think we can use this in Beagle too..!

    ReplyDelete
  2. Hi Aditya

    I'm glad you like it! I'm using this approach as much as possible whenever I have javascript to write ... I'm sure the Beagle will like it too :))

    ReplyDelete
  3. This is very cool article. It helped mi a lot with my project, just the same as some other texts on this website. I'm gonna read other things too, because it's really good explained. Thanks for that!

    ReplyDelete
  4. Hi Jakub, I'm happy it helped with your project, let me know if there's anything else you need!

    cheers

    ReplyDelete