Input Number Type "Numeric Only"

How can I verify that the input is correct type="number"only if the value is numeric or null using only Reactive Forms (no directives)?
Only numbers [0-9]and. not allowed, "e" or any other characters.


What I have tried so far:

Template:

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

Component:

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

The problem is that when the user enters something that is not a number ("123e" or "abc"), the FormControl value becomes null, keep in mind, I do not want the field to be required, so if the field is really empty nullvalue must be valid.

- ( Chrome - "e", FireFox Safari ).

+18
5

HTML ngIf ,

<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 Validators - "^ [0-9] * $"

this.Mobile = new FormControl('', [
  Validators.required,
  Validators.pattern("^[0-9]*$"),
  Validators.minLength(8),
]);
+16

- , one , , , noStrings

    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;   
      } 
    }
+1

. , , 9 :

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

:

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

0

- .

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

, .

,

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

(this) , , , .

0

: , . . , , , . ntvFormValidity , ng-invalid.

: <input type="number" formControlName="num" placeholder="0" ntvFormValidity>

:

import { Directive, Host, Self, ElementRef, AfterViewInit } from '@angular/core';
import { FormControlName, FormControl, Validators } from '@angular/forms';

@Directive({
  selector: '[ntvFormValidity]'
})
export class NtvFormControlValidityDirective implements AfterViewInit {

  constructor(@Host() private cn: FormControlName, @Host() private el: ElementRef) { }

  /* 
  - Angular doesn't fire "change" events for invalid <input type="number">
  - We have to check the DOM object for browser native invalid state
  - Add custom validator that checks native invalidity
  */
  ngAfterViewInit() {
    var control: FormControl = this.cn.control;

    // Bridge native invalid to ng-invalid via Validators
    const ntvValidator = () => !this.el.nativeElement.validity.valid ? { error: "invalid" } : null;
    const v_fn = control.validator;

    control.setValidators(v_fn ? Validators.compose([v_fn, ntvValidator]) : ntvValidator);
    setTimeout(()=>control.updateValueAndValidity(), 0);
  }
}

, ElementRef FormControl, . @ViewChild, - . , , ElementRef.

Safari HTML Angular , "abc".

, , , , CVA , HTML.

- :

<my-input-number formControlName="num" placeholder="0">

PS: If there is a better way to get a FormControl for a directive, I suppose using Dependency Injection and providersin the declaration, please let me know so that I can update my directive (and this answer).

0
source

Source: https://habr.com/ru/post/1681272/


All Articles