This tutorial will demonstrate how to convert standalone Ruby on Rails forms to a YUI dialog (hey, it’s one less page load) in only 4 easy steps.
We’ll start with a quick and dirty (and all scaffold) blogging app. I assume you know a thing or two and don’t need me to walk through this. You’ll note that there are no changes required to your controllers to make this work.
Step 1: Include YUI and all of its goodness.
There are a number of tutorials out there for this — Stuart Grimshaw has one method in this article , but an easy way is to use the YUI configuration tool and just serve the files from their CDN — it’s probably faster than your servers, anyway. I prefer to include the files I need, so that javascript_include_tag can at least concatenate them down to one file — which your users will then cache. For this example, I’m going to just do a conventional form submit, rather than an Ajaxy form handler — it doesn’t work with the Prototype.js Ajax class, and Yahoo Connection Manager is a subject for another post.
The basic HTML to include for the YUI container module (which includes Dialog and some other goodness) is:
<!-- css --> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.5.2/build/container/assets/skins/sam/container.css"> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.5.2/build/button/assets/skins/sam/button.css"> <!-- js --> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/yahoo-dom-event/yahoo-dom-event.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/animation/animation-min.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/dragdrop/dragdrop-min.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/element/element-beta-min.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/button/button-min.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.2/build/container/container-min.js"></script>
You will also want to add a class=”yui-skin-sam” to the body tag in your layout, so you pick up the styling correctly. If you want your own, go for it.
Step 2: Extract your form to a partial.
Of course, you already do this, so #new and #edit use the same partial, right? If not, go ahead and do that.
Step 3: Include the _form partial in the view
You may need to make a couple of changes to get this two work. The YUI container class uses a standard markup pattern like this:
<div id="my_form_div"> <div class="hd">Header</div> <div class="bd">Body</div> <div class="ft">Footer (optional)</div> </div>
We don’t need a footer for Dialog to work — in fact, it will add its own later, so we can leave that out. Insert the partial in the body, and your “Show” view should have something like this:
<p> <b>Title:</b> <%=h @post.title %> </p> <p> <b>Body:</b> <%=h @post.body %> </p> <p> <b>Published:</b> <%=h @post.published %> </p> <%= link_to 'Edit', edit_post_path(@post) %> | <%= link_to 'Back', posts_path %> <div id="edit_post_div"> <div class="hd">Edit Post <%=h @post.title %></div> <div class="bd"><%= render :partial => 'form', :object => @post %></div> </div>
And the page should currently render something like this:

Step 4: Wire up the dialog box.
You have a couple of options on where to include the javascript to activate this. The Rails default would be to just stick in a javascript_tag in the view after the form, so it’s available when you need it. The YUI standard would be to create an event listener to wait for the form element to be available and then do what needs to be done. My personal preference is to maintain a library of all of the javascript objects I’m using in an app in application.js, and then include a separate file per controller that sets up the listeners to activate the elements I want. To keep things simple, though, I’ll go with the first option — a javascript_tag block after the form. Code first, explanation later:
(function() {
function handleSubmit (arg) {
this.submit();
}
function handleCancel (arg) {
this.cancel();
}
var postEditor = new YAHOO.widget.Dialog('edit_post_div',
{ width : "40em",
fixedcenter : true,
visible : false,
constraintoviewport : true,
modal : true,
postmethod : "form",
buttons : [ { text:"Submit", handler:handleSubmit, isDefault:true},
{ text:"Cancel", handler:handleCancel } ]
});
postEditor.render();
YAHOO.util.Event.on('edit_post_link', 'click', function(e) {
YAHOO.util.Event.preventDefault(e);
YAHOO.util.Event.stopPropagation(e);
postEditor.show();
});
})();
So what did we just do there? The Dialog constructor takes two arguments, the id (or HTMLElement reference) of the wrapper div, and a configuration hash. The config hash sets up a 40em-wide dialog box that’s centered in the viewport, initially hidden, can’t be dragged off the screen, and that doesn’t allow you to interact with the rest of the page. To save the (nominal) trouble of dealing with Connection Manager, we’re going to submit the form using a conventional POST (or set postmethod to ‘async’ to do an ajax post). We’ve also set up “Submit” and “Cancel” buttons. The call to render() actually converts the form into the hidden dialog box.
Finally, we set up an onClick listener for the Edit link, which displays the dialog — and gives us something like this:

Further Reading
- There are a few tutorials up on the Rails wiki
- The YUI4Rails project seems to be coming along nicely, and promises a more Rails-ish integration than just writing javascript.
- There’s also Chetan Patil’s YUIRails project, which implements parts of the Prototype API using YUI — so you can use YUI as a replacement for prototype, but still take advantage of RJS to some extent.
- If you like paper, Learning the Yahoo! User Interface LIbrary
will get you up and running with YUI in no time.
- Followup post, this time using connection manager: Dynamic dialogs with Rails and YUI
RSS feed
June 20, 2008 at 7:03 pm
[...] Shiny Forms with Rails and YUI: That’s the title of Enleitened’s new tutorial that "demonstrate[s] how to convert standalone Ruby on Rails forms to a YUI Dialog (hey, [...]
June 25, 2008 at 2:16 pm
I’m contemplating the followup for this article. Any suggestions?
June 26, 2008 at 2:13 am
[...] Dialogs with Rails and YUI This tutorial is a followup to Instant Shiny Forms with Rails and YUI, with a bit more of an interesting technique that (I think, at least) really demonstrates where YUI [...]