jQuery Set Cursor to Beginning of Input Field on Focus

14,797

Solution 1

This will bind the focus AND click events of the input field to the function. Hope this helps!

$('#email').on('focus click', function() {
  $(this)[0].setSelectionRange(0, 0);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" placeholder="Enter your name" autofocus>
<input type="text" id="email" value="@website.com">

Or, without jQuery...

document.getElementById('email').addEventListener('click', moveCursor);
document.getElementById('email').addEventListener('focus', moveCursor);

function moveCursor(event) {
   event.target.setSelectionRange(0, 0);
}
<input type="text" placeholder="Enter your name" autofocus>
<input type="text" id="email" value="@website.com">

Solution 2

Do you really need jQuery for this?

document.getElementById("email").addEventListener("click", moveCursor);
document.getElementById("email").addEventListener("focus", moveCursor);

function moveCursor(event) {
    event.target.setSelectionRange(0,0);
}
<input value="@website.com" type="text" name="email" id="email"></input>

Solution 3

Whatever you want to perform with a cursor needs a field focus anyway.

Here is an old chunk I use. I even named it cursor.js in a sub-directory... I took it from many places I guess.

It's a get/set cursor position. It takes a JS element. .oO($(el)[0] for syntax loose..)

var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
    // Opera 8.0+ (UA detection to detect Blink/v8-powered Opera)
var isFirefox = typeof InstallTrigger !== 'undefined';   // Firefox 1.0+
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
    // At least Safari 3+: "[object HTMLElementConstructor]"
var isChrome = !!window.chrome && !isOpera;              // Chrome 1+
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6


function GetCursorPos (field) {

  // Initialize
  iCaretPos = 0;

  if (isIE){

    // Set focus on the element
    field.focus();

    // To get cursor position, get empty selection range
    oSel = field.createTextRange();

    // Move selection start to 0 position
    oSel.moveStart('character', -field.value.length);

    // The caret position is selection length
    iCaretPos = oSel.text.length;
  }

  if (isChrome||isSafari){
    iCaretPos = field.selectionStart;
  }

  if (isFirefox){
    iCaretPos = field.selectionStart;
  }

  return iCaretPos;
}

function SetCursorPos (field,Pos) {

  // Set focus on the element
    field.focus();

  if (isIE){
    field.selectionStart=Pos;
  }

  if (isChrome||isSafari){
    field.setSelectionRange(Pos,Pos);
  }

  if (isFirefox){
    field.selectionStart=Pos;
  }

  return;
}

About browser-friendly considerations, there is:

  1. .selectionStart -- Chrome/Safari/Firefox
  2. .setSelectionRange(Pos,Pos) -- Chrome/Safari/Firefox/Internet Explorer
  3. .createTextRange() -- Internet Explorer


An inspiration I used upthere long ago: partial (compared to the above) SO answer
Share:
14,797
Bijan
Author by

Bijan

Hi!

Updated on June 25, 2022

Comments

  • Bijan
    Bijan almost 2 years

    I have an input field <input value="@website.com" type="text" name="email" id="email"> and I want to make it so when a user focuses on this field, it will move the cursor to be before the @website.com.

    I have the following Javascript/jQuery code but it does not seem to work:

    $(document).ready(function() {
        $("#email").focusin(function(){
            $("#email").focus();
            $("#email")[0].setSelectionRange(0,0);
        });
    });
    

    It seems like the .focus() keeps calling the focusin() function.

    I know $("#email")[0].setSelectionRange(0,0); is the proper way to move the cursor to the front but how do I bind it to when the field has focus?

    Edit: So when I use:

    $("#email").focus(function(){
        $("#email")[0].setSelectionRange(0,0);
    });
    

    It sets the cursor to the beginning when I tab into the field but not when I click in.

    Edit2: This is different than enter link description here because that just gets the caret position whereas I am looking to set the caret position.

    • Alex
      Alex almost 6 years
      If you and console.log() before $("#email").focus(); above check the console, you will see that you're creating and infinite-loop by doing a .focus as the focusin event fires, resulting in maximum call stack size exceeded error.
    • Louys Patrice Bessette
      Louys Patrice Bessette almost 6 years
      First... $("#email")[0] is an abomination. You force jQuery to create an object... Then you use its [0], which is the same as document.getElementById("#email"). All more about this element that was added in the jQuery object, you disclose it. -- So that is syntaxically a "doh!"
    • Louys Patrice Bessette
      Louys Patrice Bessette almost 6 years
    • Louys Patrice Bessette
      Louys Patrice Bessette almost 6 years
      In the above comment of mine, you disclose it. should have been read you discard it.;)
  • Alex
    Alex almost 6 years
    That works. Well done. You can use $(this)[0].setSelectionRange(0,0); instead by the way.
  • Ben Botvinick
    Ben Botvinick almost 6 years
    Ah, true. Thanks!
  • Louys Patrice Bessette
    Louys Patrice Bessette almost 6 years
    Thanks for the comment. Updated.