javascriptcaretonkeydownonkeyup

How do I keep my cursor/caret from moving inside of an input text element?


I'm trying to build a form that works in a manner similar to the Google Search page, as well as Gmail and several other pages (including the this page - see the "Tags" input on the Ask Question page). As text is input, a list of options will appear, and the user can use up and down arrows to select the option they want.

The problem I am having is that the up arrow puts the cursor/caret in position 0 of the field, and down puts it at the end. Is there an easy way of keeping it from moving to the beginning/end, or do I need to find the caret position before my function is run, and reposition it to that spot after?

This is the beginning of the function that runs when when text is entered in the input element (onkeyup).

var keycode = checkKeycode (event);   // returns the keycode of the key pressed.
if (keycode == 38) {         // up arrow
    var selection = $(".optionsSelected").attr("id");
    var selId = parseInt(selection.replace('briefOption', ''));
    if (selId != 0) {
        $(".optionsSelected").removeClass("optionsSelected");
        var newSelId = selId - 1;
        $("#briefOption"+newSelId).addClass("optionsSelected");
    }
}
else if (keycode == 40) {     // down arrow
    var selection = $(".optionsSelected").attr("id");
    var selId = parseInt(selection.replace('briefOption', ''));
    if (selId != numAvEmps && numAvEmps != 0) {
        $(".optionsSelected").removeClass("optionsSelected");
        var newSelId = selId + 1;
        $("#briefOption"+newSelId).addClass("optionsSelected");
    }
}
else if (keycode == 27) {    // Escape
    $("#docDropDown").css("display","none");
}
else if (keycode == 9 || keycode == 13) {     //tab or enter
    /* Fill form */
}

Let me know if any more code would be useful. Thanks for the help.


Solution

  • You'd want to store the caret before and then when you're done doing things, set it back.

    Something like this:

    HTML body:

    <input type="text" id="mytextbox" style="border: 1px solid black" />
    

    Javascript:

    function getCaretPosition(ctrl)
    {
        var caretPos = 0;    
        // IE
        if (document.selection)
        {
            ctrl.focus ();
            var sel = document.selection.createRange();
            sel.moveStart ('character', -ctrl.value.length);
            caretPos = sel.text.length;
        }
        // Firefox
        else if (ctrl.selectionStart || ctrl.selectionStart == '0')
        {
            caretPos = ctrl.selectionStart;
        }
    
        return caretPos;
    }
    
    function setCaretPosition(ctrl, pos)
    {
        if(ctrl.setSelectionRange)
        {
            ctrl.focus();
            ctrl.setSelectionRange(pos,pos);
        }
        else if (ctrl.createTextRange)
        {
            var range = ctrl.createTextRange();
            range.collapse(true);
            range.moveEnd('character', pos);
            range.moveStart('character', pos);
            range.select();
        }
    }
    
    
    
    $(document).ready(function ()
    {
    
        $("#mytextbox").keydown(function (e)
        {
            // Up
            if(e.which == 38)
            {
                var pos = getCaretPosition(this);
    
                // Do stuff here that changes the value/caret?
    
                setCaretPosition(this, pos);
            }
            // Down
            else if(e.which == 40)
            {
                var pos = getCaretPosition(this);
    
                // Do stuff here that changes the value/caret?
    
                setCaretPosition(this, pos);
            }
    
        });
    
    });