Search

Chaps

Sweet sweet memories

Blather

Uptime verified by Wormly.com

29 August 2008

Waiting cursor during Prototype’s Ajax.Request

In your stylesheet:

body.waiting {
  cursor: wait;
}

In your script:

document.body.addClassName('waiting');
new Ajax.Request(uri, {
  onComplete: function() {
    document.body.removeClassName('waiting');
  }
});

You probably want to be careful to make sure it's in the onComplete method and not the onSuccess method. Even better might be to create a setTimeout("document.body.removeClassName('waiting')", 3000), so you don't break the cursor for the rest of the page visit.

You also might prefer the "progress" instead of the "waiting" cursor. For other cursors and their compatibility check out QuirksMode.

9 July 2008

Unobtrusive Javascript

I've been reading a little about UJS lately, trying to figure out a nice way of building some AJAX back into the Rails project I'm working on. I had a look at the UJS plugin and tried out the Low Pro. But I'm not sure I'm convinced. PPK suggests that Javascript is to behaviour as CSS is to styling, but I disagree. CSS tends to apply to many elements in a site. Javascript is more likely to be specific to a page. Most of the benefit of CSS comes from classes and being apply to apply the same style to many things at once. It makes sense to keep something like that separate.

The is the "wrong" way to do it:

<a href="/event/new" onlick="AJAX.Request(...);return false;">Create event</a>

And this is the "right" way:

<a href="/event/new" id="create_event_link">Create event</a>
<script type="text/javascript">
//<![CDATA[
Event.addBehaviour({ '#create_event_link': Remote.Link }); // attach event listener to link
//]]>
</script>

Which is pretty verbose, and to truly do it properly you're meant to put that second block in a separate file. In a Rails application, that's going to be somewhere in public/javascripts/ which feels very much like the wrong place to put this sort of logic. The second solution will also break if the link is created dynamically after the page has loaded.

An event delegation solution might solve this particular problem. You could catch all links with the class "remote" for instance, and treat them as AJAX links. But it wouldn't be very configurable. Configurability isn't a big issue for CSS, but I think is an issue for Javascript.

I certainly understand the appeal of UJS, but I don't think the parallel between styling and behaviours is convincing. And for trivial behaviours like this I don't think duplication of code is a serious problem, either for download size or for maintenability.

0.805 seconds