Railsで金額を入力するフォームをリッチにするCoffeeScriptとGemを紹介します。
- 3桁ごとにカンマ
- 漢数字変換
- 右寄せ
- データベースには数値で保存
使い方
テキストフィールドにして、moneyなどの適当なクラス名をつけます
slim
= f.text_field :some_budget, {class: 'money'}
JSでmoneyクラスに対して、キーアップやチェンジのタイミングでmoney_format
関数を適用します
Javascript
$('.money').on 'change', -> $(@).val(money_format($(@).val()))
Gemを使ってPostされてきたカンマ区切りの文字列を数値に変換して保存する宣言をします
model
# ar_strip_commas
# gem install ar_strip_commas
strip_commas_from :some_budget
strip_commas_from
はar_strip_commasのメソッドです
このGemはカンマ区切りの金額を数値に変換してDBに保存してくれます
数値と漢数字をカンマ区切りの金額に変換する実装
こちらをassets/javascripts/の適当な場所に置いておきます。
money_format
というメソッドが使えるようになります。
money_field.coffee
suuji = '〇一二三四五六七八九零壱弐参肆伍陸質捌玖零壹貳參'
keta1 = '十百千拾佰仟十陌阡'
keta2 = '万億兆京垓萬'
arb = '01234567890123456789'
@money_format = (str) ->
number_format(toArb(toHalfWidth(reject_format(str)).replace(/(\d)/g, num2ja)))
@reject_format = (val) ->
str = ''
i = 0
while i < val.length
c = val.charAt(i)
if suuji.search(c) != -1 or keta1.search(c) != -1 or keta2.search(c) != -1 or arb.search(c) != -1
str = str + c
i++
str
@number_format = (val) ->
s = '' + val
if s.length > 3
r = if (r = s.length % 3) == 0 then 3 else r
d = s.substring(r)
s = s.substr(0, r) + d.replace(/(\d{3})/g, ',$1')
s
@toArb = (kanji) ->
b = 0
t = 0
f = false
i = 0
while i < kanji.length
c = kanji.charAt(i)
if (r = suuji.indexOf(c)) != -1
if f == false
b += r % 10
f = true
else
b = b * 10 + r % 10
else if (r = keta1.indexOf(c)) != -1
t += b
d = t % 10
a = (if d == 0 then 1 else d) * 10 ** (r % keta2.length + 1)
t += a - d
b = 0
f = false
else if (r = keta2.indexOf(c)) != -1
t += b
d = t % 10000
a = d * 10000 ** (r % keta2.length + 1)
t += a - d
b = 0
f = false
else
return kanji
i++
t + b
@conv = ->
reg = new RegExp('[' + suuji + keta1 + '][' + suuji + keta1 + keta2 + ']*', 'g')
src = document.F1.S1.value
document.F1.S2.value = src.replace(reg, ($0) ->
r = toArb($0)
if document.F1.C1.checked
r = number_format(r)
r
)
return
@num2ja = (num) ->
`var i`
`var suuji`
sign =
'+': ''
'-': '−'
zero = '零'
point = '点'
zero2nine = [
'〇'
'一'
'二'
'三'
'四'
'五'
'六'
'七'
'八'
'九'
]
ten2thou = [
''
'十'
'百'
'千'
]
suffices = [
''
'万'
'億'
'兆'
'京'
'垓'
'禾予'
'穣'
'溝'
'澗'
'正'
'載,'
'極'
'恒河沙'
'阿僧祇'
'那由他'
'不可思議'
'無量大数'
]
num = num.replace(/,/g, '')
num.match /([+-])?(\d+)(?:\.(\d+))?/i
sig = RegExp.$1
int = RegExp.$2
fract = RegExp.$3
seisuu = ''
shousuu = ''
shins = new Array
counter = 0
i = int.length
while i > 0
shins.push int.substring(i, i - 4)
i -= 4
if shins.length >= 18
return suffices[17]
suffix = 0
i = 0
while i < shins.length
shin = shins[i]
if shin == '0000'
suffix++
i++
continue
sens = ''
keta = 0
digits = shin.split('').reverse()
j = 0
while j < digits.length
digit = digits[j]
suuji = if digit == 1 and keta > 0 then '' else zero2nine[digit]
if digit != 0
sens = suuji + ten2thou[keta] + sens
keta++
j++
seisuu = sens + suffices[suffix++] + seisuu
i++
result = seisuu
result = result or zero
if fract
result = result + point + fract
result
@toHalfWidth = (strVal) ->
halfVal = strVal.replace(/[!-~]/g, (tmpStr) ->
String.fromCharCode tmpStr.charCodeAt(0) - 0xFEE0
)
halfVal.replace(/”/g, '"').replace(/’/g, '\'').replace(/‘/g, '`').replace(/¥/g, '\\').replace(RegExp(' ', 'g'), ' ').replace /〜/g, '~'