Question

Why simple_form generates input tags twice for boolean fields (one hidden and the other not)?

In my simple_form, I have this:

<%= form.input :over_phone, as: :boolean, input_html: {checked: true} %>

which generates this:

<div class="control-group boolean optional order_over_phone">
  <label class="boolean optional control-label" for="order_over_phone">Order over phone</label>
  <div class="controls">
    <input name="order[over_phone]" type="hidden" value="0">
    <label class="checkbox">
      <input checked="checked" class="boolean optional" id="order_over_phone" name="order[over_phone]" type="checkbox" value="1">
    </label>
  </div>
</div>

As you can see, one input tag is hidden with a value of 0 and the other is unhidden with a value of 1. If I submit the form, in the post parameters I get both values:

order[over_phone]:0
order[over_phone]:1

I have some random behavior in model creation associated with this boolean field, so I wonder if it's caused by simple_form. This doesn't happen with non-boolean field types.

If you have come across a similar problem, please share your experience.

I'm using simple_form 2.1.0.

Was it helpful?

Solution

check_box gotcha

http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-check_box

The HTML specification says unchecked check boxes are not successful, and thus web browsers do not send them. Unfortunately this introduces a gotcha: if an Invoice model has a paid flag, and in the form that edits a paid invoice the user unchecks its check box, no paid parameter is sent. So, any mass-assignment idiom like

@invoice.update(params[:invoice])

wouldn’t update the flag.

To prevent this the helper generates an auxiliary hidden field before the very check box. The hidden field has the same name and its attributes mimic an unchecked check box.

This way, the client either sends only the hidden field (representing the check box is unchecked), or both fields. Since the HTML specification says key/value pairs have to be sent in the same order they appear in the form, and parameters extraction gets the last occurrence of any repeated key in the query string, that works for ordinary forms.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top