入力した数値を 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つです。ぜひ好みに合った方法で実装してみてください。