前提条件
- テキストボックスに入力された内容をjQueryで取得してバリデーションをしたい。
- 以下の3つを識別する関数を作成したい。
- カンマ区切りフォーマットされた数値(例:
1,234,567
) - 小数
- 文字列
- (1) カンマの区切り位置がおかしい(例:
1,23,4,56,7
) - (2) 通常(例
abc
,1234z
)
- (1) カンマの区切り位置がおかしい(例:
- カンマ区切りフォーマットされた数値(例:
コード
// <input id="sample" type="text" /> と仮定
// 入力値を取得
let inputVal = $("#sample").val();
// カンマを除く(カンマで分割して配列を生成し、その配列の要素をそのまま連結する)
let inputValDelComma = inputVal.split(',').join('');
// 文字列(2) の判定実行
if (! Math.abs(inputValDelComma) && inputValDelComma != 0) {
// ERROR!! inputVal is String(ただの文字列)
}
// 入力時にカンマを含むか(カンマ削除後の長さが不一致の場合に含むと判定)
let isExistCommaInputVal = inputVal.length !== inputValDelComma.length;
// 数字化する(文字列のみの判定は完了しているため、必ず数値化できる)
inputValDelComma = Number(inputValDelComma);
// 3桁区切りフォーマット実行
let reAddedCommaInputVal = inputValDelComma.toLocaleString();
// 文字列(1) の判定実行
if (isExistCommaInputVal && (reAddedCommaInputVal !== inputVal)) {
// ERROR!! inputVal is String(カンマ位置不正)
}
// 小数 の判定実行
if (String(Math.round(inputValDelComma)) != inputValDelComma) {
// ERROR!! inputVal is float(小数)
}
解説
文字列(2) の判定
前半部分 ! Math.abs(inputValDelComma)
-
Math.abs()
は以下の挙動を示す
Math.abs('123456'); // 123456
Math.abs('-123456'); // 123456
Math.abc('abc'); // NaN
Math.abs('123,456'); // NaN
- javascriptは
NaN
をfalseと判定することを利用
NaN ? true : false // false
後半部分 inputValDelComma != 0
- 前半部分で 0 と判定された場合、条件式が
true
となってしまう
Math.abs('0'); // 0
! 0 ? true : false // true
- 0 は文字列ではなく数値なので、0は除外する条件式をAND条件で追加する必要がある
文字列(1) の判定
前半部分 isExistCommaInputVal
- カンマを削除する前後の長さを比較することで、カンマを含むかどうか判定可能
- 入力時にカンマが入っていない場合は後半部分の判定をする必要がそもそもない
// 入力時にカンマを含むか
let isExistCommaInputVal = inputVal.length !== inputValDelComma.length;
後半部分 reAddedCommaInputVal !== inputVal
- 入力した値からカンマを削除して再度3桁区切りフォーマットすることで、適当にカンマを入れた数値を判別できる
// 例: 1,23,4,56,7 のとき inputValDelComma = 1234567
// 次の行で再度処理するために、一度数値化する
inputValDelComma = Number(inputValDelComma);
// Number.toLocaleString() で3桁区切りフォーマット
let reAddedCommaInputVal = inputValDelComma.toLocaleString(); // reAddedCommaInputVal = 1,234,567
1,23,4,56,7
と 1,234,567
は違うため弾くことができる
小数の判定
- 小数点有り、無しの場合で文字列同士を比較し、弾いている
// 例: inputValDelComma = 12.0
Math.round(inputValDelComma) // 12
String(Math.round(inputValDelComma)) // '12'
'12' != '12.0' // false
さいごに
今回は生のjavascriptで頑張って実装してみましたが
もっと簡単に実装できる方法があればご教示ください