🔏

2桁までの数字の入力フォームを実装する

2022/11/13に公開約1,800字

突然ですが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だけでは入力が制限されない

maxmin をつければよしなにやってくれそうじゃない?」

残念ながら<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

ログインするとコメントできます