はじめに
こんにちは、まつけんです。
「ユーザーが電話番号を登録するフォーム」って、よくありますよね?
↓こういうの↓
↑このHTMLのフォーム要素に<input type="number">
を使ってたりしませんか?
結論、ダメ なので解決策とセットで解説します。
問題
<input type = "number">
を電話番号フォームに使ってはダメな理由
- 先頭の0が消える可能性がある
- 電話番号は国番号をつける場合があり、+81901111222のように数字以外も入る可能性がある
問題1:先頭の0が消える可能性がある
-
<input type="number">
に先頭が0から始まる番号を入力すると、一部のブラウザ(Firefox)で0が消されて表示される - 先頭の0が不要なものとして削除される場合もある
- 数値を打ち込んでからトグルボタン(▲▼)を押すと0が消える
実際に先頭0の数値(例:0901234)を打ち込んでからトグルボタン(▲▼)を押すと0が消えるので、ぜひお試しあれ
See the Pen 誤った電話番号登録フォーム by matsuken314 (@matsuken314) on CodePen.
問題2:電話番号は数字以外も入る可能性がある
電話番号は国番号をつける場合があり、数字以外も入る可能性があります。
例えば、「+81901111222」など
number
型は半角の数字のみ許容するため、「+」などの文字を扱えません。
実際に起きたこと (少しボヤかしてます)
以下要件の「電話番号登録フォーム」の実装でのコードレビュー時
- 文字列は受けつけない(半角数字のみ)
- 9ケタ〜14ケタまでしか受けつけない
<input type="number">
を使って、実装してたら
先輩エンジニア:
「こちらの対応時に入力を type="number" で文字列を入力出来ないようにした意図が知りたいです。」
自分:
『サーバーサイドでも「文字列は受け付けず、半角数字のみ」という制限をかけてましたが、
追加でフロントに「半角数字のみしか受け付けない」制限にすればより強固なバリデーションになると思ったからです』
先輩エンジニア:
「HTMLでも<input type="tel">
のように電話番号用のinputタイプがあると思うので、
- 文字列は受けつけない(半角数字のみ)
- 9ケタ〜14ケタまでしか受けつけない
であれば、patern属性に正規表現でバリデーションかけて
input type="tel" name="tel" pattern="[0-9]{9,14}" required>
でも実現できると思います」
自分:
「<input type="tel">
を使った方が良いこととその理由まで教えていただきありがとうございます!」
解決方法
結論
-
<input type="tel">
を使う - 文字列が入力できない制限(半角数字のみ許容)については
pattern
属性と組み合わせて利用する
↓下の「Result」タブを押すと、実際のフォームで操作できます
See the Pen 正しい電話番号登録フォーム by matsuken314 (@matsuken314) on CodePen.
【解説】
<input type="tel" pattern="[0-9]{9,14}" required>
とすることで、
- 文字列は受けつけない(半角数字のみ)
- 9ケタ〜14ケタまでしか受けつけない
を実現しています
おわりに
学びとして、数値だから<input type="number">
を安易に使用するのはダメだと分かりました。
MDNでは
<input type="number">
の使用基準として、
スピンボタン(▲▼)の増減が使い勝手として有益な場合に使う方がいい
と書かれてます。
具体例として
「購入チケットの数を入力してください」のフォームが紹介されてます。
改めて、
「ユーザーがどういった目的でこの機能を使うのか」
を考え抜いて実装しないといけない教訓になりました。
丁寧に教えてくれた先輩エンジニアの方に感謝です。
参考
- 先輩エンジニアのレビュー