zerosum dirt(nap)

evolution through a series of accidents

zerosum dirt(nap)

Prototype vs YUI Connection Manager: Dialog Continued...

November 20, 2006 by nap · Comments

In the last blog entry, I wrote about doing a first pass integration between Rails and the Yahoo UI Library’s Dialog widget. In the event handler for the save action, we created an Ajax.Request object using the Prototype library to make the Ajax call but I didn’t elaborate on why just calling this.submit() in the handler wouldn’t work. Well, the answer is pretty obvious: I wanted to tease out a second article :-).

YUI expects us to set up a callback handler for the success/failure of the XMLHttpRequest request that it generates when this.submit() is called. If you don’t have a callback set up, the client receives the response but just ends up throwing it away. So let’s look into how we need to change our handler to do things the “right” way (according to Yahoo, anyway). We’ll also see how this is somewhat at odds with Prototype and RJS.

YUI’s Connection Manager utility exists to simplify your interface to the XMLHttpRequest object and provides a handler pattern for callbacks. It’s used throughout their library, so let’s use it here. This updated code should obviate the need for using Prototype in the body of the save action handler:

var handleSubmit = function() {
  this.callback = {
    success: function(o) {
      var scriptObj = document.createElement("script");
      scriptObj.setAttribute("type", "text/javascript");
      scriptObj.text = o.responseText;
      document.body.appendChild(scriptObj);
    },
    failure: function(o) { 
      // do something here
      alert(o.responseText);
    }
  };
  this.submit();
}

In the code listing above, we define the callback object to handle the success / failure cases reported by XMLHttpRequest. On success, we’re going to create a new script element in the DOM and load it up with the response that our RJS template renders. Then we have to append the new element to the DOM. Remember, what we’re appending here is really just some more JavaScript that we’ll use to alter the page contents. Here’s the code in that RJS template again (add.rjs), as a reminder:

page.replace_html 'hello_msg', @thing[:name]

Alright, that’s great. But what does the JavaScript code look like that actually gets generated?

try {
  Element.update("hello_msg", "Welcome Interstate Managers");
} catch (e) { 
  alert('RJS error:\n\n' + e.toString()); alert('Element.update(\"hello_msg\", \"sdafdsfsdff\");'); throw e 
}

That Element.update instruction is Prototype’s way of saying “take the DIV identified as hello_msg and replace it’s guts with the string Welcome Interstate Managers”. Of course, that’s just the string we gave it when we serialized our form data and sent it off (see previous article for details). Simple but powerful.

OK so that rocks, but there’s a bit of redundancy here. Yahoo’s Connection Manager utility and Prototype do a lot of the same stuff. That duplication is totally against the DRY spirit we’re going for. Sigh. Now I’m not well versed enough in the finer details to advocate The One True Way here, but I should note that I’m much more experienced with Prototype than I am with the YUI connection manager. Prototype is also much more entrenched in Rails, serving as the basis for both Scriptaculous and RJS, and it looks to remain that way as Sam Stephenson (Prototype’s creator) is part of the Rails core team.

Anyway, the point I’m trying to make is that the Yahoo UI connection manager library adds further unnecessary bloat to our applications, since it’s essentially just replicating what Prototype already does. I’m sure the YUI guys have their reasons for re-implementing this stuff (Prototype isn’t universally well-loved), but it’s kind of unfortunate for Rails developers, who are pretty well married to Prototype at this point. That isn’t to say that the Yahoo stuff is better or worse.

In the meantime, if we want to use YUI’s widgets, we just have to suck it up and eat a little extra pie this holiday season. Maybe it’s worth writing an alternative connection.js to act as a Prototype wrapper. Maybe we could whip up some helper modules to get these excellent UI widgets as well integrated into the Rails framework as the Scriptaculous stuff is. I’m sure this is all very possible, but just need to spend some time digging through the stuff in more detail. In any case, it seems clear that proper RoR integration needs a bit more thought. Add it to the TODO list!

PS the folks at OpenRico have done a nice job providing a set of controls that are very RoR-friendly. Their focus is somewhat different than that of the Yahoo library, more emphasis on behaviors and cinematic effects rather than on widgets, per se. They have a great accordion widget though, and a live grid too (although it currently lacks cell editing support, which is one of the key things we’re looking for).

blog comments powered by Disqus