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

数字項目、特に金額の入力項目においては、打ち込んだ数字の桁が間違っていないか確認する上で、3桁のカンマ区切りで表示されていることが重要視されます。
テキストボックス上で3桁カンマ区切りを実現すると、データ登録時のカンマ外しやデータ参照時のカンマ付与など実装すべきことが多くなります。それでもシステムの利便性を考慮すると、機能としては外せないものとなっています。
以下紹介するサンプルプログラムでは、次のような機能を実装しています。
- テキストボックス入力後フォーカスが外れると3桁カンマ区切りで表示する
- 再びテキストボックスにフォーカスが当たるとカンマが消える
- 小数やマイナス符号付きの数値に対応
- 全角で入力されたら半角に自動変換
- 前後のスペースはトリムで排除
- ゼロ埋めした数字は頭のゼロを除外する
- 予めカンマ入力されても問題なし
ユーザーが使う上で必要とされる機能を全て網羅しています。「使いやすさ」と「入力のしやすさ」を兼ね備えているので、様々なシステムに適用できるのではないでしょうか。
数値を3桁区切りにする方法として Number.prototype.toLocaleString() が紹介されるケースがありますが、小数を含むと途中で繰り上げられてしまいます。そもそも toLocaleString はロケールに応じて適切に変換するためのメソッドなので、3桁カンマ区切りを目的として利用するのは望ましくありません。
数値を3桁カンマ区切りにする
データの入力ルールが決まっていて、ユーザーがそれに従ってきちんと入力してくれれば、とてもシンプルなソースコードになります。しかしどんなに厳しくルールを決めても、想定外の入力が行われるのが現実です。
そこで僕の経験から、様々な入力パターンに対応したものを実装していきます。
サンプルプログラム
- <input id="numdata" type="text" />
このテキストボックスに入力された数値を3桁カンマ区切りに変換するプログラムを作成します。
- /**
- * 数値の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 で実装したプログラムの内容について、補足説明を加えて全体の流れを解説します。
- 空の場合そのまま返却
こちらは説明不要なので割愛します。
- 全角から半角へ変換し、既にカンマが入力されていたら事前に削除
全角の数値・符号・カンマの入力を許容します。全角モードのまま数字を入力したい要望が多いので取り入れた機能です。また金額入力時にカンマを入れてしまう習慣のある方いるため、半角に変換した後に一度取り除いています。
その後、trim 処理を行い前後のスペースを取り除きます。これまで trim 関数が利用できなかった IE8 のサポートが切れたので .trim() を利用しています。
- 数値でなければそのまま返却
ここでようやく数値判定を行います。頭がゼロ埋めされた数値 00012345 も許容範囲内です。また符号はマイナスだけでなくプラスも許容しています。頭のゼロ埋めとプラス記号は、この先の処理で取り除きます。
- 整数部分と小数部分に分割
カンマ区切りは整数部分のみ対応するため split で分割します。
- 整数部分を3桁カンマ区切りへ
ここでようやく Number 関数でキャストします。この処理で頭のゼロ埋めとプラス記号が除去されます。そしてカンマを加えるために String 変換し、正規表現による replace 処理で3桁カンマ区切りに置き換えます。
- 小数部分と結合して返却
分割した整数部分と小数部分を結合して返却します。小数部分の情報がなければ、ピリオド「.」は出力されません。
数値3桁カンマ区切り関数の動作確認
数値入力後、フォーカスが外れたタイミングでカンマ区切りを実施します。また改めてテキストボックスにフォーカスされると、カンマが取り除かれた状態に置き換わります。
ここではフォーカス関連でイベントを仕掛けましたが、カンマ削除処理を実行せず onkeyup で都度カンマ区切りの処理を呼び出すのも手段の1つです。ぜひ好みに合った方法で実装してみてください。