I would like to have the option value changed from the users name to the users ID on the option value in html.
For example:
<option value="John">John</option>
<option value="Jim">Jim</option>
<option value="Kelly">Kelly</option>
<option value="Monica">Monica</option>
<option value="Ralp">Ralp</option>
This is what my html is outputting, and i would like the value to be the users id, such as:
<option value="1">John</option>
<option value="2">Jim</option>
<option value="3">Kelly</option>
<option value="4">Monica</option>
<option value="5">Ralp</option>
I would also like it to be dynamic so when more and more users come I do not have to manually enter their names.
My rails for currently looks like this:
<%= form_tag '/login', method: 'post' do %>
Name:
<br/>
<%= select_tag :user_id, options_for_select(#users) %>
<br/>
<br/>
<%= submit_tag 'Login' %>
<% end %>
And my controller as such:
def login_user
user = User.find_by_name(params[:user_id])
if user
session[:user_id] = user.id
redirect_to user_path(user)
return
end
flash[:error] = 'Sorry that user not in the system.'
redirect_to root_path
end
Could someone please help point me in the right direction. Thank you in advance.
I don't understand what you mean by "dynamic". But following should fix your select issue
<%= form_tag '/login', method: 'post' do %>
Name:
<br/>
<%= select_tag :user_id, options_for_select(User.all.collect{|u| [u.name, u.id]}) %>
<br/>
<br/>
<%= submit_tag 'Login' %>
<% end %>
Got it, I used this instead:
<%= collection_select(:user, :id, User.all, :id, :name) %>
this gave me a drop down tab with user value and user name. Thank you all!
Related
I am new to ruby on rails please help me with this simple code :
I need to print
'HI' if option 1 is selected
'BONJOUR' if option 2,
'HOLA' if option 3,
'NAMASTE' if option 4.
on selecting a value on the dropdown and click the button,
<%= form_for :person do |f| %>
<%= f.select :desired_attribute, ['option1','option2','option3','option4']%>
<%= button_to "Show Text" , :onclick => "show_back(), return false" %>
<% end %>
involve your server.
view. Add remote: true to your form. And handle ajax request in controller. more about ajax in rails
<%= form_for :person, remote: true do |f| %>
<%= f.select :desired_attribute, options_for_select([ ['option1', '1'],['option2', '2'],['option3', '3'],['option4', '4']]) %>
<%= button_to "Show Text" , :onclick => "show_back(), return false" %>
<% end %>
in your controller
class PersonsController
MY_HASH = { '1': 'HI', '2': 'BONJOUR', '3': 'HOLA', '4': 'NAMASTE' }
def name_of_action
respond_to do |format|
format.js { render 'your_partial_name', name: MY_HASH[params[:person][:desired_attribute]] }
end
end
your_partial_name.js.erb
alert("<%= name %>");
Instead of MY_HASH it's better to use I18n to handle language issues. more about I18n
Use this syntax:
<%= f.select :point1, options_for_select([ ['option1', 'HI'],['option2', 'BONJOUR'],['option3', 'HOLA'],['option4', 'NAMASTE']]) %>
you will dropdown like this:
<select id="point1">
<option value="HI">option1</option>
<option value="BONJOUR">option2</option>
<option value="HOLA">option3</option>
<option value="NAMASTE">option4</option>
</select>
Dropdown option map with its value then you will get the value.
Is this the correct way of defining form, let me know if I need to provide any more details.
This is the UserPreference forms in new.html.erb
<%= form_for :user_preference, url: user_preferences_path do |u|%>
<p>
<%= u.label :title %><br>
<%= u.text_field :title %>
</p>
<p>
<%= u.label :description %><br>
<%= u.text_field :description %>
</p>
<p> <%= u.label :back_ground_color %><br>
<select name="bgcolor" id="bgcolor">
<option value="#FF3300">Orange</option>
<option value="#00FF00">Green</option>
<option value="#0000FF">Blue</option>
<option value="#FF0066">Pink</option>
<option value="#FFFF00">Yellow</option>
<option value="#FFFFFF">White</option>
</select>
</p>
<p>
<%= u.label :font %><br>
<select name="font" id="font">
<option value="Times New Roman">Times new Roman</option>
<option value="Verdana">Verdana</option>
<option value="Arial">Arial</option>
<option value="sans-serif">serif</option>
</select>
</p>
<br >
<p>
<%= u.submit %>
</p>
I am getting title and description when I am trying to render in html,
the attribute is not getting updated in database.
UserPreference.controller.rb
class UserPreferencesController < ApplicationController
def new
#user_preference = UserPreference.new
end
def create
#user_preference = UserPreference.new(userp_params)
#user_preference.save unless user_signed_in?
render plain: params[:user_preference].inspect
end
def edit
end
def update
end
private
def userp_params
params.require(:user_preference).permit(:title, :bgcolor, :font, :description)
end
end
When you say this
<%= u.text_field :description %>
because you are working with :user_preference, it will make an input like
<input type="text" name="user_preference[description]" value="foo">
(where 'foo' is the current value, or maybe it's blank)
Note the "name" attribute: this will go into params like
params = {:user_preference => {:description => "foo"}}
If you are going to hand-code the select then you need to make sure the name attribute has this structure too, eg
<select name="user_preference[bgcolor]" id="bgcolor">
So you will get params like
params = {:user_preference => {:description => "foo", :bgcolor => "#FFFFFF"}}
Which then allows you to say
#user_preference.attributes = params[:user_preference]
which is the standard way to deal with this in the controller.
However, rather than writing out all the html for the select, it's much nicer to use the rails form helpers (select in this case) like you do with the text fields. You can also define the options for the select with the options_for_select helper, which saves a lot of typing too.
<%= u.select :bgcolor, options_for_select([["Orange", "#FF3300"], ["Green", "#00FF00"], ["Blue", "#0000FF"], ["Pink", "#FF0066"], ["Yellow", "#FFFF00"], ["White", "#FFFFFF"]]) %>
It's also cleaner to define this variable of options in your code somewhere, eg in a UserPreference class method:
class UserPreference < ActiveRecord::Base
#class methods section
class << self
def bgcolor_options
[["Orange", "#FF3300"], ["Green", "#00FF00"], ["Blue", "#0000FF"], ["Pink", "#FF0066"], ["Yellow", "#FFFF00"], ["White", "#FFFFFF"]]
end
end
end
Now you can use the select like so:
<%= u.select :bgcolor, options_for_select(UserPreference.bgcolor_options) %>
http://guides.rubyonrails.org/form_helpers.html#the-select-and-option-tags
I'm a Rails beginner and I'm working on a preexisting Rails 2 project. In my application, I tried converting a select dropdown field to a form_handler f.select, but I'm getting this error:
undefined method `location.masterlocation.name
Here is my attempt:
<% form_for #newsavedmap, :html=>{:id=>'createaMap'} do |f| %>
<%= f.select(:start, options_from_collection_for_select(#itinerary.locations, "location.masterlocation.street_address, location.masterlocation.city, location.masterlocation.state, location.masterlocation.zip", "location.masterlocation.name"), :id => "startdrop")%>
Here is the original dropdown field:
<select id="startdrop">
<option value="">
<% for location in #itinerary.locations %>
<option value="<%= location.masterlocation.street_address %> <%= location.masterlocation.city %>, <%= location.masterlocation.state %>, <%= location.masterlocation.zip %>"><%= location.masterlocation.name %></option>
<% end %>
</select>
Thanks in advance for your help!
edit 1
I've gotten much closer using this code:
<%= f.select :start, options_for_select(#itinerary.locations.map{ |c| [c.masterlocation.name, c.masterlocation.street_address]}),{}, :id=>"startdrop", :name=>"startthere" %>
The problem is that I want to include the city, state, and zip in the value, all separated by commas. Any ideas about how to do this?
<%= f.select :start, options_for_select(#itinerary.locations.map{ |c| [c.masterlocation.inst_name, c.masterlocation.street_address AND , AND c.masterlocation.city AND , AND c.masterlocation.state AND, AND c.masterlocation.zip]}),{}, :id=>"startdrop", :name=>"startthere" %>
THIS WORKS!
Maptry Helper:
module MaptryHelper
def options_for_select(locations)
locations.map do |location|
[location.masterlocation.name, location_string(location.masterlocation)]
end
end
def location_string(masterlocation)
"#{masterlocation.street_address}, #{masterlocation.city}, #{masterlocation.state}, #{masterlocation.zip}"
end
end
View
<%= f.select :start, options_for_select(#itinerary.locations),{}, :id=>"startdrop", :name=>"startthere" %>
Place the following in a helper file
def select_options_for_locations(locations)
locations.map do |location|
[location_string(location.masterlocation), location.masterlocation.street_address]
end
end
def location_string(masterlocation)
"#{masterlocation.city}, #{masterlocation.state}, #{masterlocation.zip} #{masterlocation.name}"
end
Then in your view, you can use the following
= f.select :start, select_options_for_locations(#itinerary.locations), {}, :id => "startdrop"
I'm admittedly a real novice at most of this, including forming and parsing params hashes. I'm trying to get a hash of instances of the same model from a form for a voting application. Users can vote for as many candidates as they wish according to rank.
My votes#new does create Candidate.count instances of Vote with the user_id and rank properly set. I know this because the form is correctly iterating through #user.votes for each candidate.
Here's a snippet of the rendered form:
<input id="vote_rank" name="vote[rank]" type="hidden" value="1" />
<label for="vote_Candidate">Candidate</label>
<select id="vote_candidate_id" name="vote[candidate_id]"><option value=""></option>
<option value="1">Smithers</option>
<option value="2">Mr. Burns</option>
<option value="3">Bart</option>
<option value="4">Lionel Hutz</option>
<option value="5">Jimbo</option>
<option value="6">Troy McClure</option>
<option value="7">Duffman</option>
<option value="8">Maggie</option>
<option value="9">Moe</option>
<option value="10">Principal Skinner</option>
<option value="11">Apu Nahasapeemapetilan</option></select>
I can't figure out how to get the collection back from the form to my votes#create. I am able to get a params hash with a single set of candidate_id and rank values (the last), but not all 11 instances I stuck in it in the first place. The form wants to give up the right data.
#user.votes.create(vote_params) in votes#create is throwing this error: undefined method `stringify_keys' for "rank":String
Here are my controller methods and form.
def new
#user = current_user
#votes = Candidate.count.times { |i| #user.votes.build(:rank => i + 1) }
end
def create
#user = current_user
#params[:user][:votes].each do |vote_params|
##user.votes.create(vote_params)
params[:vote].each do |vote_params|
#user.votes.create(vote_params)
end
respond_to do |format|
if #user.valid?
format.html { redirect_to #user, notice: 'votes were successfully created.' }
else
format.html { render action: "new" }
end
end
end
<%= form_for :votes, :url => votes_path do |f| %>
<% #user.votes.each do |v| %>
<%= fields_for v do |vote_fields| %>
<%= vote_fields.hidden_field :rank %>
<%= vote_fields.label "Candidate" %>
<%= vote_fields.collection_select :candidate_id, Candidate.all, :id, :name, :include_blank => true %>
<% end %>
<% end %>
<p><%= f.submit :class => 'medium radius button' %></p>
<% end %>
Here's the relevant HTML
Only one set of values is getting passed:
{"utf8"=>"✓", "authenticity_token"=>"bVLXCQtOffEtu5xBNI0e94o9j9mJ8alHhuBhDkkfaRA=", "vote"=>{"rank"=>"11", "candidate_id"=>""}, "commit"=>"Save Votes", "action"=>"create", "controller"=>"votes"}
although the form is trying to give up the right values:
vote[rank]:1
vote[candidate_id]:2
vote[rank]:2
vote[candidate_id]:4
vote[rank]:3
vote[candidate_id]:2
vote[rank]:4
vote[candidate_id]:9
etc. (up to 11!)
Any help appreciated.
Update:
Solved it sort of. I'm putting this up in case it helps someone since I haven't found anything directly on point and it took me a long time to figure this problem out.
My form was creating identically named objects, which were just overwriting. Explains why I was only ever able to get the last set of values into the database.
My form now iterates over the objects passed from votes#new and includes the vote's rank in the name.
<%= form_for :vote, :url => votes_path do |f| %>
<% #user.votes.each do |v| %>
<% if v.errors.any? %>
<h1>errors</h1>
<% end %>
<%= f.fields_for "#{v.rank}" do |builder| %>
<%= builder.hidden_field :rank, :value => v.rank %>
<div class="row">
<div class="one columns"><%= builder.label "Rank #{v.rank}", :class => "left inline" %></div>
<div class="eleven columns"><%= builder.collection_select :candidate_id, Candidate.all, :id, :name, {:include_blank => true}, :class => "two" %></div>
</div>
<% end %>
<% end %>
<%= f.submit "Submit", :confirm => "Please review your ballot and confirm that your votes are correct before submitting. This message will appear as a reminder each time you press 'Submit', even if you've edited your ballot.", :class => "small round button" %>
<% end %>
This craps out a params[:vote] hash of uniquely named hashes e.g.
{"1"=>{"rank"=>"1", "candidate_id"=>"5"}, "2"=>{"rank"=>"2", "candidate_id"=>"2"}, "3"=>{"rank"=>"3", "candidate_id"=>"7"}, "4"=>{"rank"=>"4", "candidate_id"=>"4"}, "5"=>{"rank"=>"5", "candidate_id"=>"10"}, "6"=>{"rank"=>"6", "candidate_id"=>""}, "7"=>{"rank"=>"7", "candidate_id"=>""}, "8"=>{"rank"=>"8", "candidate_id"=>""}, "9"=>{"rank"=>"9", "candidate_id"=>""}, "10"=>{"rank"=>"10", "candidate_id"=>""}, "11"=>{"rank"=>"11", "candidate_id"=>""}}
My votes#create method dumps an array made of key/value pairs from the params hash into #user.votes.create(my_array)
def create
#user = current_user
#user.votes.create(sanitize_and_compress_vote_array params[:vote])
redirect_to thankyou_path
end
Then next challenge is to get validation error messages to work properly. It's over my head because what I'm seeking to validate is an array of key value pairs by the uniqueness of candidate_id scoped by user_id before any values hit the database. It looks like Rails doesn't make this easy.
validates :candidate_id, :presence => true, :uniqueness => {:scope => :user_id, :message => "You may only vote for a candidate once."}
The validation works just fine for rejecting duplicate values, but it's useless because those values that already passed are obviously already in the database. I haven't found squat on how to validate members of a collection against themselves before they save and I feel like I'm talking to myself :-(
Right now, I'm using the form_for.select and options_for_select rails helpers to create a select box with the data from the model. However, what I really need is a combobox like the one introduced with HTML5:
<input type=text list=browsers >
<datalist id=browsers >
<option> Google
<option> IE9
</datalist>
Is there a rails helper for creating such elements?
No, but it's quite easy to setup your own form builder helper method to achieve such a result, a simple example would be:
app/form_builders/combobox_form_builder.rb
class ComboboxFormBuilder < ActionView::Helpers::FormBuilder
include ActionView::Context # for nested content_tag
include ActionView::Helpers::FormTagHelper #for sanitize_to_id method access
def combobox_tag(name, options, opts= {})
#template.content_tag(:input, :name => name, :id => sanitize_to_id(name), :type => "text", :list => opts[:list_id]) do
content_tag(:datalist, :id => opts[:list_id]) {options}
end
end
end
After restarting your server you can implement your new combobox using the form builder by specifying a builder argument in your form_for call:
<%= form_for #foo, builder: ComboboxFormBuilder do |f| %>
<%= f.combobox_tag(:browser, options_for_select(["Firefox", "Chrome", "IE9"]), :list_id => "list")%>
<% end %>
Output HTML:
<input type="text" name="browser" list="list" id="browser">
<datalist id="list">
<option value="Firefox">Firefox</option>
<option value="Chrome">Chrome</option>
<option value="IE9">IE9</option>
</datalist>
Keep in mind that both IE & Safari do not offer support for the HTML5 Datalist.
<%= form_for #person do |f| %>
<%= f.label :first_name, "First Name" %>:
<%= f.text_field :first_name, list: 'first-name' %>
<datalist id="first-name">
<% Person.all.each do |person| %>
<option value="<%= person.first_name %>"></option>
<% end %>
</datalist>
<%= f.submit %>
<% end %>
You may also want to do distinct:
<% Person.select(:first_name).distinct.each do |person| %>
Just example from my code:
= form_tag controller:'beer', action: 'create' do
= text_field :beer, :name, list: 'beer-name'
%datalist#beer-name
- Beer.all.each do |beer|
%option{value: beer.name}