1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue.jsで日本語入力中に未確定状態でinput boxにmaxlengthを超えた部分が表示されないようにするには

Posted at

インプットボックスの文字数制限

最近、インプットボックスの文字数制限を実装する必要があり、日本語入力中の挙動で結構はまりました。とある方のアドバイスで解決したので、備忘録として残しておこうと思います。アドバイスしてくださった方、ありがとうございました。なお、今回はVue.jsでの実装で直面した問題でしたが、Vue.js以外でも(JavaScriptなら)同様のことが起こりうると思います。(より良い実装の情報があれば、ぜひ教えてください。)

シンプルにmaxlengthを指定した実装

以下ソースコードで問題ないと思いきや...

ソースコード

html
<div id=app>
  <input type="text" v-model="test" maxlength="5">
  {{test}}
</div>
Vue.js
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()する)

解決策のソースコード

html
<div id=app>
  <input type="text" v-model="test" maxlength="5" @input="onInput">
  {{test}}
</div>
Vue.js
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を超えている場合はイベントを無効化する

うまくいかなかった実装のソースコード

html
<div id=app>
  <input type="text" v-model="test" maxlength="5" @keydown="onKeyDown">
  {{test}}
</div>
VUe.js
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.

まとめ

半角英数で完結する言語うらやましい...日本語入力等のIME ONにする必要がある言語はこういうとき大変...

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?