Using SimpleForm, Can I set the default values for :label_method and :value_method so I do not need to set it for each input?
By default, I mean a place to set label_method and value_method for all my inputs, so I do not need to set them for each input.
Example:
Instead of this:
<%= f.association :model_in_question, include_blank: false, label_method: :label_for_form, value_method: :value_for_form %>
I want this:
<%= f.association :model_in_question, include_blank: false %>
I think this is what you're looking for:
Simple form association custom label name
<%= f.association :owner_type, :include_blank => false, :label_method => lambda { |owner| "#{owner.name} | #{owner.subtype_name}" } %>
The same logic applies for value_method. So if you have a model, you can make a method called label_for_form and value_for_form which return your required values. Then in your form:
<%= f.association :model_in_question, include_blank: false, label_method: :label_for_form, value_method: :value_for_form %>
So long as the objects in your collection respond to both those methods, then you won't need to manually write out the collection in the form.
Related
I have this code within my rails form:
Categories: <%= f.collection_select :tag_ids, Tag.order(:name), :id, :name, {}, {multiple: true} %>
This code is working, but I want to use simpleform gem to redesign my form. However, I cannot seem to figure how to 'translate' this code into simple form. Anyone have any idea how? Thanks.
Something like this should do the trick:
If you have a many to many relation you could first try what the default does.
<%= f.association :tags %>
If the defaults don't work out you can make an explicit collection:
<%= f.input :tag_ids, as: :select, collection: Tag.order(:name), label_method: :name, input_html: {multiple: true} %>
# or
<%= f.input :tag_ids, as: :select, collection: Tag.order(:name).pluck(:name, :id), input_html: {multiple: true} %>
Alternatively if you define the Tag#to_label method you don't have to pass the name of the label method. The Tag#id gets used as default value method. If you would like another value specify the method like so: value_method: :something_else.
See the simple_form Usage section (intro, collections and associations).
Using the simple_form gem, I've a form with the following field:
f.association :company, label_method: :company_name, value_method: :id, include_blank: false
How can I sort the resulting array by a attribute, like :name? The docs only mention using order for another case, using collection: .... Just adding order: :name to my input doesn't work.
Is this possible at all? Thanks!
You can specify the ordering of the collection items like this:
f.association :company, collection: Company.all.order(:name), label_method: :name, value_method: :id
I don't think there is another way to sort the displayed items, you have to use collection.
I am using Rails and simple form. I have a collection that I am displaying with an association field. For each item in the collection, I want to display a hover over title of an attribute belonging to that item, namely description.
Here is my association:
<%= f.association :user_roles, collection: #roles, as: :check_boxes, label_method: :name, label: false %>
I want to display a hover over text of the description of each role. In my head something like the following should be doable:
<%= f.association :user_roles, collection: #roles, wrapper_html: {title: UserRole.where(id: this_current_items_id).first.description}, as: :check_boxes, label_method: :name, label: false %>
or:
<%= f.association :user_roles, collection: #roles, wrapper_html: {title: :description}, as: :check_boxes, label_method: :name, label: false %>
Neither of these work obviously but in my head a solution like this should be easy. I guess the guys at simple form never thought of this situation.
However, is this possible to do? Or, how can I get the ID of the current item so that I am displaying that items description on hover over?
PS: What I need is a simple form hover_method!
You can easily add other attributes to each item in your collection like so:
<%= f.association :user_roles, collection: #roles.map { |r| [r.name, r.id, { title: r.description, "data-toggle": "hover" }] }, as: :check_boxes, label: false %>
I have a simple_form input field that looks like this:
<%= f.input :particular_users, collection: #all_users, input_html: { class: 'multiselectuser', multiple: true} %>
When I leave multiple: true off, the form submits the chosen value for the parameter :particular_users and I can see the value when debugging using "raise params.inspect". However when I leave the multiple: true option there, no vales get passed for the parameter :particular_users.
What am I doing wrong?
EDIT: I can not use the association input because :particular_users is a virtual attribute and has no relationship. I want the multiple select box to pass whatever values that are in there, even if they are arbitrary.
f.input :days, collection: #your_collection, input_html: { multiple: true }
It actually does work the way I wanted it to. The trick is to tell the strong parameters to allow a hash. It doesn't throw a strong parameters error, the param just gets thrown out and doesn't come through. So I set it to for example: params.require(:survey).permit(:particular_users => []).
To create multiple select tags with simple_form, use:
<%= f.association :particular_users, collection: #all_users, input_html: { class: 'multiselectuser'} %>
see part Associations in the gem description.
But as you don't want to use an ActiveRecord associaion, use select_tag:
<%= select_tag 'particular_users',
options_from_collection_for_select(#all_users, :id, :name),
multiple: true, class: 'multiselectuser' %>
I have a form like this in my orders/new page. I have used this to select model location and then choose a model from the location according to what is selected in the above select box.
<%= f.label "SELECT MODEL LOCATION *" %>
<div class="list_number">1</div><%= f.collection_select :location_id, Location.all, :id, :formatted_display, prompt: true, :required => true, :class => 'chosen-select' %>
<%= f.label "SELECT YOUR MODEL *" %>
<div class="list_number">2</div>
<%= f.grouped_collection_select :performer_id, Location.order(:name).map{|group| Performer.find_by_location_id(group.id).map{|performer| {'data-markup'=>performer.white_label.markup}}}, :performers, :name, :id, :first_name, include_blank: true, :required => true, class: 'chosen-select' %>
In the grouped_collection_select when I use map to set the data attribute I am getting the following error:
undefined method `map' for #<Performer:0x00000006813958>
How do I solve this error and get the data required?
After trying the below code
<%= f.grouped_collection_select :performer_id, Location.order(:name).map{|group| Performer.where(location_id: group.id).map{|performer| {'data-markup'=>performer.white_label.markup}}}, :performers, :name, :id, :first_name, include_blank: true, :required => true, class: 'chosen-select' %>
I get the following error
undefined method `performers' for [{"data-markup"=>#<BigDecimal:67e80c8,'0.0',9(36)>}]:Array
When I tried the following
<%= f.grouped_collection_select :performer_id, Location.order(:name), :performers, :name, :id, :first_name,Location.order(:name).map{|group| Performer.where(location_id: group.id).map{|performer| {'data-markup'=>performer.white_label.markup}}}, include_blank: true, :required => true, class: 'chosen-select' %>
I get the following error
undefined method `merge' for #<Array:0x000000069705a8>
Performer.find_by_location_id(group.id)
returns an instance but map is method for Array.
The fix depends on your business logic (and APP structure)
You can use Performer.where(location_id: group.id).map... if there are many Performers
I think you try to use this helper wrongly. According to documentation you should pass a collection and group_method. group_method - The name of a method which, when called on a member of collection, returns an array of child objects representing the <option> tags.
You pass an array of objects [{'data-markup' => some_value}, ...] as collection and performers as group_method. Rails try to call {'data-markup' => some_value}.performers and this raises an exception.
You should rewrite a collection the following way:
1. it should be array
2. each item of array should have method performers - which return an array of objects under one group item
I hope it will help you
I can't test but it can work (if Location has_many performers or you can implement your own method according to your business logic)
<%= f.grouped_collection_select :performer_id, Location.order(:name), :performers, :name, :id, :first_name, include_blank: true, :required => true, class: 'chosen-select' %>