Skip to content

Instantly share code, notes, and snippets.

@harssh-sparkway
Created March 5, 2014 06:18
Show Gist options
  • Save harssh-sparkway/9362139 to your computer and use it in GitHub Desktop.
Save harssh-sparkway/9362139 to your computer and use it in GitHub Desktop.
http://blog.firmhouse.com/fancy-money-entry-for-your-rails-app-with-autonumeric-and-moneyrails
Creating fancy money entry for your Rails app
This week I was working on a client project where we wanted to implement a nice way of entering an amount of money. We wanted to replace a standard text input field with something like this:
Money entry sample
In the resulting implementation, when the user types the amount in the text box it automatically splits thousands and the decimal point.
Here's how this is implemented in Rails:
1. Vendoring the autoNumeric JS library
autoNumeric is a jQuery library that takes care of formatting the number in the text field while you are typing.
I grabbed the current stable JS from GitHub and saved it as my vendor/assets/javascripts/autoNumeric.js so I could include it in my app/assets/application.js:
//= require jquery
//= require autoNumeric
//= require_tree .
2. Adding the input field
Then in my form, I prepared the input field to be used with autoNumeric:
<% @form_for :product do |f| %>
<p>
<%= f.label :price %>
<%= f.text_field :price, data: { role: 'money', a_sep: '.', a_dec: ',' } %>
</p>
<% end %>
3. Initialize the fields with autoNumeric on page load
For initializing any money field on each page load I created app/assets/javascripts/money_fields.js.coffee with the following:
$ ->
$('input[data-role=money]').autoNumeric('init');
The autoNumeric jQuery plugin will use the data-a-sep and data-a-dec html attributes on the input field to configure the thousands separator character and the decimal separation character.
4. Setting up my model
To save money values on my model I use the money-rails gem. This gem will automatically parse the text input of the field into the correct database value.
Take a look at the MoneyRails README to find out how to set up this gem and how to generate your database fields.
In my model:
class Product < ActiveRecord::Base
monetize :price_cents
end
And my controller looks like a standard CRUD controller, because monetize will take care of correctly saving the field.
class ProductsController < ActionController::Base
def update
@product = Products.find(params[:id])
if @product.update_attributes(product_attributes)
redirect_to product_url(@product)
else
render :edit
end
end
private
def product_attributes
params.require(:product).permit(:price)
end
end
5. Fixing the form submit problem
I came across one problem that caused wrong prices to be saved to the database when you press "enter" in the input field too early.
This happens when you enter an amount of 2000 in the input field and press enter to submit the form. autoNumeric will correctly convert this into 2.000 while you type but will not add the decimal points until you blur out of the field. This causes an amount of "2.000" to be submitted to your controller which the MoneyRails gem will interpret as the float 2.0 causing you to miss a few thousands of dollars.
To fix this, I added a bit of JavaScript to my app/assets/javascripts/money_rails.js.coffee that updates the autoNumeric value in the input field one last time before submitting the form:
$ ->
money_fields = $('input[data-role=money]')
money_fields.autoNumeric('init');
# Added for fixing the ENTER inside the field problem:
money_fields.keydown (event) ->
if event.keyCode == 13
$(this).autoNumeric('set', $(this).autoNumeric('get'))
6. Finished: pretty money entry fields for your Rails app
That's it! With this implementation you can have pretty fancy money entry fields for all the money amounts in your Rails app.
If you have questions about this post or about the gem and autoNumeric jQuery plugin I used: please let me know in the comments!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment