Checkbox in Rails has three values which is causing issues - ruby-on-rails

I'm new to Rails.
I have a situation where we have a fairly important form that we can't default answers for users as it revolves around government tax authorisation related things so our boolean answers essentially have three states:
nil -> user hasn't provided an answer
true -> User has said true
false -> User has said false
The issue I'm having in our Rails backend with this is by default the form.check_box :some_proper is defaulting the input to false when if the value is nil it needs to remain nil.
So what's happening is a whole series of nil values are changing to false when our form is submitted.
I have provided some code examples, but I can't find anyway of doing what's needed and we may just need to swap from checkboxes to select fields or something.
%dt= form.label :knowledge_intensive
%dd= form.check_box(:knowledge_intensive, {}, "1", "0")
I have attached a GIF to illustrate the issue clearer:
Demo of issue in GIF Form

The form builder adds a hidden field with the same name as your knowledge_intensive field. If you inspect the generated HTML it will appear immediately before the input for the checkbox.
The reason for this is to allow an unchecked box to pass through as false. I'm not sure how you can get around this, as this mechanism is required to pass the state as a param (HTML spec implies unchecked checkboxes aren't passed as form params). There's no easy way to have separate nil/true/false values - you are probably better off using radio buttons for that.
But that's the reason. The auxiliary hidden field is has a value of '0' and that will be interpreted as 'false' by Rails, unless the user checks the check box.
Does that make sense?

Related

Conditional show/hide fields based on show/hide links

What I try to do is very simple.
I have some fields in a form that are optional to fill. To make the form look cleaner, I'd like to show simple links as Add field and display the optional fields below via js unobstructedly.
If the field is present, it will be saved into the database. The field would also have a delete link. When this delete link is clicked, the field will be removed and also its value from the database when saved.
Seems pretty simple, yet I haven't found a simple approach to this. The whole solution involves many aspects such as passing hidden data to the controller to see if the record was hidden in order to delete its data from the database.
I would prefer a gem already optimized for this purpose but I couldn't found any. What I found is intended for associated records but this is not the case. These are not associations, just optional attributes from the same model.
nested_form_fields gem its also not suitable since it needs a checkbox or radio button to be triggered and not Add field/Remove field links which I believe look cleaner.
Is there such thing as a gem to accomplish this simple thing?
Instead of trying to send hidden data etc. Why don't you just load all the form fields but display:none. When a user clicks the 'show' button you display the field. If the click the hide button, just set the field to null and hide it.
When your form reaches the controller it will save the null value to the db for the hidden fields (same as if you deleted the value).

check_box_tag doesn't pass any parameter if not checked

I'm trying to have an if else statement in the controller to do something if the check_box_tag is checked and something else if it isn't checked.
<%= check_box_tag "apply[]", 1, false %>
If it is checked and the form is submitted "apply"=>["1"] is passed as a parameter, if it isn't checked nothing is sent.
Can I have a "apply"=>["0"] passed as a param if it isn't checked?
The check_box_tag indeed does not use the hidden field so it does not send anything in case the box is unchecked (unlike the check_box helper, which is nevertheless still not useful in case of an array param, as Meier notes above).
If you are trying to use your checkbox in a similar way as in this SO question (i.e. to send a user-selected array of ids for example), the simple solution might be to react on an empty param in the controller. Something in the way of:
params[:apply] ||= []
If, on the other hand, you wanted to use the checkboxes as an ordered array where each value would be determined by its constant position in the array, either true or false, (i.e. if you wanted to get something like this in the apply param: [0, 1, 0, 0, 1]), this wouldn't work. You'd have to choose a different approach, e.g. use the checkboxes with a hash param instead of array.
The rails guide has a warning box about this special case:
http://guides.rubyonrails.org/form_helpers.html
Array parameters do not play well with the check_box helper. According
to the HTML specification unchecked checkboxes submit no value.
However it is often convenient for a checkbox to always submit a
value. The check_box helper fakes this by creating an auxiliary hidden
input with the same name. If the checkbox is unchecked only the hidden
input is submitted and if it is checked then both are submitted but
the value submitted by the checkbox takes precedence. When working
with array parameters this duplicate submission will confuse Rails
since duplicate input names are how it decides when to start a new
array element. It is preferable to either use check_box_tag or to use
hashes instead of arrays.

How to get the values true or false depending on a list of checkbox checked or not in Grails

I have check boxes in a list
HTML Code
<g:checkBox id="isBookable_${index}" class=" isBookable" style = "width :auto" name='isBookable' value='${careProviderScheduleExceptionInstance?.isBookable}' />
Problem
When I get the list of this checkbox i.e isBookable in params, the values for only the checkboxes that are checked comes in the list and the value comes as on and not true.
I want the values should come as true or false based on if the checkbox is checked or not.
Thanks in advance.
Grails g:checkbox does some shenanigans for the binding magic to work correctly when you do something like:
def schedule = new Schedule(params)
So that schedule.bookable would get populated correctly. I've never been a big fan of how it works but it is what it is and at the end of the day, it does work for typical use cases.
You have to remember that per the HTML spec, you're not going to get unchecked checkboxes passed in on a form submit. So looking for false is a moot point. What you would have to do is take the ones that do get checked (and submitted) and compare that against a list of possible bookable 'schedules'.
A work around would be to use Javascript to submit your form and pass in all the checkbox's with whatever value you want mapped to the correct instance.

selecting checkbox value in ruby on rails

I have some 5 static checkboxes in my html page.
And i want to get the values of a selected checkbox when i click on submit button.
Below is my code snippet,please correct me where am wrong.
for i in 101..105
if (params[":Prod"+i] == 'selected')
#userid=session[:userid].to_i
#prodid="Prod"+i.to_i
#prodname=params[":ProdName"+i].to_s
#price=params[":Price"+i].to_i
#qty=params[":qty"+i].to_i
#Products=Product.create :UserId =>#userid, :ProductId =>#prodid, :ProductName =>#prodname, :Price =>#price,:Quantity =>#qty
if #Products.save
redirect_to viewcart_path
else
render products_path
end
end
Note:My checkboxes id's are Prod101,Prod102,Prod103,Prod104 and Prod105 which i have defined static in my html page.
You can create dynamic hash keys similar to what you're trying, but the syntax is a little off. Use:
params[:"Prod#{i}"]
or
params["Prod#{i}".to_sym]
Note that the value is not "selected" unless you've set that yourself in the view. Depending on whether or not you're using helpers to create the checkboxes, and which helpers/gems you might be using, the values can vary. It's likely you'll get "1" for checked boxes if you haven't overridden it. You might get "0" for unchecked boxes, but by default browsers don't send anything for unchecked boxes, so the param might not be there at all. Some of the form helpers trick the browser into sending "0" by using hidden form fields. Also note that "0" is a true value in Ruby, so you should explicitly check for "1" or whatever checked value you've provided in the form. Check your logs and see what the form submits to be sure.

in rails, What is the value returned in for a checkbox?

I want to set a cookie to expire in 1 year if the 'remember me' checkbox is checked.
I have a checkbox form input like:
<%= check_box_tag 'remember', '', false, :class => 'checkbox' %>
What will the value be when it gets posted?
Will it be true/false or checked or 1 or? I set the value to '' in the helper.
Checkbox will return either 0 or 1.
Don't compare with false and true, as this may cause you problems, since 0 is true in Ruby.
In the rails API documentation it has this helpful explanation of missing parameters and the hidden field work-around:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-check_box
check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
Returns a checkbox tag tailored for accessing a specified attribute (identified by method) on an object assigned to the template (identified by object). This object must be an instance object (#object) and not a local object. It’s intended that method returns an integer and if that integer is above zero, then the checkbox is checked. Additional options on the input tag can be passed as a hash with options. The checked_value defaults to 1 while the default unchecked_value is set to 0 which is convenient for boolean values.
Gotcha
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_attributes(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.
You get in your action the params
params['remember']
If if check you have the params with false like value. If it's not check you have no params send to your action.

Resources