ucantblamem

Mootools: Unobtrusive JavaScript

29th Apr 2007

The key component to any truly unobtrusive JavaScript is Event Listeners. In basic terms, what they allow us to do is run code when certain things happen on a page; For instance, we can register a particular function to the “click” event of a link. Every time that link is clicked it runs the function.

This obviously allows us to do some pretty neat stuff, without having to add anything to our markup, but there is one distinct problem with Event Listeners; Essentially, the tie between the function and the object (i.e. The link object) is in-direct. That is that an “Event” is tied to an object and a function is then tied to an Event, which means that the function cannot (directly) return anything to the object.

So, why is this a problem? Let’s look at an example:

In the old days, if we wanted to add JavaScript validation to a form, you would probably have done something like this:

<script>
function validate() {
  if (this.firstname.value == '') {
    alert('Please fill in your name');
    return false;
  }
}
</script>

<form name="myform" onsubmit="return validate();">
 	<input name="firstname" type="text" />
 	<input value="Submit" type="submit" />
</form>

As you can see the “onsubmit” action of the form waits for a return from the function. If the function returns false, the form no longer submits and therefore the Person using the form doesn’t leave the page.

Getting back to our Event Listeners, we can see that already we’re missing out on some pretty vital functionality, so what are our options. Well for starters, the submission of a form (and any of the “on….” events for that matter) don’t necessarily have to receive a return; In fact, if they receive nothing back (i.e. We halt the event itself) then we’re going one step better.

Thankfully MooTools (v1.0.0+) gives us a great implementation of “Events”, which means we have tonnes of control. Let’s look at this in code (A glossary is provided at the bottom of this article):

<script type="text/javascript">
// Instead of waiting for the 'ol "onload" event,
// we can start behaviours just after the html has loaded
// (and before anything else is);
// When the DOM is ready to role:
window.addEvent('domready', function() {
  // Associate a function with the "onsubmit" event of our form:
  $('myform').addEvent('submit', function(event) {
    // Assign our "event" to a new Event object
    // this way we can control it with the methods provided by
    // the Event class:
    var e = new Event(event);
    // Do our validation:
    if ($('firstname').value == '') {
      // Create a new element to contain the error and
      // insert it just before the "firstname" object:
      // I have split this over three lines, so it fits
      // But you could just concatenate these three lines
      var error = new Element('p').addClass('error');
      error.setHTML('Please provide your first name.');
      error.injectBefore($('firstname'));
      // THIS IS THE IMPORTANT ONE:
      // We stop our event from continuing:
      e.stop();
    }
  });
});
</script>
<form id="myform" method="post" action="/">
 	<input id="firstname" type="text" />
 	<input value="submit" type="submit" />
</form>

What we have now is a beautifully untouched piece of XHTML, thanks to MooTools and a little bit of our own spice. As commented in the code, the important parts are creating a new instance of the Event class and using the stop() method to halt the current event when we need to.

This functionality isn’t limited to the MooTools framework of course, in fact, most of what MooTools does really is consolidate a lot of in-built JavaScript functions so that by calling a single method any cross-browser issues that we may run into are handled for us. And the other big sell-point for Moo, of course, is that everything is Object-Oriented.

There isn’t a lot of documentation out there on handling scenario’s like the one used in the example for some reason, so I hope this has helped you see how to take full advantage of Event Listeners.

Happy coding!

Glossary

In the MooTools example above, there are a number of functions and methods that may be quite obscure to those who have never used MooTools previously. This glossary attempts to very quickly explain some of these things, but it is recommended that you lookup the official documentation for a more comprehensive explanation:

object.addEvent(action, function);

  • Add an event to the object, specifying the action that we want to listen to (you don’t include the “onâ€? part. So, “onsubmitâ€? becomes just “submitâ€?) and the function that will run when that action is fired. Instead of specifying the function name to run, I usually just do an inline function as you can see in the example.

$(id);

  • Is essentially an alias for document.getElementById(id);

new Event(e);

  • Creates an instance of the Event class based on the event “eâ€?.

new Element(tag);

  • Aliases document.createElement(tag); which creates a new DOM element.

element.addClass(className);

  • Add a class (CSS class) to the current element. If there are no classes currently for that element it will add the “classâ€? attribute to the element for you. Multiple classes are seperated by a space in the attribute.

element.setHTML(html);

  • Aliases innerHTML essentially; Inserts html inside the element.

element.injectBefore(elem);

  • Aliases insertBefore() in a round about sort of way (syntax is quite different). It inserts element just before elem in the page.

event.stop();

  • Cross-browser way to stop the event from continuing.

Leave a Reply