having trouble understanding :multiple => true in a checkbox - ruby-on-rails

I am very new to Ruby on Rails, I have inherited control of a Ruby/Rails web based database(created by another) for generating and tracking engineering functions. I use Aptana IDE.
My issue is that I am trying to use a form helper to select multiple values for our "product lines". I use 10 check boxes, and I get the correct output of one value if I don't use ":multiple => true".
See output image:
works as intended
<%= f.check_box :product_line, {:class => "field"}, "A9", false %> A9
(10 times with different values where "A9" is, so there are ten checkbox's total, image shows "A7" check box returned)
By simply adding the :multiple => true, the output changes as seen in the image below:
see output image:
returns too much
<%= f.check_box :product_line, {:class => "field", :multiple => true}, "A9", false %> A9
Why are all of those "-" added before the output only if the multiple selection is made? I want it to return only comma separated values of the checkbox, i.e. " A9, A7"
PRODUCT_LINES = [ "A9", "A7", "AG", "AF", "S3", "Legacy", "K/Kpro", "EMW", "HD", "Non-Metallic" ]
other ideas:
Can I loop through an array of :product_line to get what im looking for instead?
I was also playing with the multiple selection in a drop down menu but could never select a second option before the drop down returned and only selected my first selection.

Why are all of those "-" added before the output only if multiple
selection is made?
From the docs (read the Gotcha) when multiple is set to true all selections will be stored in an array of product_lines but un-selected check_boxes will also be reserve as an empty strings in the sent pararms so for the result you are seeing product_lines would be something like:
product_lines = ["", "", "", "A9", "A7"]
Can I loop through an array of :product_line to get what im looking
for instead?
Well, actually this takes us right to the problem in using multiple: true in your code.
The process explained in (1) above is how the check_box_tag was designed, the problem you are seeing is in presentation probably in your ECN#show. Without reviewing code there i am only guessing but usually it's something like:
<%= #ecn.product_lines.join('-') %>
which should be
<%= #ecn.product_lines.reject(&:blank?).join(',') %>
where: reject(&:blank?) to get rid of empty strings then joining with commas as you need
Hope this helps!

Related

Rails 7 collection_check_boxes not displaying checked items in edit view

Pursuant to this thread, I've tried to get my code to display which items are already checked when you display an edit view. All other fields are pre-populated.
Here's how I have it currently:
%fieldset.border.border-dark.p-2.mb-4
%legend Pronouns
.row.mb-4
= f.collection_check_boxes :pronouns, pronoun_list, :itself, :itself, {include_hidden: false} do |b|
.col-md-4.d-grid.d-block.mb-2
= b.check_box(class: "btn-check", checked: #member.pronouns.split(",").map(&:itself))
= b.label(:"data-value" => b.value, class: "btn btn-outline-dark text-start btn-lg")
.form-group.mb-4
= f.label :pronouns_other, "Other Pronouns"
= f.text_field :pronouns_other, class: "form-control border border-dark"
I need to call include_hidden: false as otherwise the array contains a single blank item as the first in the array.
And here's the helper method it refers to:
def pronoun_list
[
"He/Him/His",
"She/Her/Hers",
"They/Them/Their",
"Zie/Zim/Zir",
"Sie/Sie/Hir",
"Ey/Em/Eir",
"Ve/Ver/Vis",
"Tey/Ter/Tem",
"E/Em/Eir",
"Prefer not to disclose"
]
end
The thing that's different from the other thread is that I'm using a helper method to call the collection of items from while the other thread is calling a collection of objects from the database. So I'm not sure how I'm supposed to get the id's in the first place.
#member.pronouns is a string which contains an Array (I'm using PostgresQL), so first I need to convert it to an array I assume as I read somewhere else, before I can call map on it. but while .map(&:itself) doesn't return any errors, the items that are listed in the pronouns string aren't being checked when the edit view is rendered.
Any ideas?
After some hours of wrangling with the code, and digging around for other examples, I finally got Rails to work properly.
%fieldset.border.border-dark.p-2.mb-4
%legend Pronouns
.row.mb-4
- pronoun_list.each do |pronoun|
.col-md-4.d-grid.d-block.mb-2
= f.check_box :pronouns, { multiple: true, checked: #member.pronouns.include?(pronoun), class: "btn-check" }, pronoun, false
= f.label :pronouns, pronoun, value: pronoun, class: "btn btn-outline-dark btn-lg text-start"
Explanation:
I have yet to get it to work with a collection_check_boxes; however I did get it to work with a each method and then using multiple: true on each check box.
I also set the checked_value to the pronoun and set the unchecked_value field to false. if I don't set it to false and have multiple selected, I get a bunch of zeros in the array. with false set, I only get the ones I selected in the array.
I just went through this a bit, the way collection checkboxes works is it will call first and last on object in the collection you pass it. This is so you can have a different label shown to the user and pass a different value to the server. So in your case if you created the collection like
pronoun_list = [ [Him, Him], [Her, Her] ] #contrived example
Then remove the :itself, :itself from the input. The collection checkboxes helper will then call .first and .last on each of the nested arrays using Him, Her for both the label for the checkbox and the value for the checkbox sent to the server when submitting the form
When using a collection that comes from the db to begin with like User.all you can tell collection checkboxes what to use for the value and what to use for the label eg :id and :first_name where you have :itself, :itself

Why is field "line_type_eq" accessible in my view with f.object.line_type_eq but a field called "deleted_eq" always returns nil?

I am using Ransack to search a database with multiple fields. On the view side, I am pre-populating the default field values in my search form with the previous query, which is available in the view, from the controller as #q, using search_form_for #q.
Throughout the form, this is working successfully, but my field called deleted_eq always returns nil when I try to access it with f.object.deleted_eq to check the value. This is despite other field query values being returned properly in the same place using the same format, e.g. f.object.line_type_eq.
Is "deleted" a special field name in Ransack? All fields in my query are working as expected in the controller to return the correct results.
Changing the name of "deleted" would require a database migration and lots of code changes in the project, so I'd hope to check if it is a reserved name before I make all those changes for testing.
Edit for more info:
Rails 5.2.1, Ransack 2.0.1
deleted_eq is a dropdown done with f.select with descriptive text option names that are mapped to 'true', 'false', and ''. So yes, ultimately I believe Ransack is handling it as a boolean.
<%= f.select :deleted_eq, options_for_select([['Active Records', 'false'],
['Deleted Records Only', 'true'], ['Active and Deleted Records', '']],
f.object.deleted_eq || 'false'), {}, { :class => 'form-control',
:onChange => "searchOnchange();" } %>
Figured this out.
It seems like deleted_eq can be nil if a blank value is supplied. I had the most luck adapting another solution I found online like so:
<%= f.select :deleted_eq, [['Active Records', 0], ['Deleted Records', 1]],
{ include_blank: 'All Records', selected: params[:q] ? params[:q][:deleted_eq] : 0 },
{:class => 'form-control', :onChange => "searchOnchange();" } %>
It's a shame that the include_blank option ("All Records") always has to display as the first item in the dropdown, but since I'm able to choose what starts selected, and I can choose "Active Records", it's not the end of the world.

Active admin: Custom check_box input

I need to show a dynamic list of values to show on an Active Admin edit screen as checkboxes, where the list comes from code (not database). I can do that pretty easily, but I can't figure out how to show some of those as being checked.
Here's a simplified example of what I'm trying to do:
names = %w(Sam Darcy Ernie)
pairs = Hash[names.zip(names)]
f.input :buddies, as: :check_boxes, collection: pairs, checked: %w(Sam)
What I was hoping for is to show the 3 checkboxes and have the "Sam" box checked. None are checked though. What can I do to control which checkboxes are checked?
I ended up with the following that functions as desired:
people = [
['Sam', 0, checked: true],
['Darcy', 0],
['Ernie', 0],
]
f.input :buddies, as: :check_boxes, collection: people
It seems that the array items beyond the first 2 are used to set attributes. So in my case, the "checked" attribute is set, resulting in the element attribute of checked="checked"
I'm still interested in knowing if there is a better way of handling this though.

Multiple selection in RoR form_for

I have a list of items that I want to have as options for a variable. They will be saved in the model as an array, and are to be displayed as a list in the form_for. I was using
f.select(:var_name, [["option1"],["option2"],["option3"]], {}, {multiple: "multiple"})
Which works great to save into the model.
But when going back to the form, nothing is selected (even if the variable has them all saved). Then if I submit the form again, it passes an empty array. The only way for it to save correctly is to re-select the ones I want every time I view the form.
How can I get them to pass into the multi-select box?
I believe your problem stems from your choices parameter. You probably need an array of [option,id] mappings:
f.select(:person_id, Person.all.collect {|p| [ p.name, p.id ] }, {}, { :multiple => true })
When I started working on it again today, it was working. I'm not sure what change was made, but it could be that I needed to restart the server. It still looks like
f.select(:name, [[" "],["option"],["option2"],["option3"]], {}, {:multiple => true})
So it must not have been this code. In addition, the form beginning looks like
form_for(#model_name) do |f|
which hasn't changed either.
Regardless, it works now. Thanks!

Reusing the partials multiple times on one page in Ruby on Rails

I have a partial that renders a select box using the following method:
<%= collection_select 'type', 'id', #types, "id", "name",
{:prompt => true},
{:onchange =>
remote_function(
:loading => "Form.Element.disable('go_button')",
:url => '/sfc/criteria/services',
:with => "'type_id=' + encodeURIComponent(value) + '&use_wizard=#{use_wizard}'"),
:class => "hosp_select_buttons"
} %>
This partial gets used 2 times on every page, but at one point I need to get the value of the first select box. Using:
$('type_id')
returns the second select box. Is there a way to find the first one easily? Should I fix this using javascript or by redoing my partial?
Note: the dropdowns do get rendered in separate forms.
Yes, each element does need a unique ID, the page probably also fails HTML validation. Also, unless these are in 2 different forms you'll have a conflict with the CGI parameter name.
If they are in 2 different forms you can probably get away with just setting the :id as you posted, if they are the same form you need to abstract the parameter name too:
collection_select 'type', "id_wizard_#{use_wizard}"...
I figured out one way to do this by assigning an ID in the html_options block. I already am passing in a value for use_wizard, so I can append that value on to the ID to differentiate between the two dropdowns.
:id => "type_id_wizard_#{use_wizard}"

Resources