I have created drop down list for employees.
What I want?
I want to select full Name for each one of them.
Type of form:
I use simple_form.
I actually have:
= f.input :person_id, label: "Employee", collection: #employee, prompt: "Select employee"
Result(I know, that is reference):
Before I use collection_select, but simple_form doesn't support validation for this type of collection.
Code for collection_select. This type of drop down list displays properly full name.
= f.collection_select :person_id, #employee, :id, :fullName, {prompt: "Wybierz pracownika"}, {class: "form-control"}
Update:
fullName is a method in a person.rb model.
def fullName
"#{first_name} #{last_name}"
end
Object employee.
#employee = Person.where.not(type: "Client")
The easiest way to do this is :
= f.select :person_id, options_for_select(#employees.map{|e| [e.fullName, e.id]}), {:prompt=>"Wybierz pracownika", :required => true}
It will show full names as select options and will dispatch ids as values with form.
You follow this code like below:
<%= f.collection_select(:person_id, Model.all, :person_id, :fullName,{:prompt=>"Wybierz pracownika"}, {:class => 'form-control'}) %>
You will replace your model_name.
Or
= f.input :person_id, label: "Employee", collection: #employee.fullName, prompt: "Select employee"
I think will help you
Related
I have a Category Model. I want to let user select category for their post. The Model has only name. It's one model to many categories relationship.
Here is my code
<%= f.select :category, Category.all, :prompt => "Select One" %>
I learnt it from rails guy How to create Categories in Rails
I want to display the name but it shows some weird option.
Thanks in advance.
Try this i hope this will help.
<%= f.select :category, Category.all.collect{|c| [c.name, c.id]}, prompt: "Select One" %>
<%= f.select :category, Category.all.map{|c| [c.name, c.id]}, :prompt => "Select One" %>
Try this
My form contains the following tag:
<%= f.collection_select :employee_id, #employees, :id, :value, :prompt => true %>
Employee looks like this:
employee
- attr1
- attr2
- user
- firstname
- lastname
My question: How to set the lastname of an employee as the value in the select field? I'm pretty sure it's possible, but I think I have some gaps in the syntax.
Why would you do that?
It's possible, with:
<%= f.collection_select :employee_id, #employees, :last_name, :text_method, :prompt => true %>
Where :text_method is method which called on #employees members will return text that you'd like to appear in dropdown.
You may be asking yourself why I have used <%= f.select %> this is FormOptionHelper on the Ruby on Rails Api this is very similar to collection_select however with that it returns and tags for the collection of values. Whereas select creates a series of contained option tags for provided object and method. So in saying this I believe you could have the following:
<%= f.select(:employee_id, Employee.all.collect { |emp| [emp.lastname, user.id] }
.sort{ |a, b| a[0] <=> b[0] }, {:prompt => "Select a Employee"}) %>
This selects all employees and sorts them in order of their last name.
I have a collection_select form with the following code:
<%= f.collection_select(:city_id, City.order('name ASC'), :id, :name, {:prompt => "Select a City"}, {:id => 'cities_select'}) %>
Right now it just lists all of the cities by name in my database, but there are duplicate city names. For example, there are two "Peoria" cities.
So, I want to show the state attribute separate by a comma like: "Peoria, IL" to help distinguish the cities. How do I write this code within the form code?
You can also use collection_select for that
f.collection_select :city_id, City.order('name ASC'), :id, :name_with_state, { prompt: 'Select a City' }, { id: 'cities_select' }
name_with_state should be in your city model
def name_with_state
"#{name}, #{state}"
end
f.select :city_id, City.all.map{|c| ["#{c.name}, #{c.state}", c.id] }, { :prompt => "Select City" }
You can use select:
<%= f.select(:city_id, City.order('name ASC').map{ |city| [city.your_method, city.id]},
{:prompt => "Select a City"}, {:id => 'cities_select'}) %>
I'm trying to create a select box that takes data from my db. I'm having trouble setting this up. I tried this code:
<%= f.fields_for :unit do |u| %>
<%= u.label :name %>
<%= u.select :name, :class => "ingredient_unit", :prompt => "Please Select" %>
<% end %>
but I'm missing the part of the choices, I don't know how to pull them out of the database. I tried using collection_select, which worked, but then the class option wasn't working... collection_select went like this:
<%= u.collection_select :unit, Unit.all, :id, :name, :class => "ingredient_unit", :prompt => "Please Select" %>
I also don't understand what the first symbol means (:unit), it seems to be setting the html id and name, so that can be anything I want it to be?
You should look at the documentation for collection_select and select. But to answer your question, for the select part, you forgot to pass the list of options to choose from. You also need to swap the order for prompt and class since prompt is an option for the helper and class is an html option
<%= u.select :unit_id, Unit.all.map { |u| [u.name, u.id] }, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>
For the collection select
<%= u.collection_select :unit_id, Unit.all, :id, :name, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>
The first parameter passed to both helper is the column name where you want the selected answer to be saved. The 2 codes above just shows 2 different ways to generate the same select tag.
The first symbol tells it which field to populate with the id returned from the user selection.
Also, you should wrap your class section in {}
:unit refers to the model attribute that you're using for the select element. Yes, it will setup the name/id of the element (and name is the most important for the params hash).
To set a class in the collection_select, specify it as a hash as that helper takes it as an html_option.
<%= u.collection_select :unit, Unit.all, :id, :name, { :prompt => "Please Select" }, { :class => "ingredient_unit" } %>
I acctual don't know where Array ["Yes",true] came from. I have two models like this:
GeneralExam has_many topic_questions
TopicQuestion belongs to general_exam, belongs_to topic
In TopicQuestion, I have columns: general_exam_id, topic_id, number_question, to store a number question for each topic in general exam.
I built a nested form for create new general exam, on form I built a dynamic select, when user choose a course from a dropdown list, I have other dropdown lists to display topics of course chosen by user.
This is my javascript code for dynamic select:
<% content_for :head do %>
<script type="text/javascript">
$(document).ready(function() {
$('#general_exam_course_id').change(function () {
$.ajax({
type: "POST",
url: "<%= update_topics_general_exams_path %>",
data: { course_id: $('#general_exam_course_id').val() },
dataType: "script"
});
});
</script>
<% end %>
#general_exam_course_id is ID of dropdown list for select course. update_topics_general_exams_path is route to my update action in general exam controller, this is my update action:
def update_topics
#course = Course.find(params[:course_id])
#topics = #course.topics
end
I have a update_topics.js.erb also:
$('div#topic_questions select').html("<%= j options_from_collection_for_select(#topics, 'id', 'name') %>");
Dropdown lists in div#topic_questions will get #topics value from update_topics action (I think so) and display it. When I create new general exam, it's ok. But when I press Edit link, it show me an error which I don't know why and where it comes:
NoMethodError in General_exams#edit
undefined method `name' for ["Yes", true]:Array
Extracted source (around line #3):
1: <div class="row">
2: <div class="span6"><%= remove_child_link "Remove below topic", f %></div><br><br>
3: <div class="span3"><%= f.association :topic, collection: #topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %></div>
4: <%= f.input :number_question, placeholder: 'Number of questions', label: false, style: 'display: inline' %>
5: </div>
My edit action only have: #general_exam = GeneralExam.find(params[:id]). I don't know why topic association field of general exam display an Array ["Yes", true]. I don't have it, don't define it any where, why it come when I edit general exam?
Update
If I remove label_method: :name, value_method: :id in:
<%= f.association :topic, collection: #topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %>
The page is not error, but Dropdown lists have value Yes, No in select, not the name of topic I have created for exam. Form can get the number question of each topic, but it can not get name of topic.
When I create:
When I edit:
I found this in config/locales/simple_form.en.yml:
en:
simple_form:
"yes": 'Yes'
"no": 'No'
Is this a problem?
Update: Don't pass #topics in new action but it's still have on new page When course even is not selected yet
My new action:
def new
#general_exam = GeneralExam.new
5.times { #general_exam.topic_questions.build }
##topics = Topic.all
end
As in my extract source above, I have below code in new, edit too (use same form):
<%= f.association :topic, collection: #topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %>
So I don't pass #topics, but when I go to new page, dropdown lists for topic still display Yes, No value.
Ok , our time for comments chat-like is over :)(the System suggested to move to the chat room ) . The solution it seems to be passing the collection inline in the association of the simple_form :
<%= f.association :topic, collection: #topics, label_method: :name, value_method: :id, prompt: "Choose a topic", label: false %>
becomes :
<%= f.association :topic, collection: Topic.limit(1), prompt: "Choose a topic", label: false %>
It would work for now , I think .
You've got the right idea by assigning your query to #topics and passing it to your view... but, you're putting it in the wrong actions and not passing them to the right views:
def update_topics
#course = Course.find(params[:course_id])
#topics = #course.topics
end
-
What you should do:
There is NO update view for your update action, so, you must place the following 2 lines:
#course = Course.find(params[:course_id])
#topics = #course.topics
in both your new action and your edit action
Then you can go ahead and use your original simple_form code, which IS/WAS ORIGINALLY correct:
<%= f.association :topic, collection: #topics,
label_method: :name, value_method: :id,
prompt: "Choose a topic", label: false
%>
Alternatively, you could SKIP the #topics in your controllers and simply put the following in your views:
new view
<%= f.association :topic, collection: Topics.all,
label_method: :name, value_method: :id,
prompt: "Choose a topic", label: false
%>
edit view
<%= f.association :topic, collection: Course.find(params[:course_id]).topics,
label_method: :name, value_method: :id,
prompt: "Choose a topic", label: false
%>
NOTE the difference:
I would think that in your new view you would want the user to see ALL possible topics.
While in your edit view you just want them to see the topics for this course, correct?
-
Why it happened:
Since, you were not passing ANY collection earlier, there was no 'name' method/column for simple_form to use as the labels/display values in the dropdown and thus the error message you got regarding Array ["Yes",true]
If/when you removed the label_method: :name, value_method: :id, options you probably would have seen as many choices as you had expected rows in the dropdown, but instead of a list of the course topic names you would have seen a list of Topic objects (something like this):
#<Topic::xxxx>
#<Topic::xxxx>
...
#<Topic::xxxx>
And, when you don't supply the collection, you get only 2 yes/no values which is the simple_form default per the config file you found (config/locales/simple_form.en.yml).
So, as you might have guessed by now, this is why what you finally used...
<%= f.association :topic, collection:
Topic.limit(1),
prompt: "Choose a topic",
label: false
%>
...kind of "worked" as a workaround -- because it *did* execute a proper query and supplied it to the simple_form, but it limited the results to only the *first* topic in the table (without any ordering/sort)
At least, this is what I have learned/gone through. HTH!