Select text on input focus
Solution 1
The way to do this in Angular is to create a custom directive which does the autoselect for you.
module.directive('selectOnClick', ['$window', function ($window) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.on('click', function () {
if (!$window.getSelection().toString()) {
// Required for mobile Safari
this.setSelectionRange(0, this.value.length)
}
});
}
};
}]);
Apply the directive like this:
<input type="text" value="test" select-on-click />
Update1: Removed jQuery dependency.
Update2: Restrict as attribute.
Update3: Works in mobile Safari. Allows selecting part of the text (requires IE>8).
Solution 2
Here's an enhanced directive which avoids reselecting the text when the user clicks to position the cursor in the input box.
module.directive('selectOnClick', function () {
return {
restrict: 'A',
link: function (scope, element) {
var focusedElement;
element.on('click', function () {
if (focusedElement != this) {
this.select();
focusedElement = this;
}
});
element.on('blur', function () {
focusedElement = null;
});
}
};
})
Solution 3
This is an old answer, for Angular 1.x
Better way to do it is by using the ng-click
built-in directive:
<input type="text" ng-model="content" ng-click="$event.target.select()" />
EDIT:
As JoshMB has kindly reminded; referencing DOM nodes in Angular 1.2+ is no longer allowed. So, I've moved $event.target.select()
into the controller:
<input type="text" ng-model="content" ng-click="onTextClick($event)" />
Then in your controller:
$scope.onTextClick = function ($event) {
$event.target.select();
};
Here is an example fiddle.
Solution 4
Neither of proposed solutions worked well for me. After quick research I came up with this:
module.directive('selectOnFocus', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var focusedElement = null;
element.on('focus', function () {
var self = this;
if (focusedElement != self) {
focusedElement = self;
$timeout(function () {
self.select();
}, 10);
}
});
element.on('blur', function () {
focusedElement = null;
});
}
}
});
It's a mix of several solutions proposed, but works both on click and focus (think autofocus) and allows manual selection of partial value in the input.
Solution 5
For me, ng-click didn't have sense, because you could never reposition the cursor without selecting all text again, I found this was annoing. Then it is better to use ng-focus, because the text is selected only if the input was not focused, if you click again to reposition the cursor then the text just deselects, as expected, and you can write in between.
I found this approach to be the expected UX behaviour.
Use ng-focus
Option 1: separate code
<input type="text" ng-model="content" ng-focus="onTextFocus($event)" />
and in controller
$scope.onTextFocus = function ($event) {
$event.target.select();
};
Option 2: as an alternative you can join the code above into this "one-liner" (I didn't test this but it should work)
<input type="text" ng-model="content" ng-focus="$event.target.select()" />
Comments
-
Billy Coover almost 2 years
I have a text input. When the input receives focus I want to select the text inside of the input.
With jQuery I'd do it this way:
<input type="text" value="test" />
$("input[type=text]").click(function() { $(this).select(); // would select "test" in this example });
I've searched around to try and find the Angular way but most examples I'm finding are dealing with a directive that is watching a modal property for a change. I'm assuming I need a directive that is watching for an input that receives focus. How would I do that?
-
jack almost 11 yearsIf you want to do this without jquery, change element.click to element.bind('click', function() { ... } and element.select() to element[0].select()
-
Eliran Malka over 10 yearsNice and elegant. I would also explicitly restrict the directive to be applied as attribute (by returning an object literal and setting
restrict: 'A'
), as this directive aims for extending the behavior of an existing element. -
JoshMB about 10 yearsAs far as I can tell, this no longer supported. Angular throws an error: "Referencing DOM nodes in Angular expressions is disallowed!". See this thread for more info: groups.google.com/forum/#!topic/angular/bsTbZ86WAY4. The directive approach works well, however.
-
Onur Yıldırım about 10 yearsYou're right. This is the case for Angular 1.2+. I'll update the answer.
-
Vladimir Gordienko over 9 yearsI think this answer is better than the accepted, because it allow set cursor to some position in entered text, but, as a directive have own scope - i propose to rename focusedElement variable to isElementFocused and store there true or false
-
Piioo over 9 yearsDOM changes should be done in the directive, or not?
-
Precastic over 9 yearsFor some reason the other solutions didn't work for me but this did. I think the problem was that I already had a directive on the element which I was adding this click event to.
-
Dzmitry Lazerka over 9 years@Martin any idea how to do that on page open, without user click? The problem is that default value is set in another controller before my
selectOnLoad
directive link(). But in link(), although scope is already populated, element DOM is not yet synced with $scope, so when I call select(), element is still empty and nothing selected. The only way to work around that I found, is $timeout, but I feel that can stop working with some new Angular version. -
Robbie Smith over 9 yearsI get Uncaught TypeError: undefined is not a function on "this" for .select(); and yes jQuery 1.9.1 is included.
-
jcalfee314 over 9 yearsSeriously, even the onTextClick($event) is throwing the error now. Aside from the un-intuitive nature of this beast, how much is this inconvenience costing us in performance?
-
jcalfee314 over 9 yearsI'm giving up .. my angularjs app is going to be harder to use.
-
ak85 over 9 yearsthis works well on desktop/android but when I try on ipad it doesn't seem to work. Is there a known work around here?
-
Abraham Chan about 9 years
-
user1338062 about 9 yearsIn Firefox 38.0.5 clicking in the middle of the text first selects all, but then removes the selection, so this won't work.
-
user1338062 about 9 yearsThis seems the best way to go, but unfortunately it prevents selecting part of the text.
-
infomofo over 8 yearsI still had significant issues getting this to work on mobile safari. For one, the sample code only listens for "click" events and on mobile safari, the events are "touchstart" and "touchend". I also had issues with the automatic focusing causing the selection to end, so I had to prevent default behavior on touchend. Here's my modified version of the directive. gist.github.com/infomofo/4e9828fbd886eeb226a8
-
Blackfire over 8 yearsSyntax error corrected: last }); replace by: } }; });
-
Louis about 8 yearsThis one works for input type="number", which is great ! Thanks
-
Louis about 8 yearsHey, this works for Ionic in Android, but not in iOS...any idea why ? Thanks
-
Adam Reis almost 8 yearsNote that this won't work on
<input type='number'>
, see: stackoverflow.com/questions/21177489/… -
Langdon over 7 yearsSeems like you left some code behind when you adapted it from onClick... what's the point of
focusedElement
? -
Langdon over 7 yearsThis probably isn't going to ever work consistently without delaying
this.select
. -
pistol-pete over 7 yearsSimple and it works. This also allows for positioning of your cursor within the selected text, as discussed above.
-
mtfurlan about 7 yearsUsing
ng-focus
allows a user to select subsets if they really want to. -
Lex over 6 years@RobbieSmith I'm 3 years late, but change all instances of
this
toelement[0]
and it should work. I also recommend changingclick
tofocus
so that text will be selected if the user tabs into the input instead of clicking into it. -
Claudio Ferraro about 5 yearsOn angular 6 it's almost the same: Only replace ng-click with (click)="onTextClick($event); and in Your component onTexclick = function($event) { ...}
-
SwissCoder over 4 yearshow come so many people come up with all these complex answers, when the easiest way is here :D Thank you Adam
-
Eagle almost 4 yearsAgain, simplicity is the best over complexity. You follow KISS, you win. ;)