Low Pro For jQuery?
A few days ago a discussion started about porting Low Pro over to jQuery. It’s been on my mind for a while (especially since Bill blogged about agnostic UJS) but I’d hesitated in doing this for a few reasons. Firstly, of course, jQuery is the mortal enemy of Prototype and only one library shall remain come The Quickening. Aside from this completely rational reason, I wondered whether jQuery really needed anything like Low Pro at all. After all, jQuery has always been designed with ‘unobtrusiveness’ in mind and was written with most of what Low Pro originally intended to fix in Prototype implemented from the start. There was no need for something like Event.addBehavior because essentially that’s what jQuery is:
Event.addBehavior({
'a.external:click': function() { //...code...// },
'div.product:mouseover': function() { //...code...// }
});
Can be achieved in jQuery like this:
jQuery(function($) {
$('a.external').click(function() { //...code...// });
$('div.product').mouseover(function() { //...code...// });
});
And rather than ever going near inline event handlers this unobtrusive style was the de-facto method of working for the jQuery crowd. The angel on your scripting shoulder. However, as you can probably tell from reading this blog, I’ve never really adopted jQuery as my main library and this was due to one big reason (and a bundle of small ones but I’ll leave them out)…
The one big reason was that, while jQuery was super simple and concise when working on smaller projects, it offered no help in structuring larger applications. All you get in jQuery, aside from Ajax methods and a handful of utilities, is the ability to select nodes then doing something with them. On the other hand Prototype is much rounder in scope. It generally plumps out JavaScript as a language adding lots of useful methods to built-ins, a host of functional programming tools and recently a full Class-based OO system with inheritance and the whole shebang which has formed the back bone of Low Pro’s behavior classes.
Low Pro’s behavior classes have become my favourite solution to the problem of structuring complex Ajax applications in a simple and maintainable way. Even hugely complex applications can be separated up into a number of groups of elements with attached behaviors. These behaviors maintain their own state, respond to events and can also expose there own public methods. They are linked to an element but the element doesn’t know about them which eliminates the need for expandos on elements and also most of the reasons for having element references in closures which is good for keeping memory usage at bay. For instance, a click on a TabBar instance can call the loadContent method of a ContentPanel. The result is more than a set of widgets, its a way of splitting up huge complicated interfaces into a collection of small, loosely joined parts each simple in its own right and totally responsible for its part of the interface. This approach becomes incredibly useful when you introduce server-side requests and responses into the mix but that’s a whole other article.
In jQuery land this kind of effect can be achieved via plugins. You’ll find a ton of widgets in the repository that have this kind of UI:
$('#example4').draggable({ helper: 'clone', revert: true });
The plugin architecture is one of jQuery’s many strong points but this kind of approach has a couple of disadvantages. Firstly, the plugin is created within a closure which means usually if you want to change the behavior of the plugin you literally need to pop open the source and change it. The second and related disadvantage is that because of the difficulty in changing plugins they tend to have a whole raft of options to allow you to configure how it works. The problem with this is that individual widgets can end up pretty monolithic. Wouldn’t it be be better if you could just take the basic draggable behavior and just augment it to your liking?
Well, in Low Pro behaviors are classes so we can do this by simply subclassing another behavior and overriding or adding what we need. For example, we can create GhostedDraggable as a subclass of Draggable. No need to hack any existing code at all. As well as having the power and convenience of jQuery’s DOM manipulation we can have a simple and powerful way to structure larger, more complex applications. I can have my jQuery cake and eat it.
So, I’ve started experimenting with Low Pro for jQuery. Here’s a preview:
Hover = $.klass({
initialize: function(hoverClass) {
this.hoverClass = hoverClass;
},
onmouseover: function() {
this.element.addClass(this.hoverClass);
},
onmouseout: function() {
this.element.removeClass(this.hoverClass);
}
});
$('div.products').attach(Hover);
If you want to leave feeedback or abuse jump on the Low Pro list. Do you think it has a place in the jQuery landscape? How do you currently structure complex applications in jQuery?
UPDATE: Thanks to Chris of Err The Blog Low Pro JQ is rocking on GitHub. Fork away.