Tipo di Input numero di “solo valore numerico” convalida

Come posso convalidare l’input di type="number" per essere valido solo se il valore è numerico o null utilizzando solo Reattiva Forme (non direttive)?

Solo numeri [0-9] e . sono ammessi, senza la “e” o altri caratteri.


Quello che ho provato finora:

Modello:

<form [formGroup]="form" novalidate>
    <input type="number" formControlName="number" id="number">
</form>

Componenti:

export class App {
  form: FormGroup = new FormGroup({});

  constructor(
    private fb: FormBuilder,
  ) {
    this.form = fb.group({
      number: ['', [CustomValidator.numeric]]
    })
  }
}

CustomValidator:

export class CustomValidator{
  //Number only validation
  static numeric(control: AbstractControl) {
    let val = control.value;

    if (val === null || val === '') return null;

    if (!val.toString().match(/^[0-9]+(\.?[0-9]+)?$/)) return { 'invalidNumber': true };

    return null;
  }
}

Plunker

Il problema è che quando un utente entra in qualcosa che non è un numero (“123e” o “abc”) il FormControl valore diventa null, tenere a mente non voglio che il campo sia necessaria in modo che se il campo è davvero vuoto null valore dovrebbe essere valido.

Cross browser il supporto è importante (Chrome numero di campi di input non permettono all’utente di inserire le lettere – ad eccezione di “e”, ma FireFox e Safari).

avete mai trovare una risposta accettabile per questo? Ho appena imbattuto nello stesso problema quando ho deciso di passare da type="text" per type="number". Non capisco perché Angolare cambia il valore del controllo, ma non fa nulla di validità. Sembra un bug per me.
Per l’esatta situazione descritta, no. Unfortunetly…
Quindi non ho il mio attuazione per questo ancora, ma ho intenzione di implementare un custom ControlValueAccessor per superare questo problema. Ho già una data personalizzata di controllo che fa qualcosa di simile per memorizzare un conforme allo standard ISO data stringa nella forma del valore, invece di “10/16/2018” stringa che viene visualizzata in ingresso. Vorrei aggiungere la mia soluzione qui, una volta che ho il bug per quanto riguarda type="number" volte questo mese, si spera.

OriginaleL’autore Mihailo | 2017-07-12

4 Replies
  1. 14

    In un file HTML è possibile aggiungere ngIf per questo motivo

    <div class="form-control-feedback" *ngIf="Mobile.errors && (Mobile.dirty || Mobile.touched)">
            <p *ngIf="Mobile.errors.pattern" class="text-danger">Number Only</p>
          </div>
    

    .ts file è possibile aggiungere i Validatori modello – “^[0-9]*$”

    this.Mobile = new FormControl('', [
      Validators.required,
      Validators.pattern("^[0-9]*$"),
      Validators.minLength(8),
    ]);
    
    Il requisito è che il campo è nullable, tipo di numero, non di direttive di utilizzo, se non vuoto solo numeri da 0 a 9 sono ammessi. Si prega di fornire un anteprima della soluzione, questa risposta non è davvero.

    OriginaleL’autore Ishara Madawa

  2. 1

    Il modo più semplice sarebbe quella di utilizzare una libreria come questa uno e in particolare si desidera noStrings per essere vero

        export class CustomValidator{   //Number only validation   
          static numeric(control: AbstractControl) {
            let val = control.value;
    
            const hasError = validate({val: val}, {val: {numericality: {noStrings: true}}});
    
            if (hasError) return null;
    
            return val;   
          } 
        }
    
    Come posso implementare questo quando il FormControls valore è null non appena l’input contiene lettere?
    Ho modificato la risposta, per dare un’idea di come si potrebbe fare
    Sì grazie, ma questo non risolve il nocciolo del problema. Se l’input contiene lettere let val = control.value = null. Questo è un problema di come angolare analizza gli ingressi valore quando è di tipo numerico. Se l’input è di tipo testo il mio convalida funzionerebbe perfettamente.

    OriginaleL’autore luanped

  3. 0

    È necessario utilizzare le espressioni regolari per il vostro custom validator. Per esempio, ecco il codice che permette solo 9 cifre nei campi di input:

    function ssnValidator(control: FormControl): {[key: string]: any} {
      const value: string = control.value || '';
      const valid = value.match(/^\d{9}$/);
      return valid ? null : {ssn: true};
    }
    

    Dare un’occhiata a un esempio di applicazione qui:

    https://github.com/Farata/angular2typescript/tree/master/Angular4/form-samples/src/app/reactive-validator

    O semplicemente fare una prova con let regex = /\D+/; regex.exec("stringToT3est"). Se non contiene cifre, verrà restituito null. Ma questo non avrebbe funzionato per un segno decimale.
    Ho provato a usare una regex, ma non è questo il nocciolo del problema. Quando l’ingresso è di tipo numerico, e il valore non è un numero (“123e” o “abc”) il FormControl valore diventa null
    Ok, ho capito il tuo problema ora, non si tratta di logica all’interno CustomValidator, ma in che modo ottenere l’ingresso in primo luogo piuttosto che in un null. Sarebbe possibile cambiare il vostro ingresso dal numero di tipo di tipo di testo (o semplicemente eliminarlo e valori di default per il testo) e convalidare quel modo? L’utente può quindi digitare una stringa qualsiasi, ma il validatore può quindi rifiutare
    Ecco come ho risolto così lontano, ma quando l’input è di tipo testo ho perso il browser funzionalità associata agli ingressi di tipo numero. Soprattutto il modo in cui l’input atti su dispositivi mobili.
    Ho paura che per questo caso dovrete tenerlo testo e, se si desidera che l’incremento del numero di funzionalità, non sarà difficile creare un controllo personalizzato. È nella specifica HTML in modo tale che un testo di input di un numero, verrà restituito il valore null per qualcosa come ‘2e’, non c’è modo di accedere al valore grezzo : html.spec.whatwg.org/multipage/…

    OriginaleL’autore Yakov Fain

  4. 0

    A volte è più facile provare qualcosa di semplice come questo.

    validateNumber(control: FormControl): { [s: string]: boolean } {
    
      //revised to reflect null as an acceptable value 
      if (control.value === null) return null;
    
      //check to see if the control value is no a number
      if (isNaN(control.value)) {
        return { 'NaN': true };
      }
    
      return null; 
    }
    

    Spero che questo aiuta.

    aggiornato al commento
    È necessario chiamare il validatore come questo

    number: new FormControl('',[this.validateNumber.bind(this)])
    

    Bind () è necessario se si sta mettendo il validatore del componente che è come lo faccio.

    Hai provato questa? Questo non convalida quando uso l’id all’interno del CustomValidator (nel mio Plunker)
    Ce l’ho in esecuzione nel mio codice, ma non mettere in plunker, si tenta di impostare esempio quando ho un paio di minuti, ma l’ho fatto aggiornare la risposta per includere il template
    Si prega di tenere presente che il nucleo del problema è come Firefox e alcuni altri si comportano. Se si dispone di un numero di ingresso e si entra "123e" che non è un numero e il valore dell’input è null ma considero l’ingresso valido se il valore è null. Il solo 100% di successo modo che ho trovato è quello di ascoltare gli eventi di input e di controllo i tasti + copia/incolla di convalida.
    se si desidera null, per essere validi, quindi basta controllare se (di controllo.value === null){ return null;} il codice che permetta null essere ok. Se questo è accettabile, quindi vorrei modificare il codice.
    control.value === null sarà vero sia se l’ingresso è 123e o è vuoto.

    OriginaleL’autore Ken

Lascia un commento