I dynamically generate a set of checkboxes in my view:
<% Event::NOTIFICATIONS.each do |notification| %>
<%= check_box_tag "event[notifications][]",
notification,
#event.notifications.try(:include?, notification) %>
<%= t("events.notifications.#{notification}") %>
<% end %>
The values are stored as an array.
However, when I edit an event and uncheck one of the notification boxes (so no notification boxes are left checked), it will not clear the array. The parameter hash does not contain the notification key either.
Any ideas on how to solve this?
check_box_tag doesn't work like check_box. check_box creates a hidden field which returns 0 as the default value for an unchecked checkbox. check_box_tag, on the other hand, doesn't return anything with the form if it is uncheked. An easy way to solve this is to add a hidden field with the same name as the checkbox but with a value of nil. This returns an array with a nil value as the first element which Rails should ignore.
hidden_field_tag 'event[notifications][]', nil
Related
<%= form_for list do |f| %> <!-- This might be an issue in production mode -->
<%= f.fields_for l = list.list_items.build, index: l.id do |list_item| %>
<td><%= list_item.check_box :user_item_id, { checked: false, include_hidden: false }, item.id, "nil" %></td> <!-- checkboxes seem problematic, try check_box_tag? -->
<td><%= item.name %></td>
<td>$<%= number_with_precision(item.price, :precision => 2) %></td>
<td><%= list_item.number_field :quantity,
min: 1,
class: "num"%></td>
<% end %>
<% end %>
If I have three of these on my page and all three are checked, Rails will send an extra unchecked value for each form. Why is this?
Parameters: {"utf8"=>"✓", "authenticity_token"=>"sn2HLFvVLX7ZFxBTHvRGz25H+bbyiVl8E8Kok5J7788q8WA33U8RpWmLXjU2GTjD2ybW7RMaiX1CwLJ6oCLXmQ==", "list"=>{"list_item"=>[{"user_item_id"=>"nil"}, {"user_item_id"=>"19", "quantity"=>"1"}, {"user_item_id"=>"nil"}, {"user_item_id"=>"20", "quantity"=>"2"}, {"user_item_id"=>"nil"}, {"user_item_id"=>"21", "quantity"=>"3"}], "name"=>""}, "commit"=>"Create List"}
However if I turn hidden fields off, I get other issues with my forms "stealing" each-other's data when a preceding box is left unchecked. For example here I left the first form unchecked:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"qszyk+q+pJ77WuDh2/K2S8lTuBD99DptwqeEdDI4U+4yQBWIbCSYRUvGrofzH8hHfDKXSxxn6myTpZ6dAGFruA==", "list"=>{"list_item"=>[{"quantity"=>"1", "user_item_id"=>"20"}, {"quantity"=>"2", "user_item_id"=>"21"}, {"quantity"=>"3"}], "name"=>""}, "commit"=>"Create List"}
Notice how the first unchecked form neglected to set the user_item_id to "nil", and instead left the param out completely and stole the next form's user_item_id, thus messing up my quantity values (which I set to the same as before).
Why is this?
PS: I originally had "nil" just nil, but doing so prevents the unchecked value from being passed in any case and I was having issues with the forms stealing values from each other like I posted above. If anyone could tell me how to make it so that an unchecked box means that my fields_for will not be submitted at all that would be great.
That is done by rails so that the right value is sent when the checkbox is unchecked.
When you don't check the checkbox the value of the hidden field(added by the checkbox helper) reaches your server, as unchecked checkboxes are not sent by the browsers.
In the other hand, when you check it, the last value with the same name wins, meaning the checked value will be sent to the server and everything will work as you expect.
from the documentation:
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(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.
I am new to RoR. I want to know how do we make a radio button default selected just first time while creating new record?
I tried
<%= radio_button_tag 'scheduler', 'now', true%> Now <br>
<%= radio_button_tag 'scheduler', 'future'%> Future<br>
It makes the first radio button (having value Now) checked but when i select second radio button (Future) and leave other mandatory fields blank on the form then again the first radio become selected instead of second.
How to resolve this.
Note: the field "scheduler" is just a virtual field on this form that will display another HTML containing a datetimepicker if "Future" option is selected and that datetimepicker field "schedule_date" is the actual field of the model. If option "Now" is posted then simply it will save the current date and time into the database table for that field "schedule_date". So i just have to show/hide an HTML by using these radio buttons.
When you say 'leave the mandatory fields blank' i guess you are submitting the form and getting the edit form back from the server with a warning flash? What I think you need to do here is instead of setting the Now field to true, you need to use a variable and set it to true on when creating a new form. Then when you submit the form to the server the controller's create method should look at the params hash, set the variable, and if the submission fails validation is should return the edit form with the Now variable set to false and the Future variable set to true
so in the create method of the controller you have something like
#now = params[:scheduler][:now]
in the new method of the controller you have:
#now = true
and in the view:
<%= radio_button_tag 'scheduler', 'now', #now%> Now <br>
<%= radio_button_tag 'scheduler', 'future', !#now %> Future<br>
This is true because you have set the first radio button to be selected by default. So when you select the second radio button and then refresh/submit the form, the page comes to its original position losing the previous selected second button.
This is just like when you enter the form fields and then refresh the form or come back again to the form after going back, you loss the data that you filled previously.
Solution:
I say get the checked radio button value and set it using jquery as-
$('input[name="myradios"]').change(function() {
alert($(this).val());
});
Try:
<%= radio_button_tag 'scheduler', 'now', true %> Now <br>
<%= radio_button_tag 'scheduler', 'future', params[:scheduler].eql?("future") %> Future<br>
Ok, I've been digging around and haven't found an answer to this. I have a pretty complex custom rails form generator application that renders pages, sections, & surveys (forms) from a database.
It does validation server side (haven't finished the javascript yet and want both types), and I have it working for all types of form input objects, except for radio buttons. Because I can't get it to submit radio buttons to show up in params when they are not checked. As opposed to just looking for radio buttons outside of the params, I'd like to find a way to check them in my response loop (if possible).
I've seen this suggestion of binding it to the model to make sure it validates, but my questions are unique and therefore I don't have a model object I'm binding it to.
My form is declared in one partial:
<%= form_tag take_surveys_path, :id => "take_surveys_new", :method => :post do %>
and my code for generating the radio button (part of a partial that looks at a question type field):
<% when 'Radio Button' %>
<% question.answers.each do |answer| %>
<%= radio_button "response[#{question.id}]content", question.question_text, answer.value %>
<%=answer.value%>
<br />
<% end %>
<% end %>
I iterate over params in my "take_survey_controller" and then check each question to see if it's valid, which includes regex and required validation based on some attributes set in my question object:
params[:response].each do |question_id, answer|
#find my questions and answers, call
if item.valid?
#do a bunch of saving and stuff...
end
end
but this never gets called for radio buttons because empty radio buttons don't post to the params.
Any suggestions or help? Happy to share more code if needed.
What you're looking for is a way to set a default value for your radio buttons. Checkboxes do this by default, but in this instance it doesn't look like it's happening for your radio buttons.
Try this:
<%= hidden_field "response[#{question.id}]content", question.question_text %>
<%= radio_button "response[#{question.id}]content", question.question_text, answer.value %>
It sounds like part of your validation should include checking input params. If a radio button isn't selected it won't submit a value, thus you need to have a list of question ids and ensure each question was submitted before moving into your params response loop.
array_of_question_ids.each do |id|
handle_missing_question(id) unless params[:response][id]
end
params[:response].each ...
I have a problem, i made a scaffold, generating the table "requirements", i want the user to fill the fields of the table in the edit and the new requirement with select boxes and radio buttons. The select box and the radio buttons appear in the explorer but when i select one option or one button, that value selected it's not reflected in the db. The code im using its the next: (As you can see i used the original cicle f.label(:notif_card) and f.text_field(:notif_card) generated by the scaffold, but i deleted the last one and used the select box in this case.)
<%= f.label :notif_card %><br />
<% value = { "Good" => 0, "In Progress" => 1, "Denied" => 2 }%>
<%= select( #requirement, :notif_card , value) %>
<% if value == 1 %>
<% #requirement.notif_card = 1 %>
<%end%>
I just want to delete that text_field and replace it with a select box! Everything you can do i will appreciate it alot! If something needs to be in the model or in the controller besides the code that i'm using please let me know. Thanks for your help!
if you want to use the radio buttons for storing values from form to DB you can use the radio buttons..
the syntax will be like
<b>notif_card</b><br/>
<%= f.radio_button:notif_card,'0'%>Good<br\>
<%= f.radio_button:notif_card,'1'%>In progress<br\>
<%= f.radio_button:notif_card,'2'%>Denied<br\>
<%= f.submit %>
this will store values on the database by using radio buttons.
if you want to use check box method for the same, you can use but it is of Boolean method.so needs to be declared as boolean when start generating scaffolding it.
I've got a form_for form, and within it, I'm using a form helper check box. The model has a field that's a boolean value, but I'd like to be able to display it on my form in terms of its converse since I think that's easier for users to understand.
Is there any way for me to have a Rails form helper act as if the model's boolean field is flipped?
Example:
<% form_for :user do |form| %>
<%= form.check_box :privacy_disabled %>
<% end %>
In this example, the User model has a boolean field privacy_disabled. I would like to display this in the form as check here to enable privacy.
The checkbox helper function has the ability to set its checked and unchecked values, but inverting these does not seem to properly populate the checkbox with the pre-saved value.
This is how I ended up solving this issue, I was actually close with my first attempt:
<%= form.check_box :privacy_disabled,
{:checked => !#user.privacy_disabled},
0,
1 %>
So the values returned by the checkbox are flipped, and whether it starts out checked is manually flipped as well.
Not the most elegant solution, but you could do something like the following:
Add these methods to your user model:
def privacy_enabled=(val)
self.privacy_disabled = val == "0"
end
def privacy_enabled
!privacy_disabled
end
Change the form to:
<%= form.check_box :privacy_enabled %>
Again, not elegant, but it works.