入力した数値を JavaScript で自動的に3桁カンマ区切りにして表示する方法!全角入力を許容する拡張機能も実装!

更新日: 公開日:2016/01/13
JavaScriptで数値を3桁カンマ区切りにする

数字項目、特に金額の入力項目においては、打ち込んだ数字の桁が間違っていないか確認する上で、3桁のカンマ区切りで表示されていることが重要視されます。

テキストボックス上で3桁カンマ区切りを実現すると、データ登録時のカンマ外しやデータ参照時のカンマ付与など実装すべきことが多くなります。それでもシステムの利便性を考慮すると、機能としては外せないものとなっています。

以下紹介するサンプルプログラムでは、次のような機能を実装しています。

  • テキストボックス入力後フォーカスが外れると3桁カンマ区切りで表示する
  • 再びテキストボックスにフォーカスが当たるとカンマが消える
  • 小数やマイナス符号付きの数値に対応
  • 全角で入力されたら半角に自動変換
  • 前後のスペースはトリムで排除
  • ゼロ埋めした数字は頭のゼロを除外する
  • 予めカンマ入力されても問題なし

ユーザーが使う上で必要とされる機能を全て網羅しています。「使いやすさ」と「入力のしやすさ」を兼ね備えているので、様々なシステムに適用できるのではないでしょうか。

数値を3桁区切りにする方法として Number.prototype.toLocaleString() が紹介されるケースがありますが、小数を含むと途中で繰り上げられてしまいます。そもそも toLocaleString はロケールに応じて適切に変換するためのメソッドなので、3桁カンマ区切りを目的として利用するのは望ましくありません。

数値を3桁カンマ区切りにする

データの入力ルールが決まっていて、ユーザーがそれに従ってきちんと入力してくれれば、とてもシンプルなソースコードになります。しかしどんなに厳しくルールを決めても、想定外の入力が行われるのが現実です。

そこで僕の経験から、様々な入力パターンに対応したものを実装していきます。

サンプルプログラム

数値の3桁カンマ区切り処理【HTML】
<input id="numdata" type="text" />

このテキストボックスに入力された数値を3桁カンマ区切りに変換するプログラムを作成します。

数値の3桁カンマ区切り処理【JavaScript】
/**
 * 数値の3桁カンマ区切り
 * 入力値をカンマ区切りにして返却
 * [引数]   numVal: 入力数値
 * [返却値] String(): カンマ区切りされた文字列
 */
function addFigure(numVal) {
  // 空の場合そのまま返却
  if (numVal == ''){
    return '';
  }
  // 全角から半角へ変換し、既にカンマが入力されていたら事前に削除
  numVal = toHalfWidth(numVal).replace(/,/g, "").trim();
  // 数値でなければそのまま返却
  if ( !/^[+|-]?(\d*)(\.\d+)?$/.test(numVal) ){
      return numVal;
  }
  // 整数部分と小数部分に分割
  var numData = numVal.toString().split('.');
  // 整数部分を3桁カンマ区切りへ
  numData[0] = Number(numData[0]).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  // 小数部分と結合して返却
  return numData.join('.');
}

/**
 * カンマ外し
 * 入力値のカンマを取り除いて返却
 * [引数]   strVal: 半角でカンマ区切りされた数値
 * [返却値] String(): カンマを削除した数値
 */
function delFigure(strVal){
  return strVal.replace( /,/g , "" );
}

/**
 * 全角から半角への変革関数
 * 入力値の英数記号を半角変換して返却
 * [引数]   strVal: 入力値
 * [返却値] String(): 半角変換された文字列
 */
function toHalfWidth(strVal){
  // 半角変換
  var halfVal = strVal.replace(/[!-~]/g,
    function( tmpStr ) {
      // 文字コードをシフト
      return String.fromCharCode( tmpStr.charCodeAt(0) - 0xFEE0 );
    }
  );
  return halfVal;
}

/** 
 * 処理を適用するテキストボックスへのイベント設定
 * onBlur : カンマ区切り処理実施
 * onFocus : カンマ削除処理実施
 */
var elm = document.getElementById('numdata');
elm.addEventListener('blur', function(){ this.value = addFigure(this.value) }, false);
elm.addEventListener('focus', function(){ this.value = delFigure(this.value) }, false);

13行目に登場する toHalfWidth は、全角英数記号を半角に変換するオリジナル関数です。汎用性の高い関数なので、参考にしていただけたらと思います。もし全角入力を許容しないように制御するのであれば、次のように書き換えてください。

// 13行目変更前
numVal = toHalfWidth(numVal).replace(/,/g, "").trim();
// 13行目変更後
numVal = numVal.toString().replace(/,/g, "").trim();

また、既存のテキストボックスにも実装できるよう、JavaScript 側で onBlur のカンマ追加処理と onFocus のカンマ削除処理のイベントを定義しています。この部分は jQuery で実装しても構いません。

対応する入力パターン

  • 全角数値 (*) : -12345678.77777
  • カンマつき数値 : 1,234,567,890.98765
  • ゼロ埋め数値 : -0000012345.678
  • プラス符号付き数値 : +1122334455
  • 前後のスペースあり

全角の数値は toHalfWidth を利用した場合に限られます。また、このとき戻り値は半角に変換したデータになります。(全角で入力しても半角に変換して出力)

サンプルプログラムの処理の流れ

JavaScript で実装したプログラムの内容について、補足説明を加えて全体の流れを解説します。

  1. 空の場合そのまま返却

    こちらは説明不要なので割愛します。

  2. 全角から半角へ変換し、既にカンマが入力されていたら事前に削除

    全角の数値・符号・カンマの入力を許容します。全角モードのまま数字を入力したい要望が多いので取り入れた機能です。また金額入力時にカンマを入れてしまう習慣のある方いるため、半角に変換した後に一度取り除いています。

    その後、trim 処理を行い前後のスペースを取り除きます。これまで trim 関数が利用できなかった IE8 のサポートが切れたので .trim() を利用しています。

  3. 数値でなければそのまま返却

    ここでようやく数値判定を行います。頭がゼロ埋めされた数値 00012345 も許容範囲内です。また符号はマイナスだけでなくプラスも許容しています。頭のゼロ埋めとプラス記号は、この先の処理で取り除きます。

  4. 整数部分と小数部分に分割

    カンマ区切りは整数部分のみ対応するため split で分割します。

  5. 整数部分を3桁カンマ区切りへ

    ここでようやく Number 関数でキャストします。この処理で頭のゼロ埋めとプラス記号が除去されます。そしてカンマを加えるために String 変換し、正規表現による replace 処理で3桁カンマ区切りに置き換えます。

  6. 小数部分と結合して返却

    分割した整数部分と小数部分を結合して返却します。小数部分の情報がなければ、ピリオド「.」は出力されません。

数値3桁カンマ区切り関数の動作確認

数値入力後、フォーカスが外れたタイミングでカンマ区切りを実施します。また改めてテキストボックスにフォーカスされると、カンマが取り除かれた状態に置き換わります。

ここではフォーカス関連でイベントを仕掛けましたが、カンマ削除処理を実行せず onkeyup で都度カンマ区切りの処理を呼び出すのも手段の1つです。ぜひ好みに合った方法で実装してみてください。

\ この記事をシェアする /

このブログの運営者

NJ

Web系メインで従事していた元システムエンジニア。現在は個人事業主として独立。Webサイト運営における「困った問題」の解決方法をブログで発信。Web サイト運営、ポップデザインや動画制作など、パソコンでモノづくりをしている。