Using Ruby formhelper,
I want the user to see a popup like "fill this out" when they try to submit the form with any empty fields or unselected selects.
To require a text field, this works:
<%= f.text_field :name, :required => "required" %>
To require a select, I'm trying this but it doesn't work:
<%= f.collection_select :metric, Metric.all, :id, :name, :prompt => true, :required => "required" %>
The select is there and its options are populated correctly in the dropdown. But the user should see a popup if they try to submit without selecting another option besides the default "please select" - it never appears.
You need to use Ruby's select tag combined with Ruby's options_from_collection_for_select. You can set your prompt to true or add a custom prompt and required must be in curly braces and its value set to true. For example:
<%= select('trophy','metric', options_from_collection_for_select(Metric.find(:all), :id, :name),{:prompt => 'Select Metric'},{:required => true})%>
Where:
-trophy is the name of an instance variable or a model object
-metric is is the attribute of that instance variable. This is typically a field/column of the table whose data you're displaying.
-:id is the key
-:name is the result
Related
I am trying to make sense out of the instructions in this sheet:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
My objective is to make the select menu wider than the default width.
I have this form input:
<%= f.input :trl, label: false do %>
<%= f.select :trl_id, Trl.all.map { |t| [t.try(:title), t.try(:id)] },
include_blank: false,
prompt: 'Select one',
input_html: { "width: 200px" }
%>
<% end %>
At the moment, the default width html for the select drop down is super tiny. I'm trying to get the select to accept a html attribute for width.
I have tried about 50 different permutations of the above. I can't find a way that works.
From the instructions in simple form, I'm directed to the instructions in the above link. Those tell me that the structure of the input form field should follow this format:
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
From what I can decipher, I think I need as many comma separated fields as are in this example. So that's 7 in total. That's an assumption because I can't tell if you just skip the ones that I don't want to use or do something else to indicate that there is no entry for that particular field. Following that assumption, I have:
<%= f.input :trl, label: false do %>
<%= f.collection_select(:trl_id, Trl.all.map { |t| [t.try(:title), t.try(:id)] },
include_blank: false,
prompt: 'Select one',
html_options = { width: 200px })
%>
<% end %>
This gives me an error that says:
syntax error, unexpected tIDENTIFIER, expecting '}'
html_options: { width: 200px })
^
I can't find an english language translation of what tIDENTIFIER is or means. Most stack overflow questions referencing this term generally indicate that something is wrong with the syntax.
I'm struggling because I can't understand the apidock instructions in the first place. Do I need to add some more blank fields along the way? If I do, do I just write two commas in a row to indicate a blank field?
There are 7 fields in the api dock example. I think my attempts are missing content for value method and text method. I don't know how to indicate to rails that I don't have any content for them. None of the examples in the API dock indicate blank fields, so I am thinking that less than 7 fields should be acceptable.
I'm also not sure where else to search for the definition of tIDENTIFIER. There may be a clue in that term that I can't access because I can't find the meaning of the term.
Can anyone help?
Late response, but see:
https://api.rubyonrails.org/v7.0.2.3/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select
and
How do I set the HTML options for collection_select in Rails?
Essentially, the collection select definition looks like
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
as you rightly mentioned in your question, therefore try to apply your pre-defined css classes within the html_options curly braces. If you have nothing to declare for the options {} that come before the html_options (e.g disabled options), leave it empty, e.g.
<%= form.collection_select :driver_id, Driver.order(:full_name), :id, :full_name, {}, {class: "driver_name_css"} %>
I believe your code would look like:
<%= form.collection_select :driver_id, Driver.order(:full_name), :id, :full_name, {}, {style: "width: 200px"} %>
or
<%= form.collection_select :driver_id, Driver.order(:full_name), :id, :full_name, {}, {class: "pre-defined-css-class-with-desired-width"} %>
I want to add a class for the select tag.Like this.
<select class="phone_no">
I want the ruby equivalent of the above HTML line of code.
<%= select_tag(:id, '<option value="1">Lisbon</option>.') %>
Thanks in advance.
Try this:
<%= select_tag(:id, '<option value="1">Lisbon</option>.',{}, { :class
=> 'phone_no' } ) %>
select helper takes two options hashes:,
(1) one for select - in this case {}
(2) and the second for html options - in this case class
Signature:
select_tag(name, option_tags = nil, options = {}) public
(1) Select options available:
:multiple - If set to true the selection will allow multiple choices.
:disabled - If set to true, the user will not be able to use this input.
:include_blank - If set to true, an empty option will be create
:prompt - Create a prompt option with blank value and the text asking user to select something
(2) Any other key creates standard HTML attributes for the tag
more info here
According the documentation in the select_tag, you shell pass class key-value pair via third option, i.e. shell do as follows. Also you may use html_safe method to pass a proper html as the second argument:
<%= select_tag( :id, <option value="1">Lisbon</option>.'.html_safe, :class => "phone_no" ) %>
I have an HTML form in Rails. Sometimes when the user submit data, my server will reject it because the data is not appropriate (say, the user types a non-number in a field where there's supposed to be only numbers.)
<%= form_tag "myproject/win", :id => "win_form" do -%>
...
<label>
Year
<%= text_field_tag "year", '', :size => 20 %>
</label>
...
<%= submit_tag "Go!" %>
<% end -%>
In that case, my controller returns an error message
#notice = "Year must be a number"
return render action: "new"
But all the data that the user typed in disappears, and the user has to restart with a blank form. Is there a way to keep that data for the user?
That's fine if you don't have a data store behind this, but you can still leverage ActiveModel to create an object that you can use to help build forms (or use the reform gem). If you really don't want to do that, despite the additional capabilities it affords you, you can just use what you have now, but pay attention to the arguments:
From http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-text_field_tag:
text_field_tag(name, value = nil, options = {})
Creates a standard text field; use these text fields to input smaller chunks of text like a username or a search query.
Your code:
text_field_tag "year", '', :size => 20
So you're passing in '' as the value, and asking us why the value is ''. Perhaps what you really want is this:
text_field_tag "year", params[:year], :size => 20
i'm having a bit of trouble with adding a certain feature. i'm working on a buy/sell site and i want to be able to compare posts. here's what i have so far:
in the posts view:
<%= button_to "Add to Compare", :action => "addCompare" %>
in the corresponding controller:
##a = Array.new()
def addCompare
##a << Post.id
end
so, all i want to do is add the post's id to the array ##a. when i test this, i click on the "Add to Compare" button and I'm welcomed with this:
Template is missing
Missing template posts/addCompare with {:locale=>[:en, :en], :formats=>[:html], :handlers=>[:rxml, :rjs, :builder, :rhtml, :erb]} in view paths "/home/mja32/470repo/traders/app/views", "/var/lib/gems/1.8/gems/devise-1.4.2/app/views"
So I guess it's trying to redirect to a view. How do I prevent it from doing this? All I want this button to do is to add the post's id to the array and nothing more.
Thanks in advance,
Matt
First of all, storing persistent data in a controller's class variable isn't going to work the way you want it to. There's no guarantee that ##a will be the same array on your next addCompare call; for example, your next addCompare call could be handled by a different process. Also, what happens if two different clients call addCompare? Do you really want to mix their data together in one pile? Probably not. Your first task is to replace ##a with a real per-user persistent store.
If you want to return nothing at all from your controller, just do this at the end of your controller method:
render :nothing => true, :status => :ok
That will tell Rails that something has already been rendered so it doesn't need to try the default rendering action (which is to render the posts/addCompare view) and returns nothing more than a 200 status code to the client.
Once that's in place, you'll probably want to AJAXify your button with :remote => true:
:remote - If set to true, will allow the Unobtrusive JavaScript drivers to control the submit behaviour. By default this behaviour is an ajax submit.
So this:
<%= button_to "Add to Compare", { :action => "addCompare" }, { :remote => true } %>
Note that button_to looks like this:
button_to(name, options = {}, html_options = {})
and that :action is for options but :remote is for html_options so you have to explicitly set up the hashes with {}; you could just wrap the options in braces:
<%= button_to "Add to Compare", { :action => "addCompare" }, :remote => true %>
but I prefer the consistency of wrapping them both by hand.
It's obvious from the documentation (and google) how to generate a link with a segment e.g. podcast/5#comments. You just pass a value for :anchor to link_to.
My concern is about the much simpler task of generating the <a name="comments">Comments</a> tag i.e. the destination of the first link.
I've tried the following, and although they seemed to work, the markup was not what I expected:
link_to "Comments", :name => "comments"
link_to "Comments", :anchor => "comments"
I think I'm missing something obvious. Thanks.
You are getting confused by Ruby's syntactic sugar (which Rails uses profusely). Let me explain this briefly before answering your question.
When a ruby function takes a single parameter that is a hash:
def foo(options)
#options is a hash with parameters inside
end
You can 'forget' to put the parenthesis/brackets, and call it like this:
foo :param => value, :param2 => value
Ruby will fill out the blanks and understand that what you are trying to accomplish is this:
foo({:param => value, :param2 => value})
Now, to your question: link_to takes two optional hashes - one is called options and the other html_options. You can imagine it defined like this (this is an approximation, it is much more complex)
def link_to(name, options, html_options)
...
end
Now, if you invoke it this way:
link_to 'Comments', :name => 'Comments'
Ruby will get a little confused. It will try to "fill out the blanks" for you, but incorrectly:
link_to('Comments', {:name => 'Comments'}, {}) # incorrect
It will think that name => 'Comments' part belongs to options, not to html_options!
You have to help ruby by filling up the blanks yourself. Put all the parenthesis in place and it will behave as expected:
link_to('Comments', {}, {:name => 'Comments'}) # correct
You can actually remove the last set of brackets if you want:
link_to("Comments", {}, :name => "comments") # also correct
In order to use html_options, you must leave the first set of brackets, though. For example, you will need to do this for a link with confirmation message and name:
link_to("Comments", {:confirm => 'Sure?'}, :name => "comments")
Other rails helpers have a similar construction (i.e. form_for, collection_select) so you should learn this technique. In doubt, just add all the parenthesis.
If you want to go through rails, I suggest content_tag (docs).
Example:
content_tag(:a, 'Comments', :name => 'comments')
<%= link_to('new button', action: 'login' , class: "text-center") %>
created an anchor tag for login.html i.g
new button
and for
new button
use
<%= link_to('new button', controller: 'admin',
action: 'login' , class: "text-center") %>