Multiple AJAX submit buttons in a Rails form
Posted by Tim Riley Mon, 16 Jan 2006 10:29:00 GMT
In a Ruby on Rails app, if you have multiple submit buttons in a web form, the value of the button pressed is not serialised with the rest of the form and so it won’t be available to the controller in the @params hash. This is a ticket for this in the Rails bug tracking system, where a workaround for the problem is documented:
<%= hidden_field 'update_button', 'Edit' %>
<%= submit_tag 'Edit', :name => '_update_button' %>
<%= submit_tag 'Cancel', :name => '_update_button',
:onclick => "Form.getInputs(this.form, null, 'update_button')[0].value = 'Cancel'" %>
A hidden form element (which actually gets serialised) is used to pass the value of the submit buttons to the controller, and the JavaScript code in the onclick event for the second of the buttons above updates the value of the hidden field depending on which button is pressed.
I thought this was a pretty nifty workaround, but in my case, I was submitting a form using AJAX, and my buttons were created using submit_to_remote instead of submit_tag. The problem here was that submit_to_remote does not let you specify an :onclick option, since the method uses the onclick event internally in order to submit the form using JavaScript (see the code for the method in the documentation).
So, in order to have an AJAX-submitted form with multiple submit buttons that actually passes the value of the button clicked to the controller, it was necessary to quickly re-implement submit_to_remote in the view:
<% hidden_field_tag 'per_page', '20' %>
<% [ '20', '40', '60' ].each do |num| %>
<% remote_options = {
:update => "dock",
:loading => "showLoading();",
:complete => "hideLoading();",
:with => "Form.serialize(this.form)",
:url => { :action => "query" } } %>
<%= tag("input", {
:type => "button",
:onclick => "Form.getInputs(this.form, null, 'per_page')[0].value = '#{num}'; #{remote_function(remote_options)}; return false;",
:name => "show_num",
:value => "Show #{num}" },
false) %>
<% end %>
This way, you can specify the script to update your hidden variable before including the script that was part of submit_to_remote that is used to submit the form.
Using the example above, you now you can refer to @params[:per_page] in order to get the value of the button that was clicked to submit the form.
The whole reason I had to head down this path was in order to work around a silly rendering bug in Internet Explorer that was causing problems for the NetFox administration interface. In the end, we decided that this particular workaround was suboptimal and chose a different solution altogether. Is it any coincidence that my left eye has started to twitch uncontrollably since I started having to fix bugs caused by IE?
Gah! You can get full and unadulterated Tourettes from trying to find work-arounds for IE's little "quirks".