Prototype to the rescue...
March 27th, 2007
So anybody who has ever spoken to one of us at New Bamboo knows how much we try to do the “right thing”© and Rails makes it just so easy to do the right thing that you’d either have to be very very lazy or ignorant to the power Rails (and Prototype) provides you.
We’ve all heard about unobtrusive Javascript and hopefully you’ve had a look at Dan’s and Lukes UJS4Rails plugin. Which allows you to still use the Rails helpers in an unobtrusive way but more importantly declare behaviors in an easy and declarative manner. It’s also a great springboard into the world of unobstrusive Javascript for those people who’s Javascript-fu isn’t yet strong enough to roll your own.
With the release of Prototype 1.5.1 rolling your own just got a bit easier. Let’s take your standard rails form (ignore the loader gif, I’m getting a bit ahead of myself).
<% form_for(:section,@section, :url => sections_path, :html =>
{:id => "new_section_form"}) do |f|%>
<%= f.text_field :name %>
<%= submit_tag 'Add Section'%>
<%= image_tag('spinner.gif', :id => 'spinner_create',
:style => 'display:none;') %>
<% end %>
It’s a pretty standard form that creates a section given a name, nothing exciting but it works and does this in a non Ajax way. Now this is the bit of Javascript that I would probably use before in order to Ajaxify this form:
$('new_section_form).onsubmit = function(){
if(!$(this.name).present()){alert('Please enter a name');
return false;}
new Ajax.Request('<%= sections_path) %>', {
asynchronous: true,
evalScripts: true,
method: 'post',
parameters: this.serialize(),
onLoading: function(request){
Element.toggle('spinner_create');
},
onFailure: function(request){
alert('Sorry, there were problems processing your request.\n
Please try again.');
},
onComplete: function(request){
Element.toggle('spinner_create');
}
});
return false;
};
Nothing exciting here really, the code would normally be called in a dom ready block in case you were wondering. Apart from looking a bit verbose you’ve probably noticed that I’m not being very DRY in that I’ve duplicated information that could and should be retrieved from the actual form. Things such as the path to post the details to and the method in which to do this (in this case ‘post’).
Yeah I know I could just use a bit more javascript-fu to get those details (which I normally would do especially if I wanted to separate this code into a another JS file), but again this is going to get even more verbose. No wonder people like to use the Rails Javascript abstractions.
Let’s tidy this up a bit. In Prototype 1.5.1 the guys have given you the request() method which does pretty much the same as the Ajax.Request method. In fact it even accepts the same optional parameters. The main difference though between request() and Ajax.Request() is that the former gets all those little details it needs for the form itself so the above now can be shortened to this:
$('new_section_form').onsubmit = function(){
if(!this.section_name.present()){
alert('Section name cannot be blank');
return false;
}
this.request({
onLoading: function(){
Element.toggle('spinner_create')
;},
onComplete: function(){
Element.toggle('spinner_create');
}
});
return false;
}
I could of probably extracted the spinner out to a separate variable and called toggle on it to make it even DRY’er, but at least you get the idea. There are lots of other little improvements and goodies to be found in the new release of Prototype and I seriously encourage you to play around and have some fun.
Tagged with Prototype, Javascript, Unobtrusive Javascript
1 Response to “Prototype to the rescue...”
Sorry, comments are closed for this article.






That’s a great feature and I’m looking forward to it in the next version of Prototype.
I’m also using Dan’s LowPro to attach behaviors to events with nice CSS selectors. It makes it much easier to separate content and behavior.