À plusieurs endroits de mon application Angular, je dois effacer les entrées de l'utilisateur avec la touche ESC. Le problème est que je ne sais pas comment procéder avec les champs de saisie de texte (textarea s'efface correctement). Voir ce violon:
jsFiddle démonstration du problème
Contraignant:
<input ng-model="search.query" ui-keypress="{esc: 'keyCallback($event)'}" />
Rappel que j'utilise:
$scope.keyCallback = function($event) {
$event.preventDefault();
$scope.search.query = '';
}
Quelqu'un peut-il, s'il vous plaît, comprendre ce que je dois faire pour effacer la saisie de texte avec la touche Echap?
SOLUTION: Comme conseillé par bmleite , vous ne devriez pas écouter pour 'pression du clavier' mais pour 'keydown' _ et 'keyup' _ . Le problème était que "keydown" ne fonctionnait pas dans Firefox, donc seul "keyup" faisait le tour de magie d'écouter ESC. ;)
Violon de travail: http://jsfiddle.net/aGpNf/190/
SOLUTION UPDATE: À la fin, j'ai dû écouter à la fois les événements 'keydown' et 'keyup'. Parce que dans mon cas, FF réinitialise le champ de saisie lors de l'incrustation de la touche ESC à son état précédent. Donc 'keyup' efface le modèle et 'keydown' vérifie si le modèle est vide et effectue l'action appropriée. J'ai également besoin de défocaliser manuellement les entrées pour éviter que le texte ne réapparaisse.: /
La réponse acceptée ne fonctionne pas pour IE 10/11. Voici une solution basée sur une autre question qui fait:
Directive
.directive('escKey', function () {
return function (scope, element, attrs) {
element.bind('keydown keypress', function (event) {
if(event.which === 27) { // 27 = esc key
scope.$apply(function (){
scope.$eval(attrs.escKey);
});
event.preventDefault();
}
});
scope.$on('$destroy', function() {
element.unbind('keydown keypress')
})
};
})
HTML:
<input ... ng-model="filter.abc" esc-key="resetFilter()" >
Ctrl
$scope.resetFilter = function() {
$scope.filter.abc = null;
};
Je résous ce problème comme ceci (Controller as vm Syntax):
HTML
<input ... ng-model="vm.item" ng-keyup="vm.checkEvents($event)">
Manette
...
vm.checkEvents = function ($event) {
if ($event.keyCode == 27) {
vm.item = "";
}
}
Écoutez les événements 'keydown' ou 'keyup' au lieu de 'keypress':
<input ng-model="search.query" ui-keydown="{esc: 'keyCallback($event)'}" />
Version angulaire 2 qui met également à jour ngModel
Directif
import { Directive, Output, EventEmitter, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[escapeInput]'
})
export class escapeInput {
@Output() ngModelChange: EventEmitter<any> = new EventEmitter();
private element: HTMLElement;
private KEY_ESCAPE: number = 27;
constructor(private elementRef: ElementRef) {
this.element = elementRef.nativeElement;
}
@HostListener('keyup', ['$event']) onKeyDown(event) {
if (event.keyCode == this.KEY_ESCAPE) {
event.target.value = '';
this.ngModelChange.emit(event.target.value);
}
}
}
Usage
<input escapeInput class="form-control" [(ngModel)]="modelValue" type="text" />
Lorsque vous appuyez sur la touche Échap, appuyez par défaut sur IE10/11 pour effacer la zone de texte. Elle est une fonctionnalité du navigateur. Pour d'autres, nous pouvons utiliser
element.bind('keydown keypress', function (e) {
if(e.which === 27) { // 27 = esc key
// code for clearing data
e.preventDefault(); // prevents the default function of the event
}
});
Pour l'instant, avec Angular v4, cela fonctionne: (keyup.esc)="callback()"
J'ai réussi à construire une directive
effaçant directement ng-model
de l'élément d'entrée et fonctionnant correctement dans Firefox
. Pour cela, je dois vérifier si la valeur est déjà effacée (modelGetter(scope)
) et envelopper l'attribution à la méthode zéro $timeout
(pour l'appliquer dans le prochain appel de résumé).
mod.directive('escClear', ['$timeout', '$parse', function($timeout, $parse) {
return {
link : function(scope, element, attributes, ctrl) {
var modelGetter = $parse(attributes.ngModel);
element.bind('keydown', function(e) {
if (e.keyCode === $.ui.keyCode.ESCAPE && modelGetter(scope)) {
$timeout(function() {
scope.$apply(function () {modelGetter.assign(scope, '');});
}, 0);
}
});
}
};
}]);
Ma propriété $
est jQuery
, n'hésitez pas à la remplacer par nombre magique27
.