views:

409

answers:

5

Hi,

I have a textbox that may contain strings larger than the textbox size. When I'm typing, the textbox "viewport" always moves to show the last character I typed (for example when you write a very large title in a SO question). a

The problem is that if the texbox loses focus, when it is focused again the viewport always is set at the start of the text, and I want it at the end.

I tried moving the caret programatically to the end of the text and it works, but the viewport is still at the beginning of the text, so the user still has to press any key to move the viewport to the end of the text.

Example

This is the textbox before losing focus:

alt text

And this after focus is lost:

alt text

I'd like that when the txtbox gains focus again the viewport is set like in the first image.

Is possible to do this ?

+3  A: 

Sry, but I don't think it's possible. At least not in clean and browser-consistent way.

Christoph Schiessl
Happens the same if I add text to the textbox via javascript, even if it doesn't lose focus. Can't believe there's no way to solve this.
Drevak
I'm accepting your answer because even if it's possible to do it, everything is too much hacky for something as irrelevant as this.
Drevak
A: 

One way that's a little hack-y would be to dynamically reload the text-box after focus is lost.

Just store the string in a variable and remove the text-field, then add it back in with $.html() or whatever method you like with the string in it.

Simple, works across browsers, but a little hack-y.

Isaac Hodes
+1  A: 

Okay, you are battling browser and event limitations here.

You can not simulate a UI-Event in such a way that it mimics human interaction (it's a security issue). However, there are certain built-in ways to manipulate the control of text in a few DOM elements -- The textarea element is a good example of this with its selectionStart/selectionEnd (browser-specific implementation) variables. You should probably note that in Firefox, the selectionStart/selectionEnd make your desired effect, but, again, only under Firefox.

So, your issue can not be solved in a cross-browser way. You would have to go to simulating the effect through text slicing and so forth.

Here is a quick pseudo-code example of what I mean:

element.onblur = function (event) {
    this.hidden = this.value;
    if (this.value.length > (this.offsetsetWidth / 12)) {
     this.shown = this.value.slice(this.value.length - (this.offsetWidth / 12));
     this.value = this.shown;
    }
};

element.onfocus = function (event) {
    this.value = this.hidden || this.value;
};

The slice hack here is based off a ratio of a monospaced font's width (12px) to the width of the element (whatever it may be). So, if we have a box of 144px and we are dealing with a monospaced font, we know that we can fit 12 characters in the box at a time -- so, we slice in this manner.

If the length of the value in the input is 24 characters, we do simple math to slice at (24 - (w/12))'th position into the string.

It's all a hack -- And, in all honesty, is there any practical application to this? Perhaps you should add some subtext under the input that gives an ellipsis-like preview of the last part of the text.

Justin Van Horne
+1  A: 

I feel like I might have misread the question after reading the other answers talking about hacks and such, but I knocked together a quick sample that works fine in IE8 and Firefox 3.5.2. Assuming that an input element with an id="Test" and calling the following function onfocus:

function TestFocus()
{
    var Test = document.getElementById("Test");
    if (document.selection)
    {
      var SEnd = document.selection.createRange();
      SEnd.moveStart("character", Test.value.length);
      SEnd.select();
    }
    else if (Test.setSelectionRange)
    {
     Test.setSelectionRange(Test.value.length, Test.value.length);

     //- Firefox work around, insert a character then delete it
     var CEvent = document.createEvent("KeyboardEvent");
     if (CEvent.initKeyEvent)
     {
      CEvent.initKeyEvent("keypress", true, true, null, false, false, false, false, 0, 32);
      Test.dispatchEvent(CEvent);
      CEvent = document.createEvent("KeyboardEvent");
      CEvent.initKeyEvent("keypress", true, true, null, false, false, false, false, 8, 0);
      Test.dispatchEvent(CEvent);
     }
    }
    //- The following line works for Chrome, but I'm not sure how to set the caret position
    Test.scrollLeft = Test.scrollWidth;
}

In Firefox, it uses initKeyEvent to send a space key and then the backspace key immediately after. In Chrome, I'm not sure how to set the caret to go to the end, but setting scrollLeft on the input almost works, maybe you can play around with it a little? As for Opera, I have no idea. I certainly hope this helps you on your way though.

Andy E
works great in firefox, thanx
harald
A: 

set the text-align css property of the textbox to right aligned when losing focus.

with mootools:

$('#yourtextboxid').setStyle('text-align', 'right');
knittl