360

I'm using this code to try and select all of the text in the field when a user focuses on the field. What happens is, it selects all for a second, then its unselected and the typing cursor is left where I clicked...

$("input[type=text]").focus(function() {
   $(this).select();
});

I want it all to remain selected.

Smita Ahinave
  • 1,901
  • 7
  • 23
  • 42
Tim
  • 6,986
  • 8
  • 38
  • 57
  • What browser, it seems to be working OK for me in FF? – Roman Jun 30 '10 at 14:45
  • 8
    Chrome = fail for this one – wowo_999 Jun 30 '10 at 14:48
  • 1
    I was using Chrome, but .click() solves the problem :) – Tim Jun 30 '10 at 14:51
  • 4
    Note: The accepted answer here only solves half the problem. It makes the select work, but makes it difficult to then un-select it with subsequent clicks. A better solution can be found here: http://stackoverflow.com/questions/3380458/looking-for-a-better-workaround-to-chrome-select-on-focus-bug – SDC Sep 21 '12 at 10:45

17 Answers17

517

Try using click instead of focus. It seems to work for both mouse and key events (at least on Chrome/Mac):

jQuery < version 1.7:

$("input[type='text']").click(function () {
   $(this).select();
});

jQuery version 1.7+:

$("input[type='text']").on("click", function () {
   $(this).select();
});

Here is a demo

karim79
  • 339,989
  • 67
  • 413
  • 406
69

I think that what happens is this:

focus()
   UI tasks related to pre-focus
   callbacks
       select()
   UI tasks related to focus (which unselect again)

A workaround may be calling the select() asynchronously, so that it runs completely after focus():

$("input[type=text]").focus(function() { 
    var save_this = $(this);
    window.setTimeout (function(){ 
       save_this.select(); 
    },100);
});
Piskvor left the building
  • 91,498
  • 46
  • 177
  • 222
  • 4
    $("input[type=text]").focus(function() { var save_this = $(this);window.setTimeout(function(){ save_this.select(); },100); }); – etienne Nov 23 '12 at 10:12
  • @etienne: Oh, good point: the handling of `this` is a bit unexpected in such scopes. I'll update the code. – Piskvor left the building Nov 23 '12 at 16:37
  • Don't usually like time-outs but here it fits very well, simple and effective. +1 – t.mikael.d Feb 10 '13 at 13:39
  • 3
    a timeout value of 0 seems ok too, and the "focusin()" function is also working with this method. – Tanguy May 03 '13 at 13:36
  • 4
    yes, you don't even need to set a period. 0 will do fine since timeouts run at the end of the current call stack. this means that focus and click events all fire, and then your function runs – Joshua Bambrick Sep 06 '13 at 03:45
  • 1
    Timeout 0 seems to have the problem that the 'click' event can fire in a later frame, deselecting the box again. I find that timeout 10 seems to work pretty well - no noticeable delay, but more reliable than 0. – philh Nov 04 '14 at 10:25
  • It also helps to test for focus before calling select(), in case the focus is changing rapidly (e.g. the user is holding down tab) - you don't want the callback firing after they've left the box. – philh Nov 04 '14 at 10:28
61

I think this is better solution. Unlike simply selecting in onclick event, it doesn't prevent selecting/editing text with mouse. It works with major rendering engines including IE8.

$('input').on('focus', function (e) {
    $(this)
        .one('mouseup', function () {
            $(this).select();
            return false;
        })
        .select();
});

http://jsfiddle.net/25Mab/9/

