インプットボックスの文字数制限
最近、インプットボックスの文字数制限を実装する必要があり、日本語入力中の挙動で結構はまりました。とある方のアドバイスで解決したので、備忘録として残しておこうと思います。アドバイスしてくださった方、ありがとうございました。なお、今回はVue.jsでの実装で直面した問題でしたが、Vue.js以外でも(JavaScriptなら)同様のことが起こりうると思います。(より良い実装の情報があれば、ぜひ教えてください。)
シンプルにmaxlength
を指定した実装
以下ソースコードで問題ないと思いきや...
ソースコード
<div id=app>
<input type="text" v-model="test" maxlength="5">
{{test}}
</div>
const app = new Vue ({
el: '#app',
data: {
test:''
}
})
もし、挙動を試してみたい方は、以下codepenからお試しください。
See the Pen This form can't restrict max length on Japanese language input by Yasunori MATSUOKA (@YasunoriMATSUOKA) on CodePen.
微妙な状況に
しかし、この実装では日本語入力中に未確定状態では最大文字数のmaxlength
を超えた部分についてもインプットボックスに表示されてしまうという状況に悩まされていました。(Enter
押す等して確定すれば、maxlength
以降の文字は消えるのですが、その前の未変換の状態や変換中はmaxlength
以上の文字が入力できているような印象をユーザーに与えてしまうという点で微妙な状況でした。)
解決策
inputイベント時にevent.target.value
の長さをチェックし、maxlength
を超えている場合はinput boxからフォーカスを外す(event.target.blur()
する)
解決策のソースコード
<div id=app>
<input type="text" v-model="test" maxlength="5" @input="onInput">
{{test}}
</div>
const app = new Vue ({
el: '#app',
data: {
test:''
},
methods: {
onInput (event) {
console.log('onInput', event)
if (event.target.value.length > event.target.getAttribute("maxlength")) {
event.target.blur()
}
}
}
})
無理矢理感は否めませんが、これで、maxlength
を超えた際は、自動的に対象のinput boxからフォーカスが外れ、日本語入力が強制的に確定され、maxlength
以降の仮入力中の文字がinput boxに表示されることが無くなりました。
試してみたい方は、以下のcodepenでお試しください。
See the Pen Restrict max length on Japanese language input by Yasunori MATSUOKA (@YasunoriMATSUOKA) on CodePen.
試したがうまくいかなかったもの
keydown
イベント時にevent.target.value
の長さをチェックし、maxlength
を超えている場合はイベントを無効化する
うまくいかなかった実装のソースコード
<div id=app>
<input type="text" v-model="test" maxlength="5" @keydown="onKeyDown">
{{test}}
</div>
const app = new Vue ({
el: '#app',
data: {
test:''
},
methods: {
onKeyDown (event) {
console.log('onKeyDownEvent', event)
if (event.target.value.length >= 5) {
if (event.code !== "Backspace" && event.code !== "Delete" && event.code !== "ArrowRight" && event.code !== "ArrowLeft" && event.code !== "ArrowUp" && event.code !== "ArrowDown" && event.code !== "PageUp" && event.code !== "PageDown" && event.code !== "Enter" && event.code !== "Space" && event.code !== "Tab") {
event.preventDefault()
console.log('preventDefault', event)
}
}
}
}
})
IME ONの状態での入力中に、入力をJavaScriptで制御するのは難しいようで、半角英数ならば意図した通に動くものの、日本語入力中には意図した通り動作させることができませんでした。
試してみたい方は、以下codepen上でお試しください。
See the Pen Try to apply max length restriction on input Japanese language (don't work well) by Yasunori MATSUOKA (@YasunoriMATSUOKA) on CodePen.