Caution! - Many of these posts are creepy-old in the Ruby on Rails world (before 1.0!)
The :author => Charles Abbott now blogs here

submit_to_remote, form_remote_tag, script.aculo.us

2006-04-30   [ 4 comments ]

Well, here I am with another quick update. Today's quick update took me quite some time to get working, and much less time to write about how you can do the same. This post covers how rails provides us with an easy way to submit form contents via AJAX and return some new dataset for viewing / manipulation.

This is really great because we cut down on the amount of data that is transferred during the POST. By cutting down on the amount of data the webserver has to send - we save bandwith, processor time, memory ... etc. Not only that but the user gets the satisfaction of not having to watch the page flicker and reload everything - instead they can just wait for the data to appear.

I decided to use submit_to_remote on my comment forms - to save reloading the whole page. So how did I do it?

Well, let me first tell you how I did not do it... not by the Rails API example -

form_remote_tag :html => { :action =>
url_for(:controller => "some", :action => "place") }

Ok, ok... I digress - that is the example for form_remote_tag (which does the same thing). But the API clearly states under submit_to_remote that they are the same syntactically.

So, what is their difference? form_remote_tag creates the initial form tag that watches for an onSubmit action to trigger the AJAX call. While submit_to_remote actually replaces your submit_tag and watches for an onclick action to trigger itself.

What makes the submit_to_remote so cool is that you can have multiple submit_to_remote buttons for one form that all submit to different actions (thus they could all manipulate the data differently!).

form_remote_tag watches over the whole form
--and replaces <%= start_form_tag ...options...>
submit_to_remote creates a special submit button (more than one is ok)
--and replaces <%= submit_tag >

So now that you know the difference how did I use the submit to remote tag? As I stated earlier - not like the example in the API, well maybe a bit like it - but I had to make some modifications to get it to work. Here is the code directly out of my _comment_form.rhtml partial:

<%= submit_to_remote( "savecomment", "Save Comment", :url => { :action => "newcomment" }, :failure => "alert('Oops, try again.');", :update => "comments", :complete => "new Effect.SlideDown('comments');") %>

Allow me to quickly break this tag up into bite size pieces.

submit_to_remote( "savecomment", "Save Comment", :url => { :action => "newcomment" }

"savecomment" is the DOM name of the button, "Save Comment" is the text on the button, and of course :url => provides the ajax call with the name of the proper controller / action to handle the request (You can insert the :controller => "whatever" in that array). Next we have:

:failure => "alert('Oops, try again.');", :update => "comments"

:failure allows us to insert some javascript to execute in the event that the AJAX call results in an error (perhaps the page could not be loaded... webserver down?).

:update => "comments" tells the AJAX call to take the returned data and fill the innerHTML of the div "comments". This, of course, requires that you have such a div with DOM id = "comments". And finally - but equally important (and really just plain cool):

:complete => "new Effect.SlideDown('comments');"

This provides a great visual effect compliments of the script.aculo.us library. 'comments' of course makes the effect occur on the div with :id => 'comments'.

Well, that is all I have for now - its getting late so I may have forgotten a thing or two I wanted to write about. In any case, happy coding :)

:author => "Charles Abbott"
Converting to Ruby on Rails
 


Daniel said:

Older post, I know, but wanted to say thanks for this - been scratching my head hard about multiple remote form submits and the syntax is def. wrong for the submit_to_remote in the API - but I couldn't find anything about this! Finally managed to track down this blog entry - are we the only people trying this??? :o)

2006-06-05 08:50:21 UTC

Charles said:

Thanks for the comment!

I know - the documentation is sparse - and it is definitely frustrating. Hopefully we can all chip in a little to make it better.

2006-06-07 20:17:01 UTC

chris said:

I'm new to all this, and so the post helped me. I wanted to make a form that has 3 buttons - two of which do an asynchronous update, and one which submits the form and redirects to a new page. So although your article gave some good hints, i still had to do some thinking. I found nothing else on the web that provided a solution, so here's the answer I came up with.
in the form I use <%= form_tag({:action=>'foo', :controller=>'bar', :id=>my.id }) %>
(... form stuff goes here ... and then for the submit buttons i use)

<%= submit_to_remote("saverecord","Save record",:url=>{ :action=>"a", :controller=>"b",:id=>my.id }) %>

<%= submit_to_remote("sendToSF", "Send to SF", :url=>{ :controller=> "people", :action=>"SF", :id=>my.id}) %>

<%= submit_tag("Schedule call") %>

<%= end_form_tag %>

in other words, use a normal form tag and submit tag for the redirect, and submit_to_remote tags for the rest.

It's obvious once you've done it of course :-)

2006-08-23 03:05:16 UTC

Charles said:

You are correct Chris. That is how I also use multiple submits with one form. I only mentioned that you could use seperate buttons to submit to different actions, but I didn't give enough detail on how to do it....

But thanks to your comment - I wont have to update it!

Cheers!

2006-08-24 11:17:32 UTC

What?

Who?              Link?



Frameworks Good or Bad?   :date => "2007-10-06"
Where is ForTheCode.com Going?   :date => "2007-09-23"
Refactoring - Vital to Software Development   :date => "2007-09-23"
Mongrel Cluster a quick note - and extra notes   :date => "2007-05-20"
Linux Mongrel and Rails   :date => "2007-05-15"
form_remote_tag revisited   :date => "2007-01-07"
How To: Ubuntu 6.10 Edgy on Rails part 3   :date => "2006-12-30"
How To: Ubuntu 6.10 Edgy on Rails part 2   :date => "2006-12-24"
How To: Ubuntu 6.10 Edgy on Rails   :date => "2006-12-22"
verify ... 5.times do cycle   :date => "2006-09-25"
country_select, country_options_for_select, mail_to   :date => "2006-09-05"
Generate and Send Email in Rails   :date => "2006-08-26"
FDF Model, gsub, and send_data   :date => "2006-08-18"
Active Directory Authentication with acts_as_authenticated   :date => "2006-08-17"
Apache2 proxy with Lighttpd - FastCGI for Rails   :date => "2006-08-08"
reverse! && a simple file Upload Class   :date => "2006-07-29"
send_file - a link to download a file   :date => "2006-07-24"
Environments (production, development, test) and cache_pages   :date => "2006-07-04"
.class .methods .instance_variables   :date => "2006-06-14"
select_tag :multiple => true   :date => "2006-06-01"
FileUtils, action_controller rescues   :date => "2006-05-20"
file_field_tag, File.size, File.path, FileUtils.mv   :date => "2006-05-15"
javascript_include_tag, stylesheet_link_tag   :date => "2006-05-02"
submit_to_remote, form_remote_tag, script.aculo.us   :date => "2006-04-30"
periodically_call_remote, simple_format   :date => "2006-04-26"
observe_field - Ajax!   :date => "2006-04-21"
h method, TextHelper, sanitize(), strip_tags()   :date => "2006-04-15"
Rails API :My API [.count(), link_to, text_area :size]   :date => "2006-04-13"
Rails - HTML Select Tag   :date => "2006-04-05"
Pruning Old Sessions   :date => "2006-03-21"
If Elsif Else, and Searching Too!   :date => "2006-03-17"
SHA1 - A quick update   :date => "2006-03-15"
Initialized! good, Authorized? Great! part 2   :date => "2006-03-11"
Initialized! good, Authorized? Great!   :date => "2006-03-08"
Forms and Routing in RoR   :date => "2006-03-06"
My First RoR Post !   :date => "2006-03-05"