38

I have the following function that adds a selector to a search input as an advanced option, just like stack overflows advanced search.

When you click what you are searching for it adds a prefix. See Jquery below:

<script>
$(document).ready(function () {

        $("table#advanced_search_options tr").click(function () {
            var SearchSelection = $(this).children("td:last-of-type").html();
            var SearchInput = $('#Search');
            SearchInput.val(SearchInput.val() + SearchSelection);
            return false;
            alert(SearchSelection);
        });
});
</script>

How can I manipulate the above to also bring focus to the #search input, placing the carrot (the blinking text insert cursor) to the end of the inserted text/value? eg.

HC: <-- The added value to my search input, I would like to set the cursor here, right after the :

Mark
  • 4,773
  • 8
  • 53
  • 91

1 Answers1

139

You can do this using Input.setSelectionRange, part of the Range API for interacting with text selections and the text cursor:

var searchInput = $('#Search');

// Multiply by 2 to ensure the cursor always ends up at the end;
// Opera sometimes sees a carriage return as 2 characters.
var strLength = searchInput.val().length * 2;

searchInput.focus();
searchInput[0].setSelectionRange(strLength, strLength);

Demo: Fiddle

RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
palaѕн
  • 72,112
  • 17
  • 116
  • 136
  • 2
    Just in case: `if (newEl.attr('type') != 'number') {}` prevents you from trying to set the caret on input-types that do not support setting the caret – fboes Aug 13 '14 at 09:08
  • see this fork: `http://jsfiddle.net/msLkp1gt/1/`, I want user to focus on first and when they use tab to focus on second, cursor should go to end. – Akshay Oct 13 '14 at 08:58
  • You should multiply the value length by 2 because Opera sometimes sees a carriage return as 2 characters. Hence the text being selected not at the end every time. – Brad Bird Oct 28 '14 at 23:07
  • 1
    This did not work for me! I wrapped it in a `setTimeout(function() { //code }, 0);` – Derk Jan Speelman Apr 12 '17 at 08:26
  • 1
    as @DerkJanSpeelman mentioned, for me it had to be wrapped inside a setTimeout of 0 – Prashant Mar 19 '18 at 15:19