4

I have many inputs fields which I need to fill repeatedly so I usually use Tab to navigate through the form.

Fields have default suffix value which needs to be prepended. It works as expected when I focus in the input with mouse click.

However when I tab between inputs it selects all text which is undesirable behaviour in my case.

Have a look at this:

function setCaretPosition(elem, caretPos) {
  if (elem == null) return;
  if (elem.createTextRange) {
    var range = elem.createTextRange();
    range.move('character', caretPos);
    range.select();
  } else if (elem.selectionStart) {
    elem.focus();
    elem.setSelectionRange(caretPos, caretPos);
  } else {
    elem.focus();
  }
}

$(document).ready(function() {
  $('input').focus(function() {
    setCaretPosition(this, 0);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="input1" value=" km/h" />
<input type="text" id="input2" value=" kg" />
  • When you click inside any of the inputs, caret is set at the beginning.
  • When you Tab between inputs caret is not set. Instead, whole input contents is higlighted.

How do I prevent text input from higlighting its contents when using tab navigation?

I prefer the answer without use of setTimeout (if it's possible at all).

Cjmarkham
  • 9,484
  • 5
  • 48
  • 81
stil
  • 5,306
  • 3
  • 38
  • 44
  • Possible duplicate of [Is there a function to deselect all text using JavaScript?](http://stackoverflow.com/questions/6562727/is-there-a-function-to-deselect-all-text-using-javascript) – imtheman Mar 16 '17 at 23:42
  • 1
    If you think it is a duplicate, why don't you vote to close with the duplicate as a reason? – Cjmarkham Mar 16 '17 at 23:46
  • Are you sure it's working when clicking? The caret is not moved to position 0 when clicked! – ibrahim mahrir Mar 16 '17 at 23:51
  • @ibrahimmahrir It definitely works on latest Firefox. I don't really need compatibility with other browsers as it's intended to work in my internal tool. – stil Mar 16 '17 at 23:54
  • 1
    Note: Caret will be set to the end of the value in Chrome. FF and IE set to the beginning. I know you said you don't care about cross compatibility, just a note for others. – Cjmarkham Mar 16 '17 at 23:56
  • You could remove the appearance of selection with CSS. It would still overwrite the original input if you didn't manually move the cursor. Is this a validation question? You could use the client or server to prefix the value if it wasn't entered by the user. – Cjmarkham Mar 16 '17 at 23:59
  • If it's an internal tool, surely you can do away with UX and just validate and prefix if needed on the client or server side (once the form is submitted). – Cjmarkham Mar 17 '17 at 00:12

1 Answers1

5

On Chrome and Explorer(Not working on Edge and Firefox), simply:

<input type="text" value=" km/h" onfocus="this.setSelectionRange(this.value.length, this.value.length)"/>
<input type="text" value=" kg" onfocus="this.setSelectionRange(this.value.length, this.value.length)"/>

On Firefox and Chrome(Not working on Edge and Explorer)

jQuery.fn.putCursorAtEnd = function() {
  return this.each(function() {
    // Cache references
    var $el = $(this), el = this;
    
    // Timeout seems to be required for Firefox
    setTimeout(function() {
      el.setSelectionRange($el.val().length, $el.val().length);
    }, 0);
  });
};

var searchInput = $("input");

searchInput.on("focus", function() { // could be on any event
    searchInput.putCursorAtEnd()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value=" km/h" />
<input type="text" value=" kg" />
Mindless
  • 2,352
  • 3
  • 27
  • 51