Related
I am new to ror. How do I give required attribute for an input[not the required label that is provided by ruby]. When I write this,
= form.text_field :title, {html:{required: "required"}}
browser shows this,
< input html="{:required=>"required"}" id="key_date_title"
name="key_date[title]" size="30" type="text">
If you look at text_field helper. It requires 3 arguments: object_name, method and options = {}. You can pass in any standard HTML attributes directly in options argument.
= form.text_field :title, required: true
I have in my .html.erb:
<label for="form_marital_status">Marital Status:</label>
<%= select("form", "marital_status", marital_status_options, {}, { }) %>
Where marital_status_options is defined in my helper as:
def marital_status_options
%w[Select Single Married Common-Law/Partner Divorced Widowed]
end
Is there a way I can define marital_status_options to have a key value pairing for use in the select?
%w[Select Single Married Common-Law/Partner Divorced Widowed]
This is going to make the option value and text for each option the same. Return an array of arrays if you want the option value and text to be different for each option. The first value in each array is the text value for the option; the second is the option value itself.
def marital_status_options
[["Select", ""], ["Single", "single"], ["Married", "married"], ["Common-Law/Partner", "partners"], ["Divorced", "divorced"], ["Widowed", "widowed"]]
end
This is explained clearly in the documentation.
You should also consider not passing the blank "Select" option from your method as there is a way to do this through the select method itself.
# Helper
def marital_status_options
[["Single", "single"], ["Married", "married"], ["Common-Law/Partner", "partners"], ["Divorced", "divorced"], ["Widowed", "widowed"]]
end
# form
<%= select("form", "marital_status", marital_status_options, {:include_blank => "Select"}) %>
I am going through the Rails API docs for collection_select and they are god-awful.
The heading is this:
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
And this is the only sample code they give:
collection_select(:post, :author_id, Author.all, :id, :name_with_initial, :prompt => true)
Can someone explain, using a simple association (say a User has_many Plans, and a Plan belongs to a User), what I want to use in the syntax and why?
Edit 1: Also, it would be awesome if you explained how it works inside a form_helper or a regular form. Imagine you are explaining this to a web developer that understands web development, but is 'relatively new' to Rails. How would you explain it?
collection_select(
:post, # field namespace
:author_id, # field name
# result of these two params will be: <select name="post[author_id]">...
# then you should specify some collection or array of rows.
# It can be Author.where(..).order(..) or something like that.
# In your example it is:
Author.all,
# then you should specify methods for generating options
:id, # this is name of method that will be called for every row, result will be set as key
:name_with_initial, # this is name of method that will be called for every row, result will be set as value
# as a result, every option will be generated by the following rule:
# <option value=#{author.id}>#{author.name_with_initial}</option>
# 'author' is an element in the collection or array
:prompt => true # then you can specify some params. You can find them in the docs.
)
Or your example can be represented as the following code:
<select name="post[author_id]">
<% Author.all.each do |author| %>
<option value="<%= author.id %>"><%= author.name_with_initial %></option>
<% end %>
</select>
This isn't documented in the FormBuilder, but in the FormOptionsHelper
I've spent quite some time on the permutations of the select tags myself.
collection_select builds a select tag from a collection of objects. Keeping this in mind,
object : Name of the object. This is used to generate the name of the tag, and is used to generate the selected value. This can be an actual object, or a symbol - in the latter case, the instance variable of that name is looked for in the binding of the ActionController (that is, :post looks for an instance var called #post in your controller.)
method : Name of the method. This is used to generate the name of the tag.. In other words, the attribute of the object you are trying to get from the select
collection : The collection of objects
value_method : For each object in the collection, this method is used for value
text_method : For each object in the collection, this method is used for display text
Optional Parameters:
options : Options that you can pass. These are documented here, under the heading Options.
html_options : Whatever is passed here, is simply added to the generated html tag. If you want to supply a class, id, or any other attribute, it goes here.
Your association could be written as:
collection_select(:user, :plan_ids, Plan.all, :id, :name, {:prompt => true, :multiple=>true })
With regards to using form_for, again in very simple terms, for all tags that come within the form_for, eg. f.text_field, you dont need to supply the first (object) parameter. This is taken from the form_for syntax.
When I add the 'Required' attribute
to html input fields, Rails pre-pends an asterisk (*) before the label.
Does anyone know how to prevent this?
For some reason Rails transforms this:
<%= f.input :Company, :input_html => {:value => "", :id => "company_name"}, :label => "company name" %>
into this:
<div class="input string required">
<label for="company_name" class="string required">
<abbr title="required">*</abbr> company name</label>
<input type="text" value="" size="50" required="required" name="lead[Company]" id="company_name" class="string required">
</div>
I don't like that it wraps everything in a DIV and adds an ABBR element to the party.
How can I prevent this?
You can just set the required mark to empty value in simple_form's locale file:
en:
simple_form:
required:
text: 'required'
mark: '*'
Or use CSS to hide it.
In config/initializers/simple_form.rb add this line:
config.label_text = lambda { |label, required| "#{label}" }
I'm using Rails 3.1, and I have the following view code in my _form.html.erb for a given model:
<div>
<%= f.label :full_name %><br/>
<%= f.text_field :full_name, :required => true %><br/>
</div>
The label does not show an asterisk if you do it this way. Unless you post code I can't be sure of what your approach is and if my solution would fit said approach.
Updated Answer:
It sounds like you've inherited this code from someone. At any rate, after reading your code sample, you are most definitely using the simple_form gem. Information about that gem can be found here https://github.com/plataformatec/simple_form. To answer your question though, if you change your code the following:
<%= f.input :Company, :input_html => {:value => "", :id => "company_name"}, :label => "company name", :required => false %>
That should turn off the asterisk.
I would add, based on your disgust for the HTML generated from simple_form, it sounds like you should just do away with the gem and re-write your form code using the Rails default form helpers, which can be read about here http://guides.rubyonrails.org/form_helpers.html. Depending on the size of the code base, you might be better off just sucking it up and learning how to use the simple_form gem for the sake of saving time, but if you think you have the time to change it all, go for it.
The simplest way is to hide it with this css:
abbr[title="required"] {
display: none;
}
It isn't rails at all. It's the simple_form gem. So, if you don't want all the wrapping elements don't use simple_form. Use Rails form helpers. It would be more simple than customize something you don't like.
For anyone using Formtastic and having this issue, you can remove the asterisks by editing the config file, which is typically app/config/initializers/formtastic.rb.
Change this line: # Formtastic::SemanticFormBuilder.required_string = "(required)"
to be: Formtastic::SemanticFormBuilder.required_string = ""
More info here.
Code that has helped me solve the asterisk issue:
abbr[title="required"] {
display: none;
}
The chosen answer and the other suggestions asking to change the HTML in locales file dint help me with the latest Simple_form gem.
Aside from the global config suggested in the accepted answer, you can pass required: false as an input option, or defaults: { required: false } to set it for the whole form.
You can remove it from the whole form:
<%= simple_form_for #form, defaults: { required: false } do |f| %>
I found out that if you only want to remove the asterisk(*) behind it then all you have to do is to go to this file file /config/locales/simple_form.en.yml
once again is not a good practice to change your configuration files for gems and something your using for some reason, it always a question of why do you really use simple_form!
But for example I found out about that because there is great things about simple_form we use but nowadays is a better usability practice to have the asterisks on none required fields then required ones.
you can used form_for, and override method def label in config/initializer to add asterisk for mandatory fields as the following:
def label(object_name, method, content_or_options = nil, options = nil, &block)
if content_or_options.is_a?(Hash)
content_or_options.each do |key, val|
options[key] = val
end
content_or_options = method.to_s
end
content_or_options ||= method.to_s
presence_validations = [ActiveModel::Validations::PresenceValidator, ActiveRecord::Validations::PresenceValidator]
class_obj = options[:object].class if options[:object]
class_obj ||= object_name.to_s.camelize.constantize
validations = class_obj.validators_on(method.to_s).map(&:class)
if (presence_validations.map { |pv| validations.include?(pv) }).any?
content_or_options += "*"
end
Tags::Label.new(object_name, method, self, content_or_options, options).render(&block)
end
This method puts asterisk after all mandatory fields, if you used normal form_for, and used validates_presence_of
I have a model that has an attribute that is an Array. What's the proper way for me to populate that attribute from a form submission?
I know having a form input with a field whose name includes brackets creates a hash from the input. Should I just be taking that and stepping through it in the controller to massage it into an array?
Example to make it less abstract:
class Article
serialize :links, Array
end
The links variable takes the form of a an array of URLs, i.e. [["http://www.google.com"], ["http://stackoverflow.com"]]
When I use something like the following in my form, it creates a hash:
<%= hidden_field_tag "article[links][#{url}]", :track, :value => nil %>
The resultant hash looks like this:
"links" => {"http://www.google.com" => "", "http://stackoverflow.com" => ""}
If I don't include the url in the name of the link, additional values clobber each other:
<%= hidden_field_tag "article[links]", :track, :value => url %>
The result looks like this: "links" => "http://stackoverflow.com"
If your html form has input fields with empty square brackets, then they will be turned into an array inside params in the controller.
# Eg multiple input fields all with the same name:
<input type="textbox" name="course[track_codes][]" ...>
# will become the Array
params["course"]["track_codes"]
# with an element for each of the input fields with the same name
Added:
Note that the rails helpers are not setup to do the array trick auto-magically. So you may have to create the name attributes manually. Also, checkboxes have their own issues if using the rails helpers since the checkbox helpers create additional hidden fields to handle the unchecked case.
= simple_form_for #article do |f|
= f.input_field :name, multiple: true
= f.input_field :name, multiple: true
= f.submit
TL;DR version of HTML [] convention:
Array:
<input type="textbox" name="course[track_codes][]", value="a">
<input type="textbox" name="course[track_codes][]", value="b">
<input type="textbox" name="course[track_codes][]", value="c">
Params received:
{ course: { track_codes: ['a', 'b', 'c'] } }
Hash
<input type="textbox" name="course[track_codes][x]", value="a">
<input type="textbox" name="course[track_codes][y]", value="b">
<input type="textbox" name="course[track_codes][z]", value="c">
Params received:
{ course: { track_codes: { x: 'a', y: 'b', z: 'c' } }
I've also found out that if pass your input helper like this you will get an array of courses each one with its own attributes.
# Eg multiple input fields all with the same name:
<input type="textbox" name="course[][track_codes]" ...>
# will become the Array
params["course"]
# where you can get the values of all your attributes like this:
params["course"].each do |course|
course["track_codes"]
end
I just set up a solution using jquery taginput:
http://xoxco.com/projects/code/tagsinput/
I wrote a custom simple_form extension
# for use with: http://xoxco.com/projects/code/tagsinput/
class TagInput < SimpleForm::Inputs::Base
def input
#builder.text_field(attribute_name, input_html_options.merge(value: object.value.join(',')))
end
end
A coffeescrpt snippet:
$('input.tag').tagsInput()
And a tweak to my controller, which sadly has to be slightly specific:
#user = User.find(params[:id])
attrs = params[:user]
if #user.some_field.is_a? Array
attrs[:some_field] = attrs[:some_field].split(',')
end
I had a similar issue, but wanted to let the user input a series of comma separated elements as the value for the array.
My migration uses rails new ability (or is it postrges' new ability?) to have an array as the column type
add_column :articles, :links, :string, array: true, default: []
the form can then take this input
<%= text_field_tag "article[links][]", #article.links %>
and it means the controller can operate pretty smoothly as follows
def create
split_links
Article.create(article_params)
end
private
def split_links
params[:article][:links] = params[:article][:links].first.split(",").map(&:strip)
end
params.require(:article).permit(links: [])
Now the user can input as many links as they like, and the form behaves properly on both create and update. And I can still use the strong params.
For those who use simple form, you may consider this solution. Basically need to set up your own input and use it as :array. Then you would need to handle input in your controller level.
#inside lib/utitilies
class ArrayInput < SimpleForm::Inputs::Base
def input
#builder.text_field(attribute_name, input_html_options.merge!({value: object.premium_keyword.join(',')}))
end
end
#inside view/_form
...
= f.input :premium_keyword, as: :array, label: 'Premium Keyword (case insensitive, comma seperated)'
#inside controller
def update
pkw = params[:restaurant][:premium_keyword]
if pkw.present?
pkw = pkw.split(", ")
params[:restaurant][:premium_keyword] = pkw
end
if #restaurant.update_attributes(params[:restaurant])
redirect_to admin_city_restaurants_path, flash: { success: "You have successfully edited a restaurant"}
else
render :edit
end
end
In your case just change :premium_keyword to the your array field
I had some trouble editing the array after implementing this for my new.html.erb, so I'll drop my solution to that problem here:
Edit a model property of type array with Rails form?