problem with Chrome form handling: input onfocus="this.select()"
Asked Answered
S

11

25

I'm using the following HTML code to autoselect some text in a form field when a user clicks on the field:

<input onfocus="this.select()" type="text" value="Search">

This works fine in Firefox and Internet Explorer (the purpose being to use the default text to describe the field to the user, but highlight it so that on click they can just start typing), but I'm having trouble getting it to work in Chrome. When I click the form field in Chrome the text is highlighted for just a split second and then the cursor jumps to the end of the default text and the highlighting goes away.

Any ideas on how to get this working in Chrome as well?

Spillway answered 30/5, 2010 at 14:59 Comment(0)
C
23

Instead of binding to onfocus event you must bind this action into onclick event and it will work as you wanted.

<input onclick="this.select()" id="txt1" name="txt1" type="text" value="Search">
Churning answered 1/6, 2010 at 12:47 Comment(8)
That will handle the mouse, but not the keyboard. It would be much better to keep onfocus. I suspect the problem is something to do with the call to .select() rather than which event is being fired.Phocis
@Dan, but tabbing into fields using the keyboard automatically selects their contents anyway.Mattie
@Lee, I can't think of any that don't do that, but that behavior is dependent on the browser implementing it.Allier
@Tyler, yes, but if a browser didn't behave that way, it wouldn't be a great idea to try to make it behave differently. That would be alien to users familiar with that particular browser. It's not just the browser that selects text when tabbing into fields, most native O/S form fields do it too.Mattie
@Lee, but the OP asked for a behavior that isn't typical anyway.Allier
@Tyler, but this is off topic, the OP said nothing about keyboard access. The browser default behaviour already does what the OP wants for keyboard users, so there should be no need to "ensure it" by over-engineering. Like there should be no need to specify the cursor for hyperlinks.Mattie
This is a very bad solution as clicking anywhere after the field is selected should move the cursor, not reselect everything. Please don't use this solution, it's very frustrating.Segregate
javascript should be used in .js file, please don't inline js :)Ultrasound
M
17

If you really insist on sticking with onfocus, then you'll need to add onmouseup="return false" too.

Mattie answered 4/6, 2010 at 10:13 Comment(2)
Good answer. Works perfectly on Chrome, firefox and safari. onfocus="this.select()" onmouseup="return false"Prepense
That was the missing part in mobile page in chrome.Tucson
H
5

This works best for me...

<input type="text"  onfocus="this.searchfocus = true;" onmouseup="if(this.searchfocus) {this.select(); this.searchfocus = false;}" />

The mouseup event fires after onfocus.

Heidi answered 19/9, 2012 at 14:7 Comment(1)
This works bad if the focus is gained by keyboard. The next click selects the input instead of moving the caret.Segregate
I
4

This is a solution working in Firefox, Chrome and IE, both with keyboard focus and mouse focus. It also handles correctly clicks following the focus (it moves the caret and doesn't reselect the text):

<input
onmousedown="this.clicked = 1;"
onfocus="if (!this.clicked) this.select(); else this.clicked = 2;"
onclick="if (this.clicked == 2) this.select(); this.clicked = 0;"
>

With keyboard focus, only onfocus triggers which selects the text because this.clicked is not set. With mouse focus, onmousedown triggers, then onfocus and then onclick which selects the text in onclick but not in onfocus (Chrome requires this).

Mouse clicks when the field is already focused don't trigger onfocus which results in not selecting anything.

Iconography answered 12/7, 2013 at 23:58 Comment(0)
H
3

The way I got around this was by creating a wrapper function that uses setTimeout() to delay the actual call to select(). Then I just call that function in the focus event of the textbox. Using setTimeout defers the execution until the call stack is empty again, which would be when the browser has finished processing all the events that happened when you clicked (mousedown, mouseup, click, focus, etc). It's a bit of a hack, but it works.

function selectTextboxContent(textbox)
{
    setTimeout(function() { textbox.select(); }, 10);
}

Then you can do something like this to do the selection on focus:

<input onfocus="selectTextboxContent(this);" type="text" value="Search">
Holoenzyme answered 11/6, 2010 at 14:48 Comment(1)
This solution doesn't work if there is more than 10 milliseconds between mouse down and click (user is holding mouse button for more than 10 milliseconds).Segregate
E
3

Building on Jason's answer, here is a function that replaces the "select" function of DOM input nodes with an updated version that has the timeout built in:

if (/chrome/i.test(navigator.userAgent)) {
    HTMLInputElement.prototype.brokenSelectFunction = 
        HTMLInputElement.prototype.select;

    HTMLInputElement.prototype.select = function() {
        setTimeout(function(closureThis) { return function() {
            closureThis.brokenSelectFunction();
        }; }(this), 10);
    };
}

Basically, (in Chrome only) we just renamed the built-in but broken select() function to brokenSelectFunction() and then added a new function to all inputs called select() that calls brokenSelectFunction() after a delay. Now, just call select() normally, as the built-in select function has been replaced by the fixed function with Jason's delay suggestion.

This way, you don't have to worry about changing your existing calls to use a wrapper function (and once this is resolved in Chrome, you can just remove the above shim and go back to normal).

textbox.select(); // now runs select with setTimeout built-in (in Chrome only)

Edit: you might want to change the user-agent match from "chrome" to "webkit", as this issue happens in all webkit-browsers including Safari, and this fix will work for any of them.

Entry answered 20/7, 2012 at 19:42 Comment(1)
This is awesome! Works perfectly. I've been annoyed about how Webkit broke this for years!Tuberculosis
E
2

Just use <input onmouseup=select()>. That works in all browsers.

Epley answered 21/12, 2012 at 2:42 Comment(0)
S
2

This question was posted five years ago, but with HTML5, you can make this feature with the placeholder attribute.

<input type="text" name="fname" placeholder="First name">
Skillful answered 19/11, 2015 at 21:10 Comment(0)
C
1
onfocus="setTimeout(function(){select(this)})" 

or onfocus="setTimeout(function(){select(this)},118)" for Firefox.

Car answered 18/8, 2015 at 12:24 Comment(0)
S
0

Thanks ilawton. This works for me

    <input type="text"  onfocus="this.searchfocus = true;" onmouseup="if(this.searchfocus) {this.select(); this.searchfocus = false;}" />
Schnur answered 17/6, 2019 at 13:46 Comment(0)
C
0

Now a days, it works fine in Chrome. We only have to give onfocus="javascript:this.select();". Make sure it is loading with the page.

Colchester answered 28/10, 2023 at 6:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.