I have a form with several text boxes.

The onblur handler for each calls a function, and so does the onfocus handler. Both the functions alter the display.

When I am in one text box and click into another, it appears (from using alert boxes to track the results) that browsers PROCESS the onblur first, then the onfocus, but then DISPLAY the onfocus changes and finally display the changes dictated by the onblur.

The onfocus may find text already in the box, and when it does it places the cursor at the end of the text.

But then the browser does the onblur screen-changes and when it returns focus to the new text box the cursor is in the leftmost position.

Does anyone know how I can position the cursor in that text box so it appears in the position following the last byte of whatever text is already entered (thus enabling the user to continue typing)?

Dani AI

Generated

Short summary of the cause and a reliable fix you can drop into this thread: when your blur/focus handlers change layout or replace elements, the browser may finish the blur handler after running your focus logic and that final reflow resets the caret. ’s alert trick worked only because it paused the browser long enough. The robust options are (a) avoid replacing or hiding the focused input node, or (b) explicitly set the caret after the page has repainted.

A practical, cross‑browser pattern is: on focus, defer placing the caret until after the browser finishes rendering (use requestAnimationFrame with a setTimeout fallback). For modern browsers use setSelectionRange; for old IE use the TextRange API (collapse/select). This avoids race conditions with onblur code that changes display.

Example implementation:

function putCaretAtEnd(el) {
  el.focus();
  if (typeof el.setSelectionRange === 'function') {
    var pos = el.value.length;
    try { el.setSelectionRange(pos, pos); } catch (e) {}
  } else if (el.createTextRange) {
    var r = el.createTextRange();
    r.collapse(false);
    r.select();
  }
}

function attachEndCaret(input) {
  input.addEventListener('focus', function () {
    var self = this;
    var raf = window.requestAnimationFrame || function (cb) { setTimeout(cb, 0); };
    raf(function () { putCaretAtEnd(self); });
  }, false);
}

Notes: pointed out the IE API (useful for very old IE); ’s no-op trick sometimes forces a reposition but won’t help if the element is removed/replaced afterward. If your onblur hides the field with display:none, restore the same DOM node (or re-focus and re-run caret code after reinserting).

Recommended Answers

All 4 Replies

This code is Internet Explorer ONLY. The object/method is "createTextRange".

The JavaScript function might look like:

function setCursorPos( x ) {

    var txtRange = x.createTextRange();
    txtRange.moveStart( "character", x.value.length - 2 );
    txtRange.moveEnd( "character", 0 );
    txtRange.select();
}

And you call it:

<form >
    <input type="text" onfocus="setCursorPos(this);" />
</form>

What this will do is move the cursor to the END of the current value of the textbox.

Did this work? Do you need more help? Please give us some feedback.

Hi,

I use this:

<TEXTAREA NAME="txt" onfocus='this.value=this.value;'>

and it works well with any web browser...
Maybe it could help you!

Henry, en français dans le texte

I apologize for not replying sooner.

When I first tried the suggestions above, Henry's didn't work at all (and still doesn't.) The snippet below:

This is the text-box:
<input type="text" size=8 value="" id="A" onfocus="this.value=this.value">

DOES put the cursor at the end BRIEFLY on re-Focus, but then it jumps back to the start. (Interestingly, inserting an "alert()" at the end of the onFocus handler LEAVES the cursor at the end when the alert box is closed - but of course I don't want an alert everytime the user returns to a text-box.

tgreer's IE-specific function "setCursorPos(x)" didn't work when I tried it either (on re-focus it highlighted the last two bytes of the text in the box) and although I questioned why the .moveStart had a -2 in its second argument, I was by then working on the CONTENT part of my project and so chose neither to try to debug the function nor to reply that it didn't work (since my attention was then elsewhere and I didn't want to continue a thread that might not lead to a solution.)

But now I've returned to the text-box problem, and by removing the -2 in .moveStart's second argument I find that it works fine.

So I'm posting now to say "Thanks, tgreer!" I've acknowledged your contribution via a comment line in my source code for the script.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.