Cameron Bass Cameron Bass - 26 days ago 7
HTML Question

Simultaneously select radio button and submit form in Rails

Right now I have a radio button that select a particular

plan_id
. That is great and works just fine. But, I also want it to submit the form upon selection. Is there a clean way to do this? It seems like there should be an easy way but I can't seem to find it.

Here is my code:

<label>
<input type="radio" id="plan_id_1" name="plan_id" value="1" />
<%= f.submit "Select", class: "button-big reverse-blue" %>
</label>


Right now this requires a select of the radio button then a click of the submit button. How can I turn this into one action?

Answer

You can submit a form without explicitly clicking the submit button with a few lines of custom JavaScript code.

There are a few ways to do it.

Option 1 - :onclick option

Using the radio_button helper,

<%= f.radio_button :plan_id, 1 %>

you can add an onclick option which takes a string of JavaScript code

<%= f.radio_button :plan_id, 1, onclick: "alert('Hello world!');" %>

In the onclick code, you can use jQuery to select your form and then submit it. What selector you use is up to you.

// data attributes (my preference because it's explicit and flexible)
$('[data-target=my-form]')

// using jQuery's closest() method; "this" will refer to the radio button you clicked
$(this).closest(form)

// an ID or class
$("#my-form")
$(".my-form")

Once you have the form selected, you just need to call the submit method on it.

Putting it all together,

<%= f.radio_button :plan_id, 1, onclick: "$(this).closest('form').submit();" %>

Option 2 - UJS option

Unobtrusive JavaScript is the process of adding behavior to the DOM via handlers in your JavaScript code which respond to events and trigger actions accordingly.

This option has the following benefits

  1. It's modular and can be used on other input fields and forms
  2. It keeps the JavaScript out of the view

In this situation, we'll create a "submit on click" behavior that we can use to enhance your radio button with that behavior.

First the JavaScript event and handler

$(document).on("click", "[data-behavior=submit-on-click]", function() {
    $form = $(this).closest('form'); // select the form
    $form.submit(); // submit it
});

Now append that special data attribute to the radio button itself to enable the behavior.

<%= f.radio_button :plan_id, 1, data: { behavior: "submit-on-click" } %>

My convention is to use the data-behavior data attribute, but any selector is fine.

The nice part about this approach is that if you have multiple radio buttons, you can give them all the same behavior by just adding the same data attribute to each.

Additional Resources

Comments