Select all text on focus using jQuery
I have a little jQuery function that is meant to automatically select text in an asp.net text box when it gets focus. However, the text in the text box gets selected, but immediately then deselects.
The code works if i bind to the focus event with .focus(function()) but I am adding the text boxes to the page dynamically which is why I think I need to use the live event.
Can anyone see a problem? The text boxes in question are in Item templates of two gridviews inside a multiview if that makes a difference?
Code:
<script type="text/javascript">
//Select all text in Cost Rate Text Boxes when they have focus
$(document).ready(function () {
$(".CostRateTextBox").live('focus', function () {
$(this).select();
});
});
</script>
Edit:
<script type="text/javascript">
//Select all text in C开发者_JAVA技巧ost Rate Text Boxes when they have focus
$(document).ready(function () {
$(".CostRateTextBox").live('focus', function () {
$(this).select();
preventDefault();
});
});
</script>
It seems to be the mouseup
event interfering. You'll notice if you click and hold in the form field then move outside of it to "mouseup
" the selection sticks. Using mouseup
instead of focus
to trigger the select()
method seems to work well:
<script type="text/javascript">
//Select all text in Cost Rate Text Boxes when they have focus
jQuery(function($){
$("table.demo").on("mouseup", ".CostRateTextBox", function () {
$(this).select();
});
});
</script>
Demo: jsfiddle.net/gableroux/jvJzX/12
See original demo for jQuery 1.3 - 1.8 compatible code.
I had a similar problem with a product search form I was working on. I know that this has already been answered, but I figured it can't hurt to submit my code, right?
$('#product-search').focus(function(){
$('#product-search').mouseup(function(){
$(this).select(function(){
$(this).off('mouseup');
});
$(this).select();
});
});
The advantage being that it only selects the text when the form first gets focus, rather than every time the form gets clicked, such as when a user wants to select a portion of the text.
I rewrote Marcel's fiddle to demonstrate the difference. http://jsfiddle.net/7tDYq/2/
Here's the solution I came up with in the question jquery input select all on focus:
$("input").focus(function(){
$(this).on("click.a keyup.a", function(e){
$(this).off("click.a keyup.a").select();
});
});
$("input").focus(function(){
$(this).on("mouseup.a keyup.a", function(e){
$(this).off("mouseup.a keyup.a").select();
});
});
// event logger
$("input").on("mousedown focus mouseup click blur " +
"keydown keypress keyup change",
function(e) {
console.log(e.type);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="potato" />
<input type="text" value="tomato" />
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); });
Some browsers attempt to position the cursor during the mouseup
event. 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 click 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 theclick
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 click
and keyup
functions so the .off()
method doesn't remove any other listeners that might be in play.
Additionally, if you want to extend jQuery with a function called once
that will fire exactly once for any number of events:
//The handler is executed at most once per element for all event types.
$.fn.once = function (events, callback) {
return this.each(function () {
$(this).on(events, myCallback);
function myCallback(e) {
$(this).off(events, myCallback);
callback.call(this, e);
}
});
};
Then you can simplify the code further like this:
$("input").focus(function(){
$(this).once("click keyup", function(e){
$(this).select();
});
});
//The handler is executed at most once per element for all event types.
$.fn.once = function (events, callback) {
return this.each(function () {
$(this).on(events, myCallback);
function myCallback(e) {
$(this).off(events, myCallback);
callback.call(this, e);
}
});
};
$("input").focus(function(){
$(this).once("click keyup", function(e){
$(this).select();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="potato" />
<input type="text" value="tomato" />
Tested in IE 10+, FF 28+, & Chrome 35+
精彩评论