10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Railsで金額の入力フォーム。Javascriptでカンマ区切りと漢数字変換、右寄せ。保存はGemで数値にする

Posted at

Railsで金額を入力するフォームをリッチにするCoffeeScriptとGemを紹介します。

success.gif

  • 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_fromar_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, '~'
10
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?