AmountField
Rails gem/plugin that accepts (amount) values in german or us format like 1.234,56 or 1,234.56“.
Installation Rails 3
Via Bundler:
# path/to/railsapp/Gemfile
gem 'amount_field_rails3', :require => 'amount_field'
$ bundle install
As Gem:
$ gem sources -a http://gemcutter.org/ (you only have to do this once)
$ sudo gem install amount_field_rails3
As plugin:
$ rails plugin install git://github.com/thomasbaustert/amount_field.git
Installation Rails 2.x
As Gem:
$ gem sources -a http://gemcutter.org/ (you only have to do this once)
$ sudo gem install amount_field
As plugin:
$ script/plugin install git://github.com/thomasbaustert/amount_field.git, :branch => 'rails23'
Example
First: Use the helper amount_field
instead of the text_field
helper:
<%= form_for(@product) do |f| %>
<%= f.amount_field :price %>
...
<% end %>
<%= form_for(@product) do |f| %>
<%= amount_field :product, :price %>
...
<% end %>
The helper amount_field_tag
is provided too, but you have to handle the validation on your own:
<%= form_tag(:action => "create", {}) do -%>
<%= amount_field_tag :price, 1234.56 %>
...
Second: Use the validation macro validates_amount_format_of
in your model:
class Product < ActiveRecord::Base
validates_amount_format_of :price
validates_numericality_of :price
validates_presence_of :price
...
end
Note! Make sure you always call validates_amount_format_of
before every other validation macro for the same attribute (e.g. before validates_numericality_of
and validates_presence_of
for price
).
Configuration
The following configuration is supported:
Format Configuration
Definition:
Delimiter = thousand separator (e.g. '.' in 1.234.567)
Separator = separator of value and decimal places (e.g. ',' in 12,56)
Precision = number of decimal places
The default format configuration is defined via Rails I18n and accessable through the key number.amount_field.format
from the file amount_field/locale/(en|de).yml
.
Example:
I18n.locale = :de
I18n.t('number.amount_field.format') # => { :precision => 2, :delimiter => '.', :separator => ',' }
Currently only the locale de
anden
are supported.
If you want to define the default configuration independent from I18n, you can set it as follows:
AmountField::ActiveRecord::Validations.configuration =
{ :precision => 1, :delimiter => ',', :separator => '.' }
An explicitly defined format will overwrite the default configuration for that attribute:
validates_amount_format_of :price, :separator => '.', :delimiter => ',', :precision => 1
# VALID: "1,234.5" (1234.5)
Standard Rails options like :allow_blank
, or :allow_nil
are supported:
validates_amount_format_of :price, :allow_blank => true
CSS class and prefix
By default the input field contains the CSS class amount_field
so you can define a CSS layout for every amount field like:
input.amount_field {
text-align:right;
}
The method prefix and the CSS class can be changed as follows:
AmountField::Configuration.prefix = "my_prefix"
AmountField::Configuration.css_class = "my_class"
That will create the html:
<input name="product[my_prefix_price]" class=" my_class"...
and the appropriate method my_prefix_price=(value)
.
Input
By default delimiter, separator and precision are optional, so “1.234,00”, “1234,00” and “1234” are all valid for the german locale (de) at the same time.
In all other cases the validation will fail and add an error message to the original attribute (e.g. price
). (See Error Messages)
Output
The helper amount_field
uses the Rails helper number_with_precision
internally and passes the plugin format configuration as an argument. A value like 1234.56 is therefore displayed as “1.234,56” for the locale de
and “1,234.56” for the locale en
.
You can explicitly set the format configuration with the option format
:
amount_field(:price, :format => { :separator => '', ... })
And it is possible to pass the value explicitly:
amount_field(:price, :value => ...)
Error Messages
By default the german and english messages are taken from the file amount_field/locale/(en|de).yml
through the key activerecord.errors.messages.invalid_amount_format
.
You can define your own by adding your Yaml file to the load path like:
# environment.rb
I18n.load_path << "#{RAILS_ROOT}/locale/en.yml"
# "#{RAILS_ROOT}/locale/en.yml"
de:
errors:
messages:
invalid_amount_format: "'%{value}' ist ein ungültiges Format (%{format_example})"
The placeholder %{value}
is substituted with the given value (e.g. “1.x”) and %{format_example}
with a valid example of the currently accepted format (e.g. ‘d.ddd,dd’).
How does it work?
Basically the helper amount_field
defines a input field like so:
<input name="product[amount_field_price]" class=" amount_field"...
The validation macro validates_amount_format_of
defines a special setter method amount_field_price=(value)
that accept the value. After successfully format validation the original parameter is converted to a ruby value (e.g. “1.234,56” to 1234.56) and assigned to the original attribute price
. Following validation macros work on the converted value. That’s why it is currently important to call validates_amount_format_of
before every other macro.
Running Tests
You need a database gem_amount_field_test
to run all tests. See test_helper.rb for details.
Credits
-
Michael Schiller (for feedback and ideas)
-
Clements Teichmann (consider option ‘name’ and ‘id’)
Contact
For comments and question feel free to contact me: [email protected]
If you are using the plugin, consider recommending me at workingwithrails.com: workingwithrails.com/person/6131-thomas-baustert
Copyright © 2009 [Thomas Baustert], released under the MIT license