angularjs angularjs-directive

angularjs - ng angular



Seleccionar texto en el foco de entrada (8)

Aquí hay una directiva mejorada que evita volver a seleccionar el texto cuando el usuario hace clic para colocar el cursor en el cuadro de entrada.

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; }); } }; })

Tengo una entrada de texto. Cuando la entrada recibe el foco, quiero seleccionar el texto dentro de la entrada.

Con jQuery lo haría de esta manera:

<input type="text" value="test" />

$("input[type=text]").click(function() { $(this).select(); // would select "test" in this example });

He buscado para encontrar la forma Angular, pero la mayoría de los ejemplos que encuentro se refieren a una directiva que está mirando una propiedad modal para un cambio. Supongo que necesito una directiva que esté buscando una entrada que reciba atención. ¿Como podría hacerlo?


En angular 2, esto funcionó para mí, tanto en Chrome como en Firefox:

<input type="text" (mouseup)="$event.target.select()">


La forma de hacerlo en Angular es crear una directiva personalizada que haga la autoselección por usted.

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) } }); } }; }]);

Aplicar la directiva de esta manera:

<input type="text" value="test" select-on-click />

Ver demostración

Actualización1 : se eliminó la dependencia de jQuery.

Actualización2 : Restringir como atributo.

Actualización3 : Funciona en Safari móvil. Permite seleccionar parte del texto (requiere IE> 8).


La respuesta aceptada es usar el evento click; sin embargo, si usa el evento focus, solo el primer clic activará el evento y también se activará cuando se use algún otro método para enfocar la entrada (como pulsar la pestaña o llamar al foco en el código).

Esto también hace que sea innecesario verificar si el elemento ya está enfocado como sugiere la respuesta de Tamlyn.

app.directive(''selectOnClick'', function () { return { restrict: ''A'', link: function (scope, element, attrs) { element.on(''focus'', function () { this.select(); }); } }; });


Ninguna de las soluciones propuestas funcionó bien para mí. Después de una investigación rápida, se me ocurrió esto:

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; }); } } });

Es una combinación de varias soluciones propuestas, pero funciona tanto en clic y enfoque (pensar en enfoque automático) y permite la selección manual de valor parcial en la entrada.


Para mí, ng-click no tenía sentido, porque nunca podrías reposicionar el cursor sin volver a seleccionar todo el texto, encontré que esto era molesto. Entonces es mejor usar ng-focus, porque el texto se selecciona solo si la entrada no se centró, si vuelve a hacer clic para volver a posicionar el cursor, el texto simplemente deselecciona, como se esperaba, y puede escribir en medio.

Encontré este enfoque como el comportamiento de UX esperado.

Use ng-focus

Opción 1: código separado

<input type="text" ng-model="content" ng-focus="onTextFocus($event)" />

y en el controlador

$scope.onTextFocus = function ($event) { $event.target.select(); };

Opción 2: como alternativa, puede unir el código anterior en este "one-liner" (no lo probé pero debería funcionar)

<input type="text" ng-model="content" ng-focus="$event.target.select()" />


Versión modificada que funcionó para mí. El primer clic selecciona texto, segundo clic en el mismo elemento deselecciona el texto

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 }); } }

})


Esta es una respuesta antigua, para Angular 1.x

Una mejor forma de hacerlo es mediante el uso de la directiva integrada ng-click :

<input type="text" ng-model="content" ng-click="$event.target.select()" />

EDITAR:

Como JoshMB ha recordado amablemente; hacer referencia a los nodos DOM en Angular 1.2+ ya no está permitido. Por lo tanto, he movido $event.target.select() al controlador:

<input type="text" ng-model="content" ng-click="onTextClick($event)" />

Luego en tu controlador:

$scope.onTextClick = function ($event) { $event.target.select(); };

Aquí hay un ejemplo de violín .