In my Ruby on Rails application I have some form that needs inputs to select month and year. I do this with built in Rails select_date input:
= select_date #date, :order => [ :month, :year], :discard_day => true
But now I want to know is there any way to the same easy with simple_form?
Obviously an old question but the answer is YES, you absolutely can do the same with simple_form. Posted for others looking for this answer.
You'll pass date as the input type and then rather like the select_date form_for input helper, you'll pass discard_day
So it might look like this:
= f.input :your_date_field, as: :date, discard_day: true
Hello read a this documentation
1.4 Other Helpers of Interest
Other form controls worth mentioning are textareas, password fields, hidden fields, search fields, telephone fields, date fields, time fields, color fields, datetime fields, datetime-local fields, month fields, week fields, URL fields, email fields, number fields and range fields:
<%= text_area_tag(:message, "Hi, nice site", size: "24x6") %>
<%= password_field_tag(:password) %>
<%= hidden_field_tag(:parent_id, "5") %>
<%= search_field(:user, :name) %>
<%= telephone_field(:user, :phone) %>
<%= date_field(:user, :born_on) %>
<%= datetime_field(:user, :meeting_time) %>
<%= datetime_local_field(:user, :graduation_day) %>
<%= month_field(:user, :birthday_month) %>
<%= week_field(:user, :birthday_week) %>
<%= url_field(:user, :homepage) %>
<%= email_field(:user, :address) %>
<%= color_field(:user, :favorite_color) %>
<%= time_field(:task, :started_at) %>
<%= number_field(:product, :price, in: 1.0..20.0, step: 0.5) %>
<%= range_field(:product, :discount, in: 1..100) %>
http://guides.rubyonrails.org/form_helpers.html
and more example examples here:
http://apidock.com/rails/ActionView/Helpers/DateHelper/date_select
Related
I have a field called delivery_day which is of type string in delivery_preference model.
In form, I want to provide 7 checkboxes for each day like Sunday,Monday,etc., and later want to concat.
For example if a user checks Sunday and Friday, I want to concat & store it as "Sunday,Friday" in delivery_day field.
Thanks in Advance!!
You can design your form like this -
<%= form_for #delivery_preference do |f|%>
<%= f.check_box :delivery_day, {multiple: true}, "Sunday" %>Sunday
<%= f.check_box :delivery_day, {multiple: true}, "Monday" %> Monday
<%= f.submit "Add" %>
<% end %>
After submitting the form, you can get your check box selections in your controller as follows:
def your_action_name
params[:delivery_preference][:delivery_day].delete("0")
DeliveryPreference.create(delivery_day: params[:delivery_preference][:delivery_day].join(","))
end
Hope it helps!
Might have better solutions, but when I encountered similar problem, I used check_box_tag to solve it.
<%= check_box_tag "delivery_preference[delivery_day][0]", 'monday' %>Monday
<%= check_box_tag "delivery_preference[delivery_day][1]", 'tuesday' %>Tuesday
<%= check_box_tag "delivery_preference[delivery_day][2]", 'wednesday' %>Wednesday
<%= check_box_tag "delivery_preference[delivery_day][3]", 'thursday' %>Thursday
<%= check_box_tag "delivery_preference[delivery_day][4]", 'friday' %>Friday
<%= check_box_tag "delivery_preference[delivery_day][5]", 'saturday' %>Saturday
<%= check_box_tag "delivery_preference[delivery_day][6]", 'sunday' %>Sunday
then you will receive an array like { deliver_day: ['monday', 'tuesday'] } in you controller. You can choose to concat in your controller, and then save, or you can move the logic to your model.
in your controller, you strong parameter should be like
params.require(:delivery_preference).permit(.., :deliver_day => [])
to permit the array.
I do not have enough reputation to leave a brief comment yet. However, does your migration have delivery_day have something similar to t.boolean :public, default: true_or_false_here within it?
If so, within the form, you could have something like:
...
<div class="form-group">
<%= f.label :public, class: 'checkbox' do %>
<%= f.check_box :public %> Monday
<% end %>
</div>
<div class="form-group">
<%= f.label :public, class: 'checkbox' do %>
<%= f.check_box :public %> Tuesday
<% end %>
</div>
...
After above, you could designate (via boolean logic) your "concat & store it as "Sunday,Friday"
I have what I hope to be a simple question. I need to display the value for an attribute on the Edit page, while keeping the input field for the same attribute. How might this be accomplished?
Well generally you can just use the original object, like you'll have an #foo that you'll have used in your form_for statement, so you can just use that directly: = #foo.the_attribute
If you're within a partial, or elsewhere where you have only the form builder instance, then you can refer to the underlying object with the .object method, eg.:
= form_for #foo do |f|
# in here, f.object == #foo
In my case, I'm working with accepts_nested_attributes_for in two models. Event accept nested objects from Speaker. And Speaker has a perfil_id attribute which could be ['Maker', 'Developer', 'Entrepreneur', ...].
The Speaker's form is a partial rendered from the principal form, Event's form:
<%= form_for(event) do |f| %>
<%= f.text_field :title %>
<%= f.label :title, 'Event name' %>
<%= f.fields_for :speakers do |builder| %>
<%= render 'events/partials/speaker_fields', f: builder %>
<% end %>
<%= f.submit %>
<% end %>
Partial
<%= builder.number_field :name %>
<%= builder.label :name %>
<% options = options_from_collection_for_select(#profiles, 'id', 'name', f.object.member_profile_id ) %>
<%= select_tag "event[speakers_attributes][profile_id]", options, prompt: 'Select a Profile' %>
When editing Event's Speakers I wanted a select_tag to select the profile name for the actual Speaker.
I could not use an input field for this. So I need to get the correct values from the builder object and I get what I need by doing this:
f.object.profile_id
Passing it as a fourth param to the select options I get this working:
<% options = options_from_collection_for_select(#profiles, 'id', 'name', f.object.profile_id ) %>
I hope it could be useful for you too!
I am trying to link multiple rails models in my app. I am trying to let users create reviews on a product using a form. I am trying to use the rails DRY principle.
I first made a bat table with bat name, model year, and an image. Then I created a manufacturer table which only lists the names of the manufacturers of bats. My bats model belongs_to :manufacturer and my manufacturer model has_many :bats.
Instead of creating multiple tables using manufacturer, (listing the name of the manufacturer at least 3 times for each bat) how can I link my two models together?
My form is submitted to the review model. In the form I already have <%= f.collection_select :bat_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>, which lists all of the possible manufacturers in a drop down menu. HOWEVER, nothing is submitted to the :bat_id parameter in the review form when submitted.
--One guess is to have the manufacturer_id integer stored in the bat model as an integer under the column manufacturer_id(Note: already done this, but I don't know how to submit that in a form?)
--Another guess is to have the bat model inherit from the manufacturer model
Any help is greatly appreciated
My full form:
<%= form_for(#review) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field" align= "center">
<h3>Select bat</h3>
<%= f.collection_select :bat_id, Manufacturer.all, :id, :manufacturer, include_blank: true %>
<h3>What do you like about this bat?</h3>
<%= f.text_area :pros, placeholder: "Enter what you like..." %>
<h3>What do you not like about this bat?</h3>
<%= f.text_area :cons, placeholder: "Enter what you don't like..." %></br>
</div>
<div align="center">
<%= f.submit "Add Review", class: "btn btn-large btn-info" %>
</div>
<% end %>
according to the documentation
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
the params in the collection_select is supposed to be:
f.collection_select(:post, :author_id, Author.all, :id,
:name_with_initial, prompt: true)
where post is the Model,author_id is the attribute
or you could try using:
=f.select( :bat_id, options_from_collection_for_select(#manufacturers,"id","manufacturer",
f.object. bat_id),{})
and put the
#manufacturers = Manufacturer.all
inside the controller
i am new to rails and try to do the following:
I would like, because i use Bootstrap, to have a partial for a input field, with it's label and a little icon i called symbol in this case.
Here is my view:
<%= form_for(#user, :class => "form-horizontal" ) do |f| %>
<fieldset>
<%= render 'shared/text_field', function: f, tag: :name, symbol: '<i class="icon-user"></i>' %>
<%= render 'shared/text_field', function: f, tag: :email, symbol: "#" %>
<%= render 'shared/password_field', function: f, tag: :password, symbol: '<i class="icon-log"></i>' %>
<%= render 'shared/password_field', function: f, tag: :password_confirmation, alt: "Passwort wiederholen", symbol: '<i class="icon-log"></i>' %>
<!-- SUBMIT -->
<%= f.submit "Anmeldung", :class => "btn btn-primary" %>
</fieldset>
<% end %>
Here a subpartial for normal input fields:
<%= render 'shared/bootstrap/input_field' %>
<% content_for :label do %>
<%= function.label tag, :class => "control-label", :for => "prependedInput" %>
<% end %>
<%content_for :symbol do %>
<%= raw(symbol) %>
<% end %>
<% content_for :field do %>
<%= function.text_field tag, :class => "input-xlarge", :id => "prependedInput", :size => "6" %>
<% end %>
(there is also a subpartial for password fields, basicly exchanging function.text_field with function.input_field)
And here is the input_field which is rendered:
<div class="control-group">
<%= yield :label %>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><%= yield :symbol %> </span>
<%= yield :field %>
</div>
</div>
</div>
So my question is: how can i solve this Problem in a nice and easy way (this things happend while refactoring and it got even worse then better) and how can i make it work, because by now something like this happens: http://pastebin.com/bNsgT9AR so yield puts with each content_for the content and the content before into the place (except the last one)
It would be great to hear nice solutions from you, there has to be a so much nicer way as almost always in Rails.
Greetings form Germany ;)
As the author of The Rails View, I agree with Ben Taitelbaum's post on this and say that Formtastic is totally a great option for this kind of complexity.
With regards to the code you posted, as developers we want to avoid that kind of view writing across the board, as it ends up an unmanageable mess. There's too many files involved in editing a form, and at some point, some other dev will come in and overwrite our shared partial, not knowing where else it was used, to change the way a different form behaves. Any benefit of code reuse that we can get out of this kind of abstraction is completely obliterated by the potential for it to go sour very quickly with mutliple developers.
While Formtastic is great, I've also been using SimpleForm a lot in my recent apps, especially when I don't need the full power of Formtastic.
SimpleForm will handle your label, and it also supports i18n as well. With this it would be:
<%= simple_form_for #user do |f| %>
<%= f.input :name, :input_html => { :class => 'user-icon' } %>
<%= f.input :email %>
<%= f.input :password, :as => :password, :input_html => { :class => 'log-icon' } %>
<%= f.input :password_confirmation, :as => :password, :input_html => { :class => 'log-icon' } %>
<%= f.button :submit %>
<% end %>
Then in your I18n file, you can have:
en:
simple_form:
labels:
user:
username: 'User name'
password: 'Password'
password_confirmation: 'Password confirmation'
de:
simple_form:
labels:
user:
username: 'Benutzername'
password: 'Passwort'
password_confirmation: 'Passwort wiederholen'
And more as you need it. You can define your hints and placeholders in the i18n file as well.
Also, think about adding the icon as a CSS pseudo class :after, and do so for each class that you need to add in the code)
input.user-icon:after {
// image as background, positioned properly, etc etc
}
input.log-icon:after {
// image as background, positioned properly, etc etc
}
And that way, you can remove this kind of stuff from your ERB/HTML and put it where it belongs: In the CSS (presentation layer).
There's a great section on forms in The Rails View, where they recommend using FormBuilders for this type of thing (they also discuss formtastic, which is worth checking out).
The biggest lesson I got out of this book (and I can't recommend it enough!) is that it's important to keep views as simple as possible, since they tend to be the least fun part of a rails app to debug, especially as the app grows large. So from this perspective, I would want the view to be nice and simple, something like:
<%= semantic_form_for(#user) do |f| %>
<%= f.inputs do %>
<%= f.input :name, class: 'icon-user' %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
<% end %>
<%= f.buttons %>
<% end %>
Start with a nice readable view as the goal, and add the necessary helpers and formbuilders as needed for custom field types.
I'd recommend using I18n for setting the submit button text to be "Anmeldung" instead of hardcoding that as well.
I haven't used it, but you might want to check out formtastic-bootstrap for getting the integration you want..
I feel that's a bit too much generalization overhead for a simple input field.
Have you considered simply creating one shared input field partial and just passing in the field name (you named it tag) and the type of field (text_field or password_field) as parameters? I can see that your approach might be more general, but if you just need those two options for now, keep it as simple as possible.
Addition in reply to comment:
You can simply pass parameters to your partial like so:
<%= render 'shared/error_messages', object: f.object %>
And then use the the variables in your partial. in your case you could
<%= render 'shared/bootstrap/input_field', function: f, tag: :name, input_field_type: :text_field %>
and then in _input_field.html.erb
<div class="control-group">
<%= function.label tag, :class => "control-label", :for => "prependedInput" %>
...
I am a little confused.
Despite all questions around this theme here, I can't find the right solution.
What I want to do is to simply add check-boxes to my index filter form.
I am using Metasearch gem and here is my current code :
<form class="filter_form">
<%= form_for #search do |f| %>
<%= f.collection_select :categories_id_equals, Category.all, :id, :name, :include_blank => true, :prompt => "All categories" %>
<%= f.collection_select :location_id_equals, Location.all, :id, :name, :include_blank => true, :prompt => "All locations" %>
<ul>
<b> Type </b>
<% Type.all.each do |type|%>
<li>
<%= check_box_tag :types_id_equals, type.id %>
<%=h type.name %>
</li>
<% end %>
</ul>
<%= submit_tag "Find Now", :class => "find" %>
<% end %>
All works fine, except the checkboxes.
I don't have much experience in rails, so I don't really see what I am doing wrong and what could be the most convenient and simplest way.
Update
.....................
More explanation - I have a model Trips, which has HABTM relationship with two models (
Categories, Types) and belongs to Location.
I want to be able to filter Trips on it's index by categories (f.collection select) ,location (f.collection select) and types (checkboxes).
After checking types and submitting - nothing changes, no filtering is done!
<%= check_box_tag "type_ids[]", type.id %>
Will do it for you. The selected ids will be transfered as a string seperated by commatas. You can find them in params[:type_ids] but you have to deal with them manually! Rails is not a magican, its a framework.
Here's how I handled it.
<% #sub_categories.each do |cat| %>
<h2><%= cat.name %> <%= check_box_tag "q[product_category_id_in][]", cat.id %></h2>
<% end %>
Basically just q is whatever your query param is, then right after that in brackets sub in your meta_search method. I used whatever_foreign_key_in since I want to be able to add more than one id to the array to search on. Then add empty brackets after it so rails handles the post params correctly.