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.