ActiveAdmin add filter to form - ruby-on-rails

I have some properties on an active admin model, which can have a LOT of different values, so right now I'm displaying them using checkboxes:
PropertyType.find_each do |pt|
f.input :property_values
f.input :property_values, label: pt.display_name, as: :check_boxes, collection: pt.property_values.order(name: :asc, display_name: :asc).load , multiple: true
end
What I would like to do is to add an input field, in which while i'm writing, it filters the whole checkboxes list, only displaying the ones that matches the input field.
Is there a way to do that?
Thanks.

Yes. Check out chosen_rails gem.
In active_admin it will look something like this:
f.input :property_values,
label: pt.display_name,
as: :check_boxes,
collection: pt.property_values.order(name: :asc, display_name: :asc).load,
input_html: { class: 'chosen-select' },
multiple: true
The only thing I haven't tried it with check_boxes, but with as: :select, and it works perfectly. I think select would be doing the same for you, since you have multiple: true

Related

simple_form add order using label_method

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.

Hover over display related text for simple form association field

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 %>

Modify text displayed in simple_form input when using enum

I'm using simple_form for managing my users. For selecting the user role I use input as: :radio_button.
The collection come from a enum on the user model. How can I modify the text to show something specific like "Super Admin" instead of super_admin?
_form.html.slim
= form.input :role, collection: User.roles, as: :radio_buttons, item_wrapper_class: 'btn btn-default', checked: User.roles[user.role], required: true
user.rb
enum role: [:super_admin, :admin, :generic]
you can use the label_method option with the collection
= form.input :role, collection: User.roles, label_method: lambda {|k| k.humanize}, as: :radio_buttons, item_wrapper_class: 'btn btn-default', checked: User.roles[user.role], required: true
If you want to do something more complex than calling a method on the key, Simple Form has support for translating collection options with I18n - you just have to provide the collection as an array of symbols for the lookup to work.
Here's what worked for me on SimpleForm 3.5.0:
Locale file:
en:
simple_form:
options:
user:
role:
super_admin: 'Super Admin'
admin: 'Admin'
generic: 'Regular Joe'
View:
<%= f.input :role, collection: User.roles.symbolize_keys.keys %>

Ruby on Rails 4 - simple_form multiple select input

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' %>

undefined method `name' for ["Yes", true]:Array

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!

Resources