J'ai une saisie de texte. Lorsque l'entrée reçoit le focus, je veux sélectionner le texte à l'intérieur de l'entrée.
Avec jQuery, je le ferais de cette façon:
<input type="text" value="test" />
$("input[type=text]").click(function() {
$(this).select();
// would select "test" in this example
});
J'ai cherché autour de moi pour essayer de trouver la méthode angulaire, mais la plupart des exemples que je trouve concernent une directive qui surveille un changement de propriété modale. Je suppose que j'ai besoin d'une directive qui surveille une entrée qui reçoit le focus. Comment je ferais ça?
La manière de procéder dans Angular consiste à créer une directive personnalisée qui effectue la sélection automatique pour vous.
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)
}
});
}
};
}]);
Appliquez la directive comme ceci:
<input type="text" value="test" select-on-click />
Update1 : Suppression de la dépendance de jQuery.
Update2 : Restreindre comme attribut.
Update3 : Fonctionne dans Safari mobile. Permet de sélectionner une partie du texte (nécessite IE> 8).
Voici une directive améliorée qui évite de resélectionner le texte lorsque l'utilisateur clique pour positionner le curseur dans la zone de saisie.
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;
});
}
};
})
C'est une vieille réponse, pour Angular 1.x
La meilleure façon de le faire est d'utiliser la directive intégrée ng-click
:
<input type="text" ng-model="content" ng-click="$event.target.select()" />
MODIFIER:
Comme JoshMB a gentiment rappelé; référencer des nœuds DOM dans Angular 1.2+ n'est plus autorisé. Donc, j'ai déplacé $event.target.select()
dans le contrôleur:
<input type="text" ng-model="content" ng-click="onTextClick($event)" />
Puis dans votre contrôleur:
$scope.onTextClick = function ($event) {
$event.target.select();
};
Aucune des solutions proposées n'a bien fonctionné pour moi. Après de rapides recherches, j'ai trouvé ceci:
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;
});
}
}
});
C'est un mélange de plusieurs solutions proposées, mais fonctionne à la fois sur le clic et le focus (pensez autofocus) et permet la sélection manuelle de la valeur partielle dans l'entrée.
Pour moi, ng-click n'avait pas de sens, car vous ne pouviez jamais repositionner le curseur sans sélectionner à nouveau tout le texte, j'ai trouvé que c'était annulant. Ensuite, il est préférable d’utiliser ng-focus, car le texte n’est sélectionné que si l’entrée n’a pas été focalisée. Si vous cliquez à nouveau pour repositionner le curseur, le texte se désélectionne comme prévu et vous pouvez écrire entre les deux.
J'ai trouvé cette approche comme étant le comportement attendu de l'UX.
Utilisez ng-focus
Option 1: code séparé
<input type="text" ng-model="content" ng-focus="onTextFocus($event)" />
et dans le contrôleur
$scope.onTextFocus = function ($event) {
$event.target.select();
};
Option 2: comme alternative, vous pouvez joindre le code ci-dessus dans ce "one-liner" (je n'ai pas testé cela, mais cela devrait fonctionner)
<input type="text" ng-model="content" ng-focus="$event.target.select()" />
Dans angular 2, cela fonctionnait pour moi, à la fois sous Chrome et Firefox:
<input type="text" (mouseup)="$event.target.select()">
La réponse acceptée utilise l'événement click. Toutefois, si vous utilisez l'événement focus, seul le premier clic déclenche l'événement. Il se déclenche également lorsqu'une autre méthode est utilisée pour se concentrer sur l'entrée (comme appuyer sur l'onglet ou appeler le code dans le code).
Cela évite également de vérifier si l'élément est déjà concentré, comme le suggère la réponse de Tamlyn.
app.directive('selectOnClick', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.on('focus', function () {
this.select();
});
}
};
});
Aucune directive nécessaire, ajoutez simplement onfocus="this.select()"
javascript natif à l'élément d'entrée ou à la zone de texte.
La version modifiée qui a fonctionné pour moi . Le premier clic sélectionne le texte, le second clic sur le même élément désélectionne le texte
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
});
}
}
})