One of my favorite little AJAX tricks is posting only a few fields of the DOM with link_to_remote.
The real world application of this is when you have a composite object that needs to be created in the process of creating your main composing object. It can also be helpful when you have a dynamic interface with hidden divs within one main form and you don’t not want to pass the whole form via xhr (it could be a multipart request with a file selector).
Here is how to submit only one DOM element’s children form inputs:
1.Define the DOM element you want to submit1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<div id="remote_message" style="display:none"></div> <div id="create_input"> <label>Movie name</label> <input type="text" name="create_movie_name" id="create_movie_name" value="" /> </div> <%= link_to_remote "Create movie", {:url=>'/movie/create', :submit=>"create_input", :success=>'handleCreateSuccess(request);', :failure=>'handleCreateFailure(request);' }, {:id=>'create_movie_link_id'} %> |
The important thing to note is the :submit=>‘create_input’ which defines the DOM element whose children will be serialized and passed to the controller on submit. Also notice we haven’t defined an HTML form. Prototype is smart enough to serialize any DOM structure, not only forms. This could just as well be inside a form, but only the DOM element we specify will be sent to the server.
2. A standard controller to handle the post1 2 3 4 5 6 7 8 9 10 |
class MovieController < ApplicationController def create return unless request.xhr? && request.post? # do stuff render :inline => "'#{params[:create_movie_name]}' was created" end end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<script type="text/javascript"> //<![CDATA[ function handleCreateSuccess(request) { showMessage("Success! " + request.responseText); } function handleCreateFailure(request) { showMessage("Problems creating that movie: <br/>" + request.responseText); } function showMessage(message) { $('remote_message').show(); $('remote_message').innerHTML = message; new Effect.Highlight('remote_message'); new Effect.Fade('remote_message', {duration: 10}) } //]]> </script> |
prototype's Ajax.Request()
1 2 3 4 5 6 |
new Ajax.Request('/movie/create', {asynchronous:true, evalScripts:true, onFailure:function(request){handleCreateFailure(request);}, onSuccess:function(request){handleCreateSuccess(request);}, parameters:Form.serialize('create_input')}); |
Using this technique you are no longer forced to do full form submissions when you only want a small bit of data which will lead to a more dynamic and ‘snappy’ user experience.


Thanks a lot for this article! I’ve been looking for this kind of solution for about three days!
Anyway it’s still not working and maybe someone reading (or having written ;-)) this article can help me.
I’ve a text_field_tag with the div-dom-id ‘bar’ sitting in a context with the div-dom-id ‘foo’.
I now have the link_to_remote-method set up with
:submit => 'foo'.In the controller I’m trying to fetch the text_field_tag-value using
params[:bar].Now even if I’ve a value in the text_field_tag my controller always receives
nil. Do you know what I’m doing wrong here?Javier,
I think div-dom-id ‘bar’ should have a text field name of ‘bar’. The params come through as the named elements on not the DOM ids.
Casey
thanks, very nice…