I’ve hit this problem when I was working on a @mentioning system for a chat I’m developing at work. When the user selected a mentionee from the results, I needed to insert that user in the input at the current cursor / caret position.

The Solution

To do this, I’ve used the following helper:

window.moveCursor = (el, pos) => {
    if (el.setSelectionRange) {
        el.setSelectionRange(pos, pos);
    } else if (el.createTextRange) {
        const range = el.createTextRange();

        range.collapse(true);
        range.moveEnd('character', pos);
        range.moveStart('character', pos);
        range.select();
    }
};

To use it, include it in the file that contains all your code or in a file that gets loaded before your code and call it:

moveCursor(HTMLElement, newPosition);

The HTMLElement represents the input element, and the newPosition would be the index where you want to place the cursor inside the input.

The function uses two different APIs for backwards compatibility with older versions of IE. It should work fine as far back as IE9.