show already selected items in rails select drop down - ruby-on-rails

I have a select box in rails. When editing the records, I want the previously selcted items to be highlighted.
I have
<div class="field">
<td><%= f.label :keywords %>(Use Control-Click to select multiple keywords)</td>
<td> <%= f.select :keywords,
options_for_select(#keywords,
:selected => #keywords),
{:include_blank => false},
{:multiple => true, :size =>10} %>
</div>
I tried a couple of variations on the :selected => statement above but can't get what I want.
What I'm looking for is When a user edits a record, the f.select will have the selections that are in the database pre selected.
I do see a "Gotcha" here in that even if the items are pre selected, if the user clicks on any item without a Control-click, then the pre selected items are lost.
-------- update-----------
form for
<%= form_for #bedsheet_line, :html =>
{ :class => 'form-horizontal', multipart: true} do |f| %>

I got this working.
I changed the form dropdown element to
<%= f.select :keywords,
options_for_select(#keywords,
:selected => previous_keywords),
{:include_blank => false},
{:multiple => true, :size =>11} %>
The difference is that the selected => is calling a def called previous_keywords.
previous_keywords is in my controller and looks like
# ---------------------------------------- previous keywords ----------------------------------------------
# This is designed to grab the keywords already entered for a bedsheet. This is so that if a bedsheet records is
# edited, then the keywords will be selected if the record is edited.
#
# NOTE - the eval function is risky. However, since this is an internal application and the input is coming from
# a select box, then the risk should be acceptable.
helper_method :previous_keywords
def previous_keywords
#current_bedsheet_line = BedsheetLine.find(params[:id]) # grab the current bedsheet line
#previous_keywords = #current_bedsheet_line.keywords # get the keywords for the current bedsheet line
keywords = Array.new
keywords = eval(#previous_keywords) # NOTE - the eval function is risky if there is any outside traffic.
return keywords
end
NOTE - the eval function is risky. HOWEVER this application is for internal use only, does not deal with financial or other sensitive data and what is being fed to eval is from the database which comes from a drop down list. Therefore the risk should be mitigated.

Related

Collection_select doesn't let me select when multiple => true

This is the template with multiple => true, but when i remove the multiple the selection tray works perfectly and takes in a single value.
What i need is multiple options to be selected and to be stored in the confirer_string as a string.
The problem i'm encountering is that all the options are listed but they coudn't be selected though they can be clicked on.
new.html.erb
<%= form_with(model: #base, local: true) do |form| %>
<%= form.label :description %>
<%= form.text_field :description, id: :base_tbl_description %>
<%= form.label :confirer_string %>
<%= form.collection_select(:confirer_string, Confirmer.all , :position, :name,{ :prompt => "Please select" }, { :multiple => true } ) %>
<%= form.submit %>
<% end %>
Is it a problem since i'm not using id's but integer fields. And one more thing :confirer_string is of type string.
There are two models, without any association between them. All i'm trying to do is get the list of options from the other model to be listed as option in the selection of primary model. Then the set of selected options will return their position, which will be stored in the confirer_string.
Thing is i cant select anything, not even one option when multiple is true.
UPDATE: i got the multiple select working again but i need to use ctrl+click to select mutliple entries. But the data is not storing, it is giving unpermitted error: conf_string
Just add the {attribute_name: []} in the strong params.

f.select doesn't show entered value in Rails 4 when editing a record in a form

I'm new to rails and I'm trying to build my Edit record form.
The record I'm editing is an address.
I am having trouble getting the f.select menu to display the record in the #address.state column. It puts all the other address info the respective input fields as defaults...but not the f.select. With the f.select it defaults back to "Alabama" (the first state). How can I get the menu to stay set on the state that is recorded in the database?
Here's my code:
<%= f.select :state, options_for_select(us_states), { :class => 'chosen-select ', :style => 'height:30px', }, {:value => #project.state} %>

display previously selected choices in multiple select form (rails)

I've built a multi-select form (from within form_for) like this:
<div class="rounded-block quarter-wide radio-group">
<h4>Exclude customers from source:</h4>
<%= f.select :excluded_sources, options_for_select(User.select(:source).group(:source).order(:source).map {|u| [u.source,u.source]}), {:include_blank => false}, {:multiple => true} %>
<%= f.error_message_on :excluded_sources %>
</div>
this works well for what I need. The only problem is that when i go back to the page that displays the choices, I don't see what was previously selected (i.e. what is already in the DB at time of rendering). Is there an easy way to get rails to display what's previously been selected? I'd MUCH prefer not to switch to check boxes.
in my matching profiles model (corresponding to the table that stores excluded_sources), i have this:
serialize :excluded_sources
this ended up being the relevant piece:
:selected => matching_profile.send(:excluded_sources)
here:
<div class="rounded-block quarter-wide radio-group">
<h4>Exclude customers from source:</h4>
<%= f.select :excluded_sources, options_for_select(User.select(:source).group(:source).order(:source).map {|u| [u.source,u.source]}, :selected => matching_profile.send(:excluded_sources)), {:include_blank => false}, {:multiple => true} %>
<%= f.error_message_on :excluded_sources %>

Ruby-on-Rails: populate select box based off prior select

I have a set of 3 collection_selects that I would like to filter the next select. Upon selecting an item in the first select box, it should limit the possible values of the second and third select boxes.
A similar data model would be as follows...
Tables, and fields
Lock
lock_id
brand_id
master_id
regular_id
Lock Brand
brand_id
Master Key
master_id
brand_id
Regular Key
regular_id
brand_id
So while filling in the form for adding a new Lock there would be select boxes for brand, master, and regular. Upon selecting a brand, it would then limit the master and regular keys to those that are only of the selected brand.
I've found a couple partial examples of how to do this, however none are complete. I'd appreciate a complete example of how to implement this.
All you need to do is bind the selects with an event listener that fires off an ajax request populating the other 2 partials containing the subsequent selects. i.e.
<%= form_for #thing, :remote => true do, :update => 'second_form' |f| %>
<%= hidden_field_tag 'form_partial', :value => 'form_2' %>
<%= select_tag :some_param, [[a,a],[b,b],[c,c]] :class => 'submittable' %>
<%= f.label :checked %>
<%= thing.name %>
<% end %>
<div id='second_form'>
</div>
<div id='third_form'>
</div>
class ThingController < ApplicationController
def update
checkboxes = some_logic_to_select_checkboxes from params[:some_params]
render :partial => params[:form_partial], :locals => {:select_menu => select_menu}
end
end
$('.submittable').live('change', function() {
$(this).parents('form:first').submit();
return false;
});
Your form partial should contain your forms populated with whatever selects you want enabled. Thought is was redundant to just repeat the form.

Ruby on Rails Country/State Select Enigma

I am trying to implement something seemingly very simple, and I have been beating my head against it for days at this point.
My desired end result is a Country select drop-down, tied to a State select drop-down, in such a way that when a given country is selected, IF states are known THEN those states are displayed in a select drop down, and if NO states are known for that country, then a text field is displayed instead.
I feel like I am almost there. At this point the interface will actually generate that list of states based on the persons' country, except it is refusing to update the drop-down dynamically.
The portion of my view where country and state location is gathered looks like:
# _person_setup.html.erb
<td>
<%= f.label :country, 'Select your country' %>*<br />
<%= f.select :country, Carmen::country_names, {},
{:style => 'width: 200px',
:id => 'country_select',
:onchange => remote_function(
:url => {:action => 'update_states'},
:with => "'country='+value")} %>
</td><td>
<p>
<div id="states_div">
<%= render :partial => 'states',
:object => Carmen::states(
Carmen::country_code(
#person.country)),
:locals => {:form => f} %>
</div>
</p>
</td>
The partial being referenced in the DIV is as follows:
# _states.html.erb
<% unless states.nil? or states.empty? %>
<%= form.label :state, 'Select your state' %>*<br />
<%= form.select :state, states.collect{|s| [s[0], s[0]]} %>
<% else %>
<%= form.label :state, 'Please enter state or province' %>*<br />
<%= form.text_field :state %>
<% end %>
Finally, the controller code which is intended to update the list of states dynamically:
def update_states
puts "Attempting to update states..."
q = params[:country]
states = Carmen::states(Carmen::country_code(q))
puts "Country = #{q}, states = #{states.collect{|s| s[0]}.join(", ")}."
render :update do |page|
page.replace_html "states_div",
:partial => 'states',
:object => states,
:locals => {:form => form_for(#person)}
end
puts "OK"
end
Now, this code is being called at the proper time and generating the appropriate lists of states. For example, when the user clicks Australia, "Attempting to update states... Country = Australia, states = Australian Capital Territory, New South Wales, Northern Territory, Queensland, South Australia, Tasmania, Victoria, Western Australia" shows up in the server process. However it doesn't update the page, and won't print the "OK" at the end. In short the line which is failing is undoubtedly
page.replace_html "states_div",
:partial => 'states',
:object => states,
:locals => {:form => form_for(#person)}
Note that replacing this line with
page.replace_html 'states_div', "<b>is it working</b>"
properly replaces the div, but of course not with anything useful.
Can someone help me understand what is going on here?
It looks like you're assuming that the #person variable is still available from your original action. This could be set up by a filter for the current person but you don't show that in your question.
If you do need to lookup the #person again you'll have to pass the id through in your remote_function I think.
Ryan Bates has a Railscast that shows how to select a category for a product or create a new category by typing the name. It sounds like a similar scenario to what you have, so you might want to check it out: Create Model Through Text Field.
This took me a full day to figure out something that would at least "work". I am also using Carmen and also messing with the select tag in a form_for model form (actually, fields_for nested within forms_for...which adds additional complications).
I would think there is a better solution but this worked for me. The select needs to be referenced by the form but the options don't. Thus, first time through, I use the Carmen state_select method which populates the select tag correctly and all the nested options tags. The second time through, I just replace the options. Take a look:
In the view, I chose to use an observe_field method since I do other things besides update the states (some other localization changes) but this should work for remote_function and others, too:
<%= address_form.country_select :country, {:prompt => "--Select One--"} %>
Don't be confused by the id (user_address_attributes_country) it is just my silly forms_for/fields_for implementation)
<%= observe_field :user_address_attributes_country, :url => { :action => :changecountry }, :with => 'new_country' %>
<%= address_form.state_select :state, #user.address.country, {:prompt => "--Select One--"}, :style => 'width: 90px' %>
Then in my controller, it just looks like this:
def changecountry
c = params[:new_country]
respond_to do |format|
format.html
format.js {
render :update do |page|
page['user_address_attributes_state'].innerHTML = \
"<option>--Select One--</option>" + state_options_for_select(nil, c)
end
}
end
end
Note: state_options_for_select is also from Carmen. I could not get it to work unless I put it inside the respond_to block where I guess the view helpers are available. Also, I hard code user_address_attributes_state which is my nested id generated from the form_for/fields_for address_form.state_select rendering call in the view.
I hope this helps. If anyone can do it better, believe me, I'm all ears. I'll change the design in time...but needed something that just worked today and this was the best I could figure out in a limited time.

Resources