user2072367
  • 719
  • 5
  • 3
  • 4
    This only works for existing fields, here is an update for binding it to new input fields: [jsfiddle.net](http://jsfiddle.net/harianus/25Mab/24/) – adriaan Jan 21 '14 at 11:25
  • Sometimes focus can be given without a click, and this handles it well. Because of that, this to me is the cleanest answer -- even though there may be some dangling event listeners each time the input is focused and not by a click... much better than setTimeout – ilovett Jun 02 '15 at 18:04
  • This doesn't allow a second click within numeric inputs to select another part of the text with the mouse. Removing the second `select()` seems to work though. – dperish Aug 24 '18 at 12:33
  • Even better with an additional `$('input[autofocus]').select();` – Daniel Bleisteiner Mar 11 '19 at 08:16
40

There are some decent answers here and @user2072367 's is my favorite, but it has an unexpected result when you focus via tab rather than via click. ( unexpected result: to select text normally after focus via tab, you must click one additional time )

This fiddle fixes that small bug and additionally stores $(this) in a variable to avoid redundant DOM selection. Check it out! (:

Tested in IE > 8

$('input').on('focus', function() {
    var $this = $(this)
        .one('mouseup.mouseupSelect', function() {
            $this.select();
            return false;
        })
        .one('mousedown', function() {
            // compensate for untriggered 'mouseup' caused by focus via tab
            $this.off('mouseup.mouseupSelect');
        })
        .select();
});
animatedgif
  • 1,060
  • 12
  • 16
26

After careful review, I propose this as a far cleaner solution within this thread:

$("input").focus(function(){
    $(this).on("click.a keyup.a", function(e){      
        $(this).off("click.a keyup.a").select();
    });
});

Demo in jsFiddle

The Problem:

Here's a little bit of explanation:

First, let's take a look at the order of events when you mouse or tab into a field.
We can log all the relevant events like this:

$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
              function(e) { console.log(e.type); });

focus events

Note: I've changed this solution to use click rather than mouseup as it happens later in the event pipeline and seemed to be causing some issues in firefox as per @Jocie's comment

Some browsers attempt to position the cursor during the mouseup or click events. This makes sense since you might want to start the caret in one position and drag over to highlight some text. It can't make a designation about the caret position until you have actually lifted the mouse. So functions that handle focus are fated to respond too early, leaving the browser to override your positioning.

But the rub is that we really do want to handle the focus event. It lets us know the first time that someone has entered the field. After that point, we don't want to continue to override user selection behavior.

The Solution:

Instead, within the focus event handler, we can quickly attach listeners for the click (click in) and keyup (tab in) events that are about to fire.

Note: The keyup of a tab event will actually fire in the new input field, not the previous one

We only want to fire the event once. We could use .one("click keyup), but this would call the event handler once for each event type. Instead, as soon as either mouseup or keyup is pressed we'll call our function. The first thing we'll do, is remove the handlers for both. That way it won't matter whether we tabbed or moused in. The function should execute exactly once.

Note: Most browsers naturally select all text during a tab event, but as animatedgif pointed out, we still want to handle the keyup event, otherwise the mouseup event will still be lingering around anytime we've tabbed in. We listen to both so we can turn off the listeners as soon as we've processed the selection.

Now, we can call select() after the browser has made its selection so we're sure to override the default behavior.

Finally, for extra protection, we can add event namespaces to the mouseup and keyup functions so the .off() method doesn't remove any other listeners that might be in play.


Tested in IE 10+, FF 28+, & Chrome 35+


Alternatively, if you want to extend jQuery with a function called once that will fire exactly once for any number of events:

$.fn.once = function (events, callback) {
    return this.each(function () {
        var myCallback = function (e) {
            callback.call(this, e);
            $(this).off(events, myCallback);
        };
        $(this).on(events, myCallback);
    });
};

Then you can simplify the code further like this:

$("input").focus(function(){
    $(this).once("click keyup", function(e){      
        $(this).select();
    });
});

Demo in fiddle

Community
  • 1
  • 1
KyleMit
  • 30,350
  • 66
  • 462
  • 664
  • In Firefox 31 on Windows your code only selects the text on every other click when you click between the two text boxes – Vitani Aug 18 '14 at 10:26
  • 1
    @Jocie, I'm not sure why it is alternating, but it looks like FF handles the text selection in the `click` event which is further down the pipeline than `mouseup`. Since we want to handle the end of the selection as late as possible to give us the most chance of overriding the browser, using click instead of mouseup should do the trick. Tested in FF, Chrome, and IE. – KyleMit Oct 28 '14 at 12:24
  • 1
    Thank you! Finally a solution that really works and in all browsers! – Vincent Sep 09 '15 at 23:57
  • 2
    Yes! This worked for me too! Thank you. This should have been the official answer – Fandango68 Dec 16 '15 at 02:15
  • Maybe it wasn't available when the answer was written, but there is already something like "once": http://api.jquery.com/one/ – RiZKiT Jan 20 '16 at 16:18
  • 1
    @RiZKiT, `one` won't cut it as "The handler is executed once per element **per event type**. It will automatically turn off the event that fired it, but the other will still be lingering around, and `off` takes care of both anyway. See my question: [function that will fire exactly once for any number of events](http://stackoverflow.com/a/24589200/1366033) – KyleMit Jan 20 '16 at 16:22
  • There is a small (and visible) delay between the click and the selection, with this solution. It works for its intended purpose, but if initial click-select is unlikely, I prefer [animatedgif's answer](http://stackoverflow.com/a/22102081/2565369) – tdtm Jun 09 '16 at 15:32
13

This would do the work and avoid the issue that you can no longer select part of the text by mouse.

$("input[type=text]").click(function() {
    if(!$(this).hasClass("selected")) {
        $(this).select();
        $(this).addClass("selected");
    }
});
$("input[type=text]").blur(function() {
    if($(this).hasClass("selected")) {
        $(this).removeClass("selected");
    }
});
ErichBSchulz
  • 15,047
  • 5
  • 57
  • 61
Nianpeng
  • 139
  • 1
  • 3
6

The problem with most of these solutions is that they do not work correctly when changing the cursor position within the input field.

The onmouseup event changes the cursor position within the field, which is fired after onfocus (at least within Chrome and FF). If you unconditionally discard the mouseup then the user cannot change the cursor position with the mouse.

function selectOnFocus(input) {
    input.each(function (index, elem) {
        var jelem = $(elem);
        var ignoreNextMouseUp = false;

        jelem.mousedown(function () {
            if (document.activeElement !== elem) {
                ignoreNextMouseUp = true;
            }
        });
        jelem.mouseup(function (ev) {
            if (ignoreNextMouseUp) {
                ev.preventDefault();
                ignoreNextMouseUp = false;
            }
        });
        jelem.focus(function () {
            jelem.select();
        });
    });
}
selectOnFocus($("#myInputElement"));

The code will conditionally prevent the mouseup default behaviour if the field does not currently have focus. It works for these cases:

  • clicking when field is not focused
  • clicking when field has focus
  • tabbing into the field

I have tested this within Chrome 31, FF 26 and IE 11.

Colin Breame
  • 1,367
  • 2
  • 15
  • 18
  • This works perfectly for click events, but if I use tab to move to the next input field I see that the content gets selected and de-selected just later – ToX 82 Apr 01 '15 at 12:16
6

This version works on ios and also fixes standard drag-to-select on windows chrome

var srcEvent = null;

$("input[type=text],input[type=number]")

    .mousedown(function (event) {
        srcEvent = event;
    })

    .mouseup(function (event) {
        var delta = Math.abs(event.clientX - srcEvent.clientX) 
                  + Math.abs(event.clientY - srcEvent.clientY);

        var threshold = 2;
        if (delta <= threshold) {
                   try {
                        // ios likes this but windows-chrome does not on number fields
                        $(this)[0].selectionStart = 0;
                        $(this)[0].selectionEnd = 1000;
                    } catch (e) {
                        // windows-chrome likes this
                        $(this).select();
                    }
        }
    });

http://jsfiddle.net/Zx2sc/2/

anihilnine
  • 127
  • 1
  • 6
4

Found a awesome solution reading this thread

$(function(){

    jQuery.selectText('input:text');
    jQuery.selectText('input:password');

});

jQuery.extend( {
    selectText: function(s) { 
        $(s).live('focus',function() {
            var self = $(this);
            setTimeout(function() {self.select();}, 0);
        });
    }
});
RafaelTSCS
  • 1,234
  • 2
  • 15
  • 36
3

I'm coming from late 2016 and this code just works in recent versions of jquery (jquery-2.1.3.js in this case).

if ($(element).is("input")) {
    $(element).focus(function () {
        $(element).select();
    });
}
Aaron
  • 181
  • 1
  • 12
3

I always use requestAnimationFrame() to jump over internal post-event mechanisms and this works perfectly in Firefox. Haven't tested in Chrome.

$("input[type=text]").on('focus', function() {
    requestAnimationFrame(() => $(this).select());
});
R.P. Pedraza
  • 173
  • 1
  • 6
2

Or you can just use <input onclick="select()"> Works perfect.

tectiv3
  • 21
  • 2
  • 1
    no it doesn't. it works for selecting the whole. but try to select a part of the text manually, you won't b able to do it. – Sujay Phadke Dec 24 '15 at 02:08
2
var timeOutSelect;
$("input[type=text]").focus(function() { 
        var save_this = $(this);
        clearTimeout(timeOutSelect);
        timeOutSelect = window.setTimeout (function(){ 
                save_this.select(); 
        }, 100);
});

Use clearTimeout for more security if you switch quickly between two input.. clearTimeout clean the old timeout...

asimov
  • 71
  • 4
  • Please edit with more information. Code-only and "try this" answers are discouraged, because they contain no searchable content, and don't explain why someone should "try this". We make an effort here to be a resource for knowledge. – Brian Tompsett - 汤莱恩 Jul 11 '16 at 08:56
2

You can use simple code:

$('#idname').select();
Rubén Ruíz
  • 453
  • 4
  • 9
2

Works great with the native JavaScript select().

$("input[type=text]").focus(function(event) {
   event.currentTarget.select();
});

or in general:

$("input[type=text]")[0].select()
Tobi G.
  • 1,530
  • 2
  • 13
  • 16
1

i using FF 16.0.2 and jquery 1.8.3, all the code in the answer didn't work.
I use code like this and work.

$("input[type=text]").focus().select();
GusDeCooL
  • 5,639
  • 17
  • 68
  • 102
  • 4
    This doesn't answer the question, which is how to select the contents of an input box *when the user focuses the field*. This will immediately focus and select the code, without user input. – saluce Dec 14 '12 at 21:13
  • @saluce i don't understand what you mean? what the questioner want is when he select the field, all the current text is selected. And my code should did that. I even use it for my project, as the time when i write this answer. – GusDeCooL Dec 15 '12 at 19:26
  • 1
    This code will focus and select everything when it runs, but the code, in and of itself, is not tied to a *user-generated event*, such as clicking on the textbox. For example, `$("input[type=text]").on('click', function () { $(this).focus.select(); })` is causing the focus and selecting to happen when the user clicks the box, because it is executed when the user clicks the box. Without the event handler, the code doesn't answer the question, hence the downvote and comment. Basically, you got the "all the current text is selected" but not the "when he selects the field" part. – saluce Dec 17 '12 at 19:49
  • 1
    @GusDeCooL funnily enough (even though this isn't exactly what he asked) I wanted to same result as you did on this :) – scrowler Oct 30 '13 at 01:02
0
<script>$.ready( $("input[type=text]").attr("onclick" , "this.select()"));<script>
trikon
  • 1
  • This will probably be marked as a low quality answer because it doesn't have any explanation of what's going on. – tumultous_rooster Apr 02 '16 at 04:42
  • Your `$.ready` is not correct. You need to pass a function to it to make it delay the `attr` until the document is ready. You are doing it immediately then passing the element collection to `$.ready`. – doug65536 Apr 02 '16 at 09:00
  • Also, avoid 'onclick', particularly this way. Use `addEventListener`. – doug65536 Apr 02 '16 at 09:01