Skip to content Skip to sidebar Skip to footer

Insert Character At Cursor Position In Vue Js

I have been trying to insert emoji in textarea exactly where the cursor is at. I looked around how tos in the web could not find anything specific in VUE JS. Most of them are in pl

Solution 1:

Two steps:

1 get textarea element using a vue-way:

1.1 Add ref attrbute to textarea tag in your template code:

<textarearef="ta"></textarea>

1.2 get this element after mounted hook of this component:

let textarea = this.$refs.ta

2 get cursor position of textarea element.

let cursorPosition = textarea.selectionStart

Here is reference: ref

Solution 2:

<!-- tag --><textarearef="yourTextarea"v-model.trim="txtContent"......></textarea>

// methods:insertSomething: function(insert) {
  const self = this;
  var tArea = this.$refs.yourTextarea;
  // filter:if (0 == insert) {
    return;
  }
  if (0 == cursorPos) {
    return;
  }

  // get cursor's position:var startPos = tArea.selectionStart,
    endPos = tArea.selectionEnd,
    cursorPos = startPos,
    tmpStr = tArea.value;

  // insert:
  self.txtContent = tmpStr.substring(0, startPos) + insert + tmpStr.substring(endPos, tmpStr.length);

  // move cursor:setTimeout(() => {
    cursorPos += insert.length;
    tArea.selectionStart = tArea.selectionEnd = cursorPos;
  }, 10);
}

Solution 3:

I learned about setSelectionRange from a different question, and I used it to handle credit card number input. I will show my solution here so a person can perhaps become inspired by it.

template:

<input
    ref="input"
    v-model="value"
    @input="handleChange"
>

instance methods:

data() {
    return {
        lastValue: '',
    }
},

methods: {
    setCursorPosition(el, pos) {
        el.focus();
        el.setSelectionRange(pos, pos);
    },
    handleChange() {
        // handle backspace eventif (this.value.length < this.lastValue.length) {
            this.lastValue = this.value;
            this.$emit('input-changed', this.value);
            return;
        }
        // handle value-edit eventif (this.$refs.input.selectionStart < this.value.length) {
            const startPos = this.$refs.input.selectionStart;
            this.value = this.value.replace(/\W/gi, '').replace(/(.{4})/g, '$1 ').trim();
            this.$nextTick(() => this.setCursorPosition(this.$refs.input, startPos));
            this.lastValue = this.value;
            this.$emit('input-changed', this.value);
            return;
        }
        // handle everything elsethis.value = this.value.replace(/\W/gi, '').replace(/(.{4})/g, '$1 ').trim();
        this.lastValue = this.value;
        this.$emit('input-changed', this.value);
    },
},

The goal with the above code is to add spaces into a credit card input, so 1234123412341234 is automatically reformatted to 1234 1234 1234 1234. A person venturing into this territory will notice that problems arise when editing the input value.

You can see there are three conditions in my sample above. The last one is the default which simply reformats the current value with a 2-step combo: remove all spaces then adds a space every 4th character.

If you comment out the two if blocks, you can watch the problems emerge.

The first if block handles the backspace event. As you can see, every time the input changes, the value is captured as this.lastValue. When you press backspace, the goal of the first condition is to NOT run the regex. In my opinion, this is better UX. If you comment out that condition, you can see.

The second if block handles the editing events. A good way to test it, is to enter a valid CC but omit the 3rd character, so that everything is off by one. Then add the character in. Everything should be good. Likewise if you backspace multiple characters out. The goal of the second condition is to properly manage the cursor position (or caret position if you prefer that nomenclature).

You can safely delete the first condition and all references to lastValue and the code will still work. This is arguably simpler but worse UX.

Post a Comment for "Insert Character At Cursor Position In Vue Js"