rails3 content_tag with static attributes - ruby-on-rails-3

The following is being properly generated into HTML code
<%= content_tag(:span, (t 'hints.h'), :class => "has-tip", :title => (t 'hints.s') ) %>
But I am trying to generate
<span data-tooltip aria-haspopup="true" class="has-tip" title="title bla bla">translated h</span>
and have found no way to generate these span attributes data-tooltip aria-haspopup="true" They cannot be part of the options hash given one has only a name... and the second one has a dash which impedes from defining it as a symbol :aria-haspopup

I suggest that you use the following:
content_tag(:span, t('hints.h'), :class => 'has-tip', :title => t('hints.s'), :'aria-haspopup' => true, :'data-tooltip' => '')
Note that you can use the dash character in symbols if you enclose them in quotes.
The data attribute you could also specify as nested hash like :data => {:tooltip => ''} instead of :'data-tooltip' => '', use whatever you prefer.
As for the boolean attribute data-tooltip, setting the value to an empty string is as good as omitting it (and your best option with Rails 3 ;)). See also:
http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#boolean-attributes

Related

Rails String Interpolation in Model

I'm trying to string interpolate in a message model.
I want to combine a string 'message' and a select media_url into a :body so I can text a text message that contains both a message and a link concatenated. Any help with the interpolation would be appreciated.
I'm trying to do a before_create to grab two fields and combine them into a 3rd field that's saved as body.
My current result yields:
MESSAGE#{#message.media_url}
message.rb
before_create do
self.body = 'MESSAGE' + '#{#message.media_url}'
end
new.html.erb
<%= f.text_field :body, :value => "body" ,:class => 'form-control ' %>
<%= f.select :media_url, Url.order('name asc').all.collect { |u| [u.name, (u.sanitized_url + u.short_url)] }, { class: 'form-control' } %>
It is suppose to output something like... Message and www.google.com/EdRds which is the value coming from the select box.
Thank you
You got the MESSAGE#{#message.media_url} result, because you're wrapping your #{} in single quotes '', that must be between double quotes.
You could try just interpolating, not concatenating:
before_create do
# Not an instance variable, the media_url attribute from the object itself
self.body = "MESSAGE #{self.media_url}"
end
Because '#{#message.media_url}' won't work as a interpolation, that must be with double quotes "", and 'MESSAGE' + is concatenating the #message.media_url value, so you could wrap all in double quotes and your variable value in {}.

Selected option not working for select

I have this select which works fine, but default the select is empty and doesn't show the selected value (which is filled correctly):
<%= f.select(:relationgroup, options_for_select(#relationgroups), { :selected => #relation.relationgroup, :include_blank => true}) %>
Any idea why? Thanks!
Try it that way:
<%= f.select(
:relationgroup,
options_for_select(#relationgroups, #relation.relationgroup),
:include_blank => true
) %>
Not sure, but maybe it'll work better.
Anyway, assuming Relationgroup is some model with id and name (or any other attribute that you want to be visible in select options) attributes, and you're using default relationgroup_id foreign key in your model you'd better construct your select like that:
<% f.select(
:relationgroup_id,
options_from_collection_for_select(#relationgroups, :id, :name),
:include_blank => true
) %>
It'll choose selected value based on object.relationgroup_id where object is the model you're building form for. See docs for more information.

How to populate a rails simple_form select box using an index?

hopefully this isn't too complicated..
So I have a model with LOTS of attributes, which I've decided to store as indexes in the database which refer to an constant at the model:
class Profile < ActiveRecord::Base
STATUS_CHOICES = %w( single relationship married divorced complicated open )
etc...
In my form, I'm doing this right now:
= f.simple_fields_for :profile do |p|
= dp.input :relationship_status, :required => true, :collection => Datingprofile::STATUS_CHOICES
This displays the collection very well, but of course, the value needs to be set from the index coming through from the model. How would I set the values on the collection to correspond to the correct index of the STATUS_CHOICES array?
Update: Going to re-architect this to make the enum-ed attribs actual AD objects
model
some sort of constant hash:
HASH_NAME = {
0 => "Choose:",
1 => "On-Campus Recruiting - CSO",·
2 => "CSO Staff Referral",
3 => "Faculty Contact",·
4 => "Career Day",·
5 => "CSO Summer Job Listing",·
6 => "Alumni Contact",·
7 => "Personal Contact",·
8 => "Other"·
}
-- view
<%= f.input :some_field, :collection => Model::HASH_NAME.sort.map {|k,v| [v,k]} %>
This would output nice select with select-value as hash key and select-name as hash value, such as:
<select id="form_application_job_source" class="select required" name="form_application[job_source]">
<option value="0">Choose:</option>
<option value="1">On-Campus Recruiting - CSO</option>
<option value="2">CSO Staff Referral</option>
<option value="3">Faculty Contact</option>
<option value="4">Career Day</option>
<option value="5">CSO Summer Job Listing</option>
<option value="6">Alumni Contact</option>
<option selected="selected" value="7">Personal Contact</option>
<option value="8">Other</option>
</select>
Now, if you select say 'On-Campus Recruiting - CSO' from the dropdown, the value that would be stored is : 1
To show it in the view as 'On-Campus Recruiting - CSO' you would have to create a small return function like so in the model itself :
def return_paper_type
HASH_NAME[id]
end
In the view, it would be like this : <%= #instancevariable.return_paper_type %>
One way to quickly solve this would be to make the collection the enumerated indices for the option element values, then use the STATUS_CHOICES array to get the labels using :label_method.
= f.simple_fields_for :profile do |p|
= dp.input :relationship_status, :required => true, :collection => 0..Datingprofile::STATUS_CHOICES.length, :label_method => lambda { |i| Datingprofile::STATUS_CHOICES[i] }
References:
https://github.com/plataformatec/simple_form#collections
https://github.com/plataformatec/simple_form/blob/master/test/inputs/collection_select_input_test.rb#L141
Decided to implement this constants of hashes instead of arrays, which affords the simplicity of one model without the complexity of dealing with indexes..I'll store the hash keys and use the values only in the view.
Whee!!
Add this line to your application's Gemfile:
gem 'enum_help'
And then execute:
$ bundle
In model
class Profile < ActiveRecord::Base
enum relationship_status:{single: 0,relationship:1, married:2, divorced:3, complicated:4, open:5}
etc...
In _form.html.erb using simple_form:
<%= f.input :relationship_status %>
For more information: https://github.com/zmbacker/enum_help

Rails 3/3.1 and I18n: Validation hits when switching between languages

The database is seeded with values in english language and format, e.g., :hourlyrate => 20.90. On first start (language is english by default), the input form displays the content of the field correctly. I can modify and save, no problem.
If I switch to german, the number is displayed correctly as 20,90. If I edit anything on this form, I can not save again, as the validation catches the number as not being valid.
My question is, do I have to perform corrections in my controller before saving, or did I miss some built-in function of Rails?
Relevant parts of the code
Helper:
def my_number_with_precision(value)
if value
# value
number_with_precision(value, :precision => 2)
end
end
Validation:
validates :hourlyrate, :numericality => { :greater_or_equal_than => 0, :message => " is an invalid number or below zero" }
Form:
<div class="input">
<%= f.text_field :hourlyrate, :value => my_number_with_precision(f.object.hourlyrate) %>
</div>
Gemfile
gem 'rails-i18n'
I came up with one of the following solutions - language specific code:
def parse_i18n(value)
if I18n.locale = 'de'
value.gsub(',', '.')
else
value
end
end
def parse_i18n(value)
value.gsub(I18n.t("number.currency.format.unit"),'').
gsub(I18n.t("number.currency.format.delimiter"), '').
gsub(I18n.t("number.currency.format.separator"), '.')
end

Rails select_tag - Setting include_blank and selecting a default value

select_tag :country_id, options_from_collection_for_select(Country.order('priority desc, name asc'), "id", "name"), { :prompt => 'Select a country', :include_blank => 'None' } %>
Does as expected, except :include_blank => 'None'. Renders an blank option. Like such:
<option value=""></option>
Second, with the select_tag. How do I specify a default value. For example, if I need the select box to select a specific country. I tried adding :selected => Country.first to no avail:
<%= select_tag :country_id, options_from_collection_for_select(Country.order('priority desc, name asc'), "id", "name"), { :prompt => 'Select` a country', :include_blank => 'None', :selected => Country.first } %>
Above always selects "Select a country".
Why?
Blank Value
I don't think this is getting enough attention on other posts:
include_blank on a select_tag does not respect the string passed to it. It only interprets it as a true/false value.
In order to set a blank value for select_tag with a specific string, you need to use prompt.
Selected Value
Because select_tag does not belong to a object, the way select does, you need to specify the selected value as part of the options. pass the selected value into the options param of the select_tag.
In your case, you are using options_from_collection_for_select to help generate those options. This method takes a fourth parameter that specifies which option should be selected.
options_from_collection_for_select(
Country.order('priority desc, name asc'),
:id,
:name,
Country.find_by_name('Canada')
)