40 votes

Moyen approprié de restreindre les valeurs de saisie de texte (par exemple, uniquement les chiffres)

Est-il possible de mettre en place un input qui permet de taper uniquement des chiffres à l'intérieur sans manipulation manuelle de event.target.value ?

Dans React, il est possible de définir value et, par la suite, la modification de l'entrée sera fondamentalement liée à la valeur (il n'est pas possible de la modifier sans la propriété value changement). Voir exemple . Et cela fonctionne très bien sans aucun effort.

Dans Angular 2, il est possible de définir [value] mais il ne fera que fixer la valeur au départ, et par la suite input n'est pas empêché de procéder à des modifications.

Je jouais avec ngModel y [value] / (input) voir exemple .

Mais dans les deux cas, il y a un problème essentiel :

  1. lorsque vous tapez 10 (la valeur du modèle est 10 ; la valeur d'entrée est 10) - correct
  2. lorsque vous tapez 10d ensuite (la valeur du modèle est 10 - non modifiée, tous les chiffres manquants ont été supprimés ; la valeur d'entrée est 10d) - incorrect, car la valeur du modèle est la même que précédemment.
  3. lorsque vous tapez 10d3 - (la valeur du modèle est 103 ; la valeur d'entrée est 103) - correct

Comment faire ce composant simple (à première vue), sans manipuler manuellement event.target.value ?...

UPDATE Je ne cherche pas de HTML5 natif input[number] élément ici. L'entrée des chiffres ici est juste pour l'exemple - il pourrait y avoir beaucoup plus de tâches où j'ai besoin de restreindre le texte d'entrée.

De plus, input[number] est 1) ne m'empêche pas de taper 10ddd et 2) (moins important) contient des flèches dont je n'ai pas besoin.

Et le problème ici est de prevenir l'utilisateur de taper quelque chose au-delà des valeurs restreintes, au lieu de permettre pour saisir quoi que ce soit et valider après coup

5 votes

Je déteste qu'on doive toujours avoir cette discussion. A un moment donné, nous avons besoin d'une entrée standard qui fasse ça tout de suite. Elle devrait accepter combien de chiffres, sans vous permettre d'entrer des caractères, négatifs ou non. Je sais qu'il existe un machin numérique HTML 5, mais nous n'avons pas encore atteint le nirvana. Je suis fatigué de devoir écrire ce code pour chaque framework, etc.

0 votes

Ce problème peut être résolu avec la réponse donnée dans le document : stackoverflow.com/questions/41465542/

0 votes

Pour l'amour de Dieu ne faites pas ça à moins que vous ne détestiez vos utilisateurs. Toujours permettre une entrée libre et vérifier/nettoyer plus tard. Si vous faites cela, vous, l'utilisateur de l'OS, créerez probablement un champ inaccessible. Est tab une touche numérique ? Qu'en est-il ctrl-v ? Non ? Oups, l'utilisateur est maintenant coincé dans votre champ parce que vous venez de tout empêcher. - Au lieu de cela, facilitez les choses en définissant le bon type d'entrée, puis en définissant une balise pattern pour le valider, et c'est tout.

41voto

weizong song Points 369

Dans component.ts, ajoutez cette fonction

_keyUp(event: any) {
    const pattern = /[0-9\+\-\ ]/;
    let inputChar = String.fromCharCode(event.key);

    if (!pattern.test(inputChar)) {
      // invalid character, prevent input
      event.preventDefault();
    }
}

Dans votre modèle, utilisez les éléments suivants

<input(keyup)="_keyUp($event)">

Cela permettra de capturer l'entrée avant qu'angular2 ne capture l'événement.

1 votes

L'événement KeyPress est invoqué uniquement pour les touches de caractères (imprimables), l'événement KeyDown est déclenché pour toutes les touches, y compris les touches non imprimables telles que Control, Shift, Alt, BackSpace, etc.

15 votes

Même cela n'est pas suffisant, il ne limitera pas les valeurs copiées-collées

0 votes

Les événements de pression sur le clavier ne sont pas le bon crochet à utiliser pour la détection de changement

32voto

Abhijeet Points 401

Après avoir fait beaucoup de recherches, j'ai finalement créé une fonction qui répond entièrement à cette exigence. La fonction que j'ai créée restreint tous les caractères spéciaux et ne permet que les alphabets et les nombres et cette fonction fonctionne bien pour les deux, que vous fassiez un copier-coller ou que vous tapiez les deux. J'espère que cela fonctionne :)

 public inputValidator(event: any) {
    //console.log(event.target.value);
    const pattern = /^[a-zA-Z0-9]*$/;   
    //let inputChar = String.fromCharCode(event.charCode)
    if (!pattern.test(event.target.value)) {
      event.target.value = event.target.value.replace(/[^a-zA-Z0-9]/g, "");
      // invalid character, prevent input

    }
  }

     <input type="text" [(ngModel)]="abc.abc" (input)="inputValidator($event)" />

Comment vous utilisez -
1) Ajoutez la méthode ci-dessus dans votre composant de classe du fichier ts.
2) Appel de la méthode inputValidator($event) sur l'événement de saisie .

0 votes

Exactement ce dont j'avais besoin. Merci !

0 votes

J'ai investi beaucoup de temps dans cette solution. Il semblait pour travailler. Mais j'ai remarqué qu'avec Angular 7 et une limite de deux caractères sur un texte d'entrée HTML, bien que les caractères indésirables n'apparaissent pas dans la zone de texte, le dernier caractère indésirable apparaît dans la variable liée ! J'ai alors essayé la solution de Ben Gulapa à ce lien et cela a fonctionné : stackoverflow.com/questions/41465542/

0 votes

Mais j'apprécie quand même les informations d'Abhijeet. J'en ai appris davantage sur les expressions régulières et je les ai appliquées à la solution de Ben Gulapa, que j'ai modifiée pour que l'expression régulière devienne un attribut de la directive.

19voto

Steve Paul Points 135

Le plugin inputmask est le meilleur outil pour cela. . Il est extrêmement flexible dans la mesure où vous pouvez fournir n'importe quelle expression rationnelle pour limiter l'entrée. Il ne nécessite pas non plus JQuery.

Étape 1 : Installez le plugin :

npm install --save inputmask

Etape 2 : créer une directive pour envelopper le masque d'entrée :

import {Directive, ElementRef, Input} from '@angular/core';
import * as Inputmask from 'inputmask';

@Directive({
  selector: '[app-restrict-input]',
})
export class RestrictInputDirective {

  // map of some of the regex strings I'm using (TODO: add your own)
  private regexMap = {
    integer: '^[0-9]*$',
    float: '^[+-]?([0-9]*[.])?[0-9]+$',
    words: '([A-z]*\\s)*',
    point25: '^\-?[0-9]*(?:\\.25|\\.50|\\.75|)$'
  };

  constructor(private el: ElementRef) {}

  @Input('app-restrict-input')
  public set defineInputType(type: string) {
    Inputmask({regex: this.regexMap[type], placeholder: ''})
      .mask(this.el.nativeElement);
  }

}

Étape 3 :

<input type="text" app-restrict-input="integer">

Consultez leur documentation github pour plus d'informations.

0 votes

ERREUR dans /Users/xxx/Work/dashboard/dashboard/lib/utils/restrict-input.directive.ts (41,46) : La propriété 'includes' n'existe pas sur le type 'string[]'.

2 votes

@BBaysinger : A oui je devrais probablement modifier mon code pour être plus rétrocompatible. Il s'agit d'une fonctionnalité d'es2016. Vous pouvez soit utiliser un polyfill Array.includes, soit modifier ce code comme suit : Object.keys(this.patterns).indexOf(type) !== -1 ? type : this.patterns[type] ;

2 votes

Note : cela ne fonctionnera pas sur une entrée avec type="nombre".

8voto

RohanArihant Points 660

Réponse testée par moi :

formulaire.html

<input type="text" (keypress)="restrictNumeric($event)">

form.component.ts :

public restrictNumeric(e) {
  let input;
  if (e.metaKey || e.ctrlKey) {
    return true;
  }
  if (e.which === 32) {
   return false;
  }
  if (e.which === 0) {
   return true;
  }
  if (e.which < 33) {
    return true;
  }
  input = String.fromCharCode(e.which);
  return !!/[\d\s]/.test(input);
 }

0 votes

Comment régler le problème si quelqu'un veut copier-coller avec votre solution... votre solution est très bien mais je veux aussi qu'elle limite le copier-coller.

6voto

eltonkamami Points 3527

Vous pouvez utiliser l'entrée HTML5 de type nombre.

Il n'accepte aucun caractère dans sa déclaration

<input type="number" [(model)]='myvar' min=0 max=100 step=5 />

Voici un exemple de son utilisation avec angular 2 [(model)]

http://www.webpackbin.com/VJNUNF0M-

1 votes

Permet de saisir des caractères sur IE11

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X