Reputation: 3837
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?
Upvotes: 122
Views: 106235
Reputation: 1579
$event.target.select()
not resolved in Angular template
The event target can be any HTML Element and a cast to the application interface should be applied here (like HTMLSelectElement
), however, Angular expressions don't allow casting. The best workaround would be to wrap $event.target
with $any()
so, it should look like this: (focus) = $any($event.target).select()
further explanation found here here.
Upvotes: -1
Reputation: 1909
The easiest way to select all text on click or focus or tab, is !!!:
<input (focus)="inputFocused($event)">
...
inputFocused(event: any){
event.target.select()
}
Upvotes: 3
Reputation: 4483
No directives needed, just add onfocus="this.select()"
native javascript to the input element or text area.
Upvotes: 11
Reputation: 33674
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.
Upvotes: 42
Reputation:
In angular 2, this worked for me, both in Chrome & Firefox:
<input type="text" (mouseup)="$event.target.select()">
Upvotes: 8
Reputation: 7207
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()" />
Upvotes: 12
Reputation: 1
Modified version that worked for me. First click selects text, second click on same element deselects text
module.directive('selectOnClick', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var prevClickElem = null; //Last clicked element
var ignorePrevNullOnBlur = false; //Ignoring the prevClickElem = null in Blur massege function
element.on('click', function () {
var self = this;
if (prevClickElem != self) { //First click on new element
prevClickElem = self;
$timeout(function () { //Timer
if(self.type == "number")
self.select();
else
self.setSelectionRange(0, self.value.length)
}, 10);
}
else { //Second click on same element
if (self.type == "number") {
ignorePrevNullOnBlur = true;
self.blur();
}
else
self.setSelectionRange(self.value.length, self.value.length); //deselect and set cursor on last pos
}
});
element.on('blur', function () {
if (ignorePrevNullOnBlur == true)
ignorePrevNullOnBlur = false; //blur called from code handeling the second click
else
prevClickElem = null; //We are leaving input box
});
}
}
})
Upvotes: 0
Reputation: 4774
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.
Upvotes: 15
Reputation: 8866
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).
Upvotes: 217
Reputation: 704
The accepted answer is using the click event however if you use the focus event, only the 1st click will fire the event and it also fires when some other method is used to focus on the input (like hitting tab or calling focus in code).
This also makes it unnecessary to check if the element is already focused as Tamlyn's answer suggests.
app.directive('selectOnClick', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.on('focus', function () {
this.select();
});
}
};
});
Upvotes: 6
Reputation: 23602
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;
});
}
};
})
Upvotes: 44