2桁までの数字の入力フォームを実装する
突然ですが2桁までしか入力できない数字の入力フォームを実装できますか?
これがかんたんそうに思えて、実際にやろうとすると結構難しいんです。
DR;TL
急いでいる方のために、最初に結論を。
oninput
, min
, max
を使って実現できます。
<input
type="number"
min="0"
max="99"
oninput="javascript: this.value = this.value.slice(0, 2);"
/>
ポイントはoninput で入力値の最初の2文字だけを取得しているところです。
oninput="javascript: this.value = this.value.slice(0, 2);"
inputイベントが3桁目入力直後に発火するので、実質2桁しか入力できなくなります。
ReactやVueなどのフレームワークを使っている場合は、inputイベントを拾って同じ実装をすればOKです🙆
結論は以上!
以降は、これ以外のできそうでできない方法についてご紹介します。
max,minだけでは入力が制限されない
「max
、min
をつければよしなにやってくれそうじゃない?」
残念ながら<input type=number>
はそこまで気が効かず、入力としては3桁以上も受け付けてしまいます😇
<input type="number" min="0" max="99" />
maxlengthも効かない
「maxlengthを使えばいいのでは?」
<input type="number" maxlength="2" />
こちらも残念なことにtype=numberでは動作しません😱
beforeinputでは入力をキャンセルできない
入力直前に発火するbeforeinputを使った方が、一度入力された後にsliceするより良さそうです。
<input type="number" beforeinput="{{3桁以上入れようとしたら入力をキャンセルする処理}}" />
しかしこれも残念なことに現状beforeinputのイベントをキャンセルすることはできません。
beforeinputの今後に期待
今回ご紹介したoninput
を使う方法ですが、まだ、変換前の文字が表示されてしまう(入力はできない)という問題が残っています。
この問題について、こちらで議論されているように、beforeinputで入力をキャンセルできるようにしようという動きがあるようです。
beforeinputで入力がキャンセルできるようになれば、入力がinput method editor(変換前の下線が入った文字)かを判定して、変換前の文字を表示できるようなりますね。
<input
type="number"
min="0"
max="99"
oninput="javascript: if(event.isComposing) { event.preventDefault() } "
/>
今後に期待しましょう💪
Discussion