1

I have some checkboxes and their name maps to a column in my activerecord model. Problem is, when the checboxes are selected, they appear in the params array in Sinatra, which works fine. But when they are deselected, the params never contains :checkbox => false. It only contains :checkbox => true. So the user can go from deselected to selected, but never vice versa as the params hash for :checkbox => false is never passed.

I feel like I am missing something fundamental here. Please help. Thanks

0xSina
  • 20,973
  • 34
  • 136
  • 253
  • Go for the hidden field. http://stackoverflow.com/questions/476426/submit-an-html-form-with-empty-checkboxes?lq=1 – oldergod Dec 03 '12 at 02:24

2 Answers2

4

A control in a HTML form only gets submitted to the server if it is “successful’. For checkboxes this means that it is checked. An unchecked checkbox doesn’t get submitted. This means that in Sinatra the value of params[:the_checkbox] is either the value of the checkbox specified in the HTML (if you don’t specify a value this will be the default which is the string 'on') if it is checked, or will be nil since nothing will have been submitted.

The obvious solution is to explicitly check for nil, and then assume that the checkbox is unchecked in that case:

checkbox_value = params[:the_checkbox].nil? ? false : true

Another option is to make use of the fact that the name/value pairs of the form data are sent to the server in the order that they appear in the document, and that when Sinatra sees a repeated name when parsing the data it will override the earlier value with the later one. This means that you can do something like this in the HTML:

<input type='hidden' name='the_checkbox' value='false' />
<input type='checkbox' name='the_checkbox' value='true' />

Now if the checkbox isn’t checked it won’t get submitted, but the hidden input will, and if it is checked it will get submitted, but will appear after the hidden input with the same name. The result is that params[:the_checkbox] will be the string 'true' if it has been checked, and the string 'false' if it hasn’t. (Note that you may still have to convert the strings to booleans, depending on what you’re doing with the submitted data).

matt
  • 78,533
  • 8
  • 163
  • 197
0

You could do something like this :

post '/your-route' do
  params[:checkbox] ||= false

  # now do whatever you want with params[:checkbox]
end

What this does is assign false to params[:checkbox] unless it is already defined and set to true.

marco-fiset
  • 1,933
  • 1
  • 19
  • 31