Multiple selection in RoR form_for - ruby-on-rails

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!

Related

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.

having trouble understanding :multiple => true in a checkbox

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!

how to ensure rails multiselect input field passes all values correctly?

so, I've got a form inside a bootstrap modal.
when the modal loads, some javascript calls to the server to figure out what the current user has already chosen (this is an edit modal). once the server response returns, the form select sets itself to the values that the user has already chosen as is demonstrated in the below screenshot.
My problem occurs when the form is submitted. The params being sent to the server have the key 'room_object_id' that points to a single value. Naming issues of that key aside, I need that key to point to an array of values or a string or any structure that will hold multiple values and this is not the case, as demonstrated by the below screenshot.
My form is being generated by
<%= form_for :student, url: student_path, html: {class: 'form-horizontal sync'}, method: :put do |f| %>
<%= f.select(:room_object_id, options_for_select(#rooms.map {|room| [ room['name'], room['objectId'] ]}),{multiple: 'true', include_blank: ''} , {:class => 'select2-init form-control force-full-width', required: 'true', multiple: 'true', name: 'room_object_id'}) %>
<% end %>
I'm a bit unclear how select2 and the html form are working together and I have a feeling my problems are related to this. I'm also a bit unclear of the different usages of rails select, collection_select and options_for_select. I've looked at other SO posts on this topic but nothing pointed me in the right direction. Any pointers would be much appreciated.
Are you using the JavaScript required to run select2?
$(document).ready(function() {
$("#id_of_your_select_field").select2();
});
If you are, is your JavaScript console displaying any errors?

simple_form select collection populated by AJAX

I thought this would be fairly easy, but I'm not finding any help by Googling.
I have a form (simple_form) with numerous inputs with select lists (collections) that are populated from the database, so many it is slowing down the initial page load. I thought I could speed it up by only populating those drop down lists as the user selects them using Ajax. Is there something built in like remote => true for the form itself? Can someone point me in the right direction?
EDIT:
I found this SO question but I cannot figure out how to implement the answer.
Currently, my form looks like this;
= simple_form_for(#account)
= f.input :account_number
= f.input :area, collection: #areas
= f.submit nil, :class => 'btn btn-primary'
Based on the answer in the linked question, I should add something like this, but of course it is not working
= simple_form_for(#account)
= f.input :account_number
= f.input :area, collection: #areas, :input_html => {"data-remote" => true, "data-url" => "/my_areas", "data-type" => :json}
= f.submit nil, :class => 'btn btn-primary'
I can think of two ways to go about this if you don't want to load the contents initially when the page loads. One way is to run a script after the DOM has loaded to change the options for the select tag and the other is to collect the options when you click on the drop-down on the select element. I might go for the first way because there wouldn't be latency when a user clicks on the select element--they wouldn't have to wait for the options to populate.
So you'd run a jQuery script on document ready that makes an AJAX call to a method in your controller, which then returns the collections you want, then you iterate through the select elements you want to change with JQuery scripts. It might look something like this.
# in view with the select options to be changed
$(document).ready(function() {
$.get(change_selects_path, function(response) {
$.each(response, function(args) {
// code for each select element to be changed
$('.class_of_select_element').html(<%= j options_from_collection_for_select(args) %>);
});
});
)};
# in controller
def change_selects
# make db calls and store in variables to feed to $.get request
end
Note that this not tested but should give you a good start towards a solution. For further info on the each loop, you can check out this documentation.
Not sure if this fits your exact use case (please clarify if not), but I also have a few collection selects that have a large amount of database rows behind them. I use the select2-rails gem to take care of this. Users can begin to type in the name and the relevant results will show up (it will also show a few initially if they don't type something).
Check it out here: https://github.com/argerim/select2-rails
Edit: For a cascading dropdown, I recommend this gem: https://github.com/ryanb/nested_form

Value not retained in the dropdown

I am using the simple form in my application where I have a drop down. The code is as:
<%= f.select :assigned_to, options_for_select(#user_members.collect{ |u| [u.name,u.id] }, :selected =>"#{#task.assigned_to}"), :prompt => "Assign To"%>
The issue that I am facing is that the value is not retained in the drop down after refreshing the page even though I have used :selected also.
The selected field's value should be pased in the params, so you can use that as the selected. Use the "pry" gem to debugg, your development life will become much easier :)
Try that and let me know how it went. Also, could you the code from your controller?

Resources