Automatically Submitting a Rails Form

I was recently surprised to find very little recent information on the web for allowing a Rails form to submit automatically upon change of a value. In my use, I was attempting to automatically submit a form when a user changed the quantity of an item in the cart via a drop-down, thus saving them the redundant visual of an ‘Update Quantity’ at each item line or the need to hit an ‘Update Cart’ button.

After implementing what I was confident to be the correct syntax for the onchange:

onchange: ‘this.form.submit();’

Nothing happened on my page. The solution turned out to be simple. Rails takes two sets of options passed in via hashes for select. The first determines options for the drop-down menu itself (e.g. specifying if a blank option should be included), while the second determines the HTML options. These come in a strict order, and if options for the drop-down are not specified but HTML options are, it will assume that your HTML options are actually options for the drop-down. My original, non-functional code was as follows:

<%= form_for(item, url: cart_item_path(item)) do |f| %>
<div class=’form-group’>
<%= f.select :quantity, quantities, value: item.quantity, class: ‘form-control’, onchange: ‘this.form.submit();’ %>
</div>
<% end %>

Note: The div and class options are not necessary for functionality. They are there solely for bootstrap styling.

Because of my syntax, everything after quantities looked like the options hash. As a result, my value was filling in correctly, but class and onchange are not valid options for the drop-down and were duly ignored. This was solved by modifying to the following context:

...
<%= f.select :quantity, quantities, {}, { value: item.quantity, class: 'form-control', onchange: 'this.form.submit();' } %>
...

My complete form then looked like:

<%= form_for(item, url: cart_item_path(item)) do |f| %>
<div class='form-group'>
<%= f.select :quantity, quantities, {}, { value: item.quantity, class: 'form-control', onchange: 'this.form.submit();' } %>
</div>
<% end %>

That’s it. As simple as an extra {}.