How to disable specific value in dropdown select with simple_form? - ruby-on-rails

I am using simple_form in my rails application. I want to disable a particular value in drop-down.
Here is part of the code
= simple_form_for(#organization,url: admin_organization_path) do |f|
= f.input :hospital_name, input_html: { class: "form-control"}
= f.input :parent, collection: #organizations, input_html: { class: "form-control", id: "chosen-select-speciality"}
I tried using :disabled => #organizations.first but i was failed.
Is there any other method to use.Kindly help me. thanks.

Simpleform builder for select box uses value of the each option to compare with value of disabled attribute, so you just simple have to use id of the organization to disable desired option:
= simple_form_for(#organization,url: admin_organization_path) do |f|
= f.input :hospital_name, input_html: { class: "form-control"}
= f.input :parent, collection: #organizations, input_html: { class: "form-control", id: "chosen-select-speciality"}, disabled: #organizations.first.id
If you want to disable several options for selectbox, you can manually build options list inline or using helper and use it as attribute for input:
= f.input :parent, collection: #organizations.map{|o| [o.id, o.name, {disabled: o.id.in?([1,21,10])}]}, input_html: { class: "form-control", id: "chosen-select-speciality"}

By using JavaScript you can easily disable a particular value in drop-down as:
$(/* option selector */).prop('disabled', true);
See it in action

To disable the particular value use below code:
<%= f.input :parent,
collection: #organizations,
input_html: { class: "form-control",
id: "chosen-select-speciality"},
disabled: #organizations.first.id %>
If you want to disable multiple options, put below code to fetch the list of unused organizations in your helper file:
#unused_org_list = Organization.where("Condition to fetch unused organizations")
Then, in your view file:
<%= f.input :parent,
collection: #organizations,
input_html: { class: "form-control",
id: "chosen-select-speciality"},
disabled: #unused_org_list&.map {|u| u.id} %>
NOTE: Make sure to pass ids into disabled option as it expect id or [array of ids]

Related

Getting value of an object in collection select

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

Simple form default value in select box

I'm using simple form, and I have the :selected => 0 so that the select has value 0 from its collection by default. But this is not working, the select box is blank and I need to choose the "0" option manually... I'm in a modal by the way. Any idea?
<%= f.input :price_type, label: "¿Conoces el precio?", collection: ["0","1","2"], :selected => 0 , id: "tag_price_type", html_input: "required", input_html: {class: 'ipt'} %>
Try matching the object types between the collection and the selection. So either:
<%= f.input :price_type, label: "¿Conoces el precio?", collection: [0,1,2], selected: 0 , id: "tag_price_type", html_input: "required", input_html: {class: 'ipt'} %>
or
<%= f.input :price_type, label: "¿Conoces el precio?", collection: ['0','1','2'], selected: '0' , id: "tag_price_type", html_input: "required", input_html: {class: 'ipt'} %>
You have to use quotes, see: How do I set the default selected item in a Rails drop-down menu?
So you should have: :selected => "0"

Simple_form inputs are too long

As always with Ruby on Rails I use simple_form gem to handle forms in more elegant and, well, simple way. But i have this problem, that string inputs are not generated properly. i mean they work as they are supposed to, but they are just extremely long, like totally out of my screen. it isn't normal behaviour is it? should i apply any special css for this? or maybe there is some other solution?
This form i have looks like this:
= simple_form_for #book, url: books_path, method: :post do |f|
= f.input :title, label: false, placeholder: "title"
= f.input :author, label: false, placeholder: "author"
= f.input :isbn, label: false, placeholder: "ISBN"
= f.input :publishing_date, label: false, placeholder: "Publishing date"
= f.input :amount, label: false, placeholder: "Amount"
= f.submit class: "btn btn-success"
Other that this i just put 'gem "simple_form"' to the Gemfile and thats it.
There is a good answer I found from typing simple_form width:
{:maxlength =>2,:style=> 'width: 20px'}%>
from this answer:
Rails Simpleform setting the width of a form input element

Semantic ui with simple_form

tell me how to configure simple_form. I would like to use the checkbox of semantic ui, but when I wrap checkbox in the class, he becomes active, that is, visually it is, but when you click the check box is not activated.
= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f|
.ui.three.column.middle.aligned.relaxed.grid.basic.segment
.column
.column
.column
.ui.form.segment
#marg.field= f.label :email, 'Email'
#marg.field=f.input :email, placeholder: 'Email', autofocus: true, label: false
#marg.field= f.label :password, 'Пароль'
= f.input :password, :required => false, placeholder: 'Пароль', label: false
#marg.ui.toggle.checkbox
= f.input :remember_me, as: :boolean if devise_mapping.rememberable?
#marg= f.button :submit, 'Войти!', class: 'small ui blue submit button'
http://i.imgur.com/C8Wn4K9.png
Please try it
= f.input :remember_me, as: :boolean, boolean_style: :inline
A simpler way to do this is to create a custom simple form wrapper. Here is a blogpost which describes how to add the wrapper: http://pranavsingh.me/semantic-ui-simple-form-wrapper/
The above configuration will automatically add all the essential classes semantic form classes, and also adds wrappers to create proper checkbox fields. Below is an example:
= f.input :published, label: "Published?",
hint: "If you are not ready to go live yet, keep this site unpublished.",
wrapper: :ui_toggle_checkbox
Here's what I had to do (the accepted answer got me on the right track, but didn't fully fix the issue):
In the config/initializers/simple_form.rb file, change
config.boolean_style = :nested
to
config.boolean_style = :inline
This prevents Simple Form from wrapping the input tag in the label tag (essentially inserting a tag between the '.ui .checkbox' div and the input, which breaks Semantic's checkbox functionality).
In the app/assets/javascripts/application.js file:
$('.ui.checkbox').find('input').checkbox();
My form now displays checkboxes correctly and passes the appropriate value when submitted.
Here is another option (to just fix one checkbox) -
In a _form.html.erb partial:
<div class="inline field">
<div class="ui checkbox">
<%= my_form.input :my_input, label: 'My Label', as: :boolean, boolean_style: :inline %>
</div>
</div>
In the application.js file:
$('.ui.checkbox').find('input').checkbox();

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