Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Input cursor jumps to end of input field on input event

I’m trying to convert the user input to uppercase on input event

so, whenever I type a key in the input field I’m facing the following issues

  1. The cursor jumps to end of the input value when user types in the middle.
  2. the last typed character (not the last character) is not converting to uppercase.

Here is the link to JS fiddle https://jsfiddle.net/aeL051od/ to reproduce the issue

new Vue({
  el: "#app",
  data() {
    return {
      input: null
    }
  },
  methods: {
    handleInput(e) {
      this.input = e.target.value ?
        e.target.value.toString().toUpperCase() :
        e.target.value;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <input type="text" v-model="input" @input="handleInput"> {{ input }}
  <!-- {{ input }} is just for reference -->
</div>
like image 633
Teja D Avatar asked Apr 02 '19 15:04

Teja D


2 Answers

If you (or Vue) copy a new value into an input, the cursor will be set to the end of the input. If you want to retain the previous position, you will need to capture the position, make the change, then on the $nextTick restore the position.

Also note that if you are going to set this.input in the handler, there's no point in your using v-model, too. It's also unlikely that saving the event is sensible, but you can.

new Vue({
  el: "#app",
  data() {
    return {
      input: null,
      event: null
    }
  },
  methods: {
    handleInput(e) {
      const el = e.target;
      const sel = el.selectionStart;
      const upperValue = el.value.toUpperCase();

      el.value = this.input = upperValue;
      this.event = e;
      this.$nextTick(() => {
        el.setSelectionRange(sel, sel);
      });
    }
  }
});
#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

input {
  margin-bottom: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input type="text" @input="handleInput">
  <p>{{ event ? event.target.value : null }}</p>
  <p>
    {{input}}
  </p>
</div>
like image 111
Roy J Avatar answered Nov 14 '22 22:11

Roy J


{{ event ? event.target.value : null }} here you display target value.

you have to display converted input value. The should be like below

 <div id="app">
      <input type="text" v-model="input" @input="handleInput">
      <p>{{ input }}</p>
    </div>

for Cursor Jump issue get the position of the cursor on start then after update value set back cursor to start position

  handleInput(e) {
          var start = e.target.selectionStart;
            this.input = this.input.toUpperCase()
          this.$nextTick(()=>{
                  e.target.selectionStart = e.target.selectionEnd = start;
                    })
        }

Fiddle : https://jsfiddle.net/r53ecug6/

like image 28
dagalti Avatar answered Nov 14 '22 22:11

dagalti