views:

2326

answers:

3

I'm toying with the idea for my text input box of clicking on a div containing a selection of "tags" to add meta content. My text input has a width of 35, but I want it to be able to overflow.

I've searched and found methods to focus and position my caret at the end of the updated input content, and chrome and IE behave themselves and auto scroll to show the cursor in the visible area of the input box, but when the text input is full and overflows Firefox 3.0.7 leaves the correctly positioned caret out of view to the right (though if you press right arrow on keyboard you can get to it without disturbing the position).

Any help appreciated.

+2  A: 

See my answer this question. Although it is relatively kludgy, you can trigger an keypress event in FF and the input will scroll to the end (showing the caret where you'd like to see it).

jthompson
A: 

Thanks, that works for me jtompson. Combined it with an existing script to move the caret to the end of a textinput or textarea seems to cover IE7, FF3, and chrome.

    function setCaretPosition(elemId, caretPos) {
        var elem = document.getElementById(elemId);

    if(elem != null) {
        if(elem.createTextRange) {
            var range = elem.createTextRange();
            range.move('character', caretPos);
            range.select();
        }
        else {
            if(elem.selectionStart) {
                elem.setSelectionRange(caretPos, caretPos);
                elem.focus();
                // Workaround for FF overflow no scroll problem
                // Trigger a "space" keypress.
                var evt = document.createEvent("KeyboardEvent");
                evt.initKeyEvent("keypress", true, true, null, false, false, false, false, 0, 32);
                elem.dispatchEvent(evt);
                // Trigger a "backspace" keypress.
                evt = document.createEvent("KeyboardEvent");
                evt.initKeyEvent("keypress", true, true, null, false, false, false, false, 8, 0);
                elem.dispatchEvent(evt);
            }
            else
                elem.focus();
        }
    }
}
 setCaretPosition(document.getElementById("searchinput").id, document.getElementById("searchinput").value.length);
Saul
+1  A: 

I was having a similar problem with scrolling to a selection within a textarea in FireFox. I couldn't send a 'space' then a 'backspace' character because that would overwrite the selection in the textarea. So I found a better way which was to virtually retype the character immediately after the selection which would force the selection to be visible.

Here is the code:

function setSelRange(inputEl, selStart, selEnd) { 
  if (inputEl.createTextRange) {
  var range = inputEl.createTextRange(); 
  range.collapse(true); 
  range.moveEnd('character', selEnd); 
  range.moveStart('character', selStart); 
  range.select(); 
  //range.scrollIntoView();
 } else if (inputEl.setSelectionRange) {
  inputEl.focus(); 
  inputEl.setSelectionRange(selEnd, selEnd + 1);
  // ---- Firefox Workaround ----
  // Send a virtual key, which is the character immediately after the 
  // selected text. It justs rewrites the same character so that no unnecessary changes
  // are made to the content.
  // When the selection is at the end of the textarea, an extra space is appended
  // because the inputEl.value.charCodeAt(selEnd) would otherwise cause an error.
  var evt = document.createEvent("KeyboardEvent");
  if (inputEl.value.length == selEnd) {
   evt.initKeyEvent("keypress", true, true, null, false, false, false, false, 0, 32);
  } else {
   evt.initKeyEvent("keypress", true, true, null, false, false, false, false, 0, inputEl.value.charCodeAt(selEnd));
  }
        inputEl.dispatchEvent(evt);
  inputEl.setSelectionRange(selStart, selEnd);

 } 
}

Hope this helps anyone who has been searching for this. I wasted a lot of time trying to figure this out.