Sangwin Gawande
Sangwin Gawande

Reputation: 8166

Angular 4 Form Validators - minLength & maxLength does not work on field type number

I am trying to develop a contact form, I want user to enter phone number values between length 10-12.

Notably same validation is working on Message field, Its only number field which is giving me trouble.

I found this answer but it is of no use for me.

I have code like following :

HTML :

<form [formGroup]="myForm" (ngSubmit)="myFormSubmit()">
      <input type="number" formControlName="phone" placeholder="Phone Number">
      <input type="text" formControlName="message" placeholder="Message">
       <button class="button" type="submit" [disabled]="!myForm.valid">Submit</button>
</form>

TS :

this.myForm = this.formBuilder.group({
     phone: ['',  [Validators.required, Validators.minLength(10), Validators.maxLength(12)]],
     message: ['',  [Validators.required, Validators.minLength(10), Validators.maxLength(100)]]
});`

Upvotes: 59

Views: 199816

Answers (14)

Eli
Eli

Reputation: 1846

In my case I used maxLength instead of maxlength (notice the lowercase l ) in the template.

Upvotes: 0

Nagender Pratap Chauhan
Nagender Pratap Chauhan

Reputation: 2204

I have a trick that 100% work.

Define input of type 'text' and not 'number'.

For eg:

<input placeholder="OTP" formControlName="OtpUserInput" type="text">

Then use pattern which is part of Validation.

Like :

this.ValidOtpForm = this.formbuilder.group({
             OtpUserInput: new FormControl(
              { value:'', disabled: false },
          [
          Validators.required,
          Validators.minLength(6),
          Validators.pattern('[0-9]')
        ]),
});

It means we define input type text that is suitable for min length and we also define pattern(validation) for numeric value so that we can achieve both validation.

Remaining code :

<mat-error *ngIf="RegistrationForm.controls['Password'].hasError('minlength')">Use 6 or more characters with a mix of letters</mat-error>
<mat-error *ngIf="ValidOtpForm.controls['OtpUserInput'].hasError('pattern')">Please enter numeric value.</mat-error>

Upvotes: 16

Chandru
Chandru

Reputation: 11184

try this working sample code :

component.html

<div class="container">
    <form [formGroup]="myForm" 
    (ngFormSubmit)="registerUser(myForm.value)" novalidate>
        <div class="form-group" [ngClass]="{'has-error':!myForm.controls['phone'].valid}">
            <label for="phone">Email</label>
            <input type="phone" formControlName="phone" placeholder="Enter Phone" 
            class="form-control">
            <p class="alert alert-danger" *ngIf="myForm.controls['phone'].hasError('minlength')">
                Your phone must be at least 5 characters long.
            </p>
            <p class="alert alert-danger" *ngIf="myForm.controls['phone'].hasError('maxlength')">
                Your phone cannot exceed 10 characters.
            </p>
            <p class="alert alert-danger" *ngIf="myForm.controls['phone'].hasError('required') && myForm.controls['phone'].dirty">
                phone is required
            </p>
        </div>
        <div class="form-group text-center">
            <button type="submit" class="btn btn-primary" [disabled]="!myForm.valid">Submit</button>
        </div>
    </form>
</div>

component.ts

import { FormGroup, FormBuilder, Validators } from '@angular/forms';

export class AppComponent implements OnInit {
    myForm: any;
    constructor(private formBuilder: FormBuilder) { }
    
    ngOnInit() {
        this.myForm = this.formBuilder.group({
            phone: [null, Validators.compose([Validators.required, Validators.minLength(5), Validators.maxLength(10)])]
        });
    }
}

Upvotes: 19

NaN
NaN

Reputation: 9094

<mat-error>
   <span *ngIf="phone.errors?.required">campo obrigatório</span>
   <span *ngIf="phone.errors?.minlength">o nº deve conter no mínimo 13 dígitos</span>
   <span *ngIf="phone.errors?.maxlength">o nº deve conter no máximo 13 dígitos</span>
</mat-error>

Upvotes: 0

Sangwin Gawande
Sangwin Gawande

Reputation: 8166

Used it like following and worked perfectly :

phone: ['',  [Validators.required, Validators.min(10000000000), Validators.max(999999999999)]],

customValidationService :

import { AbstractControl, ValidatorFn } from '@angular/forms';

export class customValidationService {
   static checkLimit(min: number, max: number): ValidatorFn {
    return (c: AbstractControl): { [key: string]: boolean } | null => {
        if (c.value && (isNaN(c.value) || c.value < min || c.value > max)) {
            return { 'range': true };
        }
        return null;
    };
  }
}

Upvotes: 34

Fateh Mohamed
Fateh Mohamed

Reputation: 21377

You can use a pattern instead to validate your phone number, and change your input type to text

<input type="text" formControlName="phone" placeholder="Phone Number">

and use this pattern for phone number tha have a length between 10 and 12

phonePattern = /^[0-9]{10,12}$/;

and change the validator on your form control

phone: ['',  [Validators.required, Validators.pattern(this.phonePattern)]],

and you can display the error:

<div *ngIf="myForm.get('phone').invalid">
      <div class="error-message invalid-feedback" *ngIf="myForm.get('phone').hasError('required')">
        required!
      </div>
      <div class="error-message invalid-feedback" *ngIf="myForm.get('phone').hasError('pattern')">
        invalid!
      </div>
</div>

Upvotes: 3

aman raj
aman raj

Reputation: 193

This trick will be helpful

In .html file

 <input type="text" (keyup)="onKeyUp($event)" formControlName="phone" placeholder="Phone Number">

In .ts file

The below code restrict string characters

    public onKeyUp(event: any) {
    const NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/;
    let newValue = event.target.value;
    let regExp = new RegExp(NUMBER_REGEXP);

    if (!regExp.test(newValue)) {
      event.target.value = newValue.slice(0, -1);
    }
   }

and other validation

phone: ['', Validators.compose([
        Validators.required, 
         Validators.pattern('^[0-9]{0,30}$')])
      ])],

The above pattern code allow number upto 30 digits. If you want minimum two digits, you can do like this

 Validators.pattern('^[0-9]{2,30}$')

Upvotes: 5

laurensdewaele
laurensdewaele

Reputation: 17

Keep <input type="number" /> and just transform the int values to strings.

const phoneControl: FormControl = this.myForm.controls.phone;

// Do not forget to unsubscribe

phoneControl.valueChanges.subscribe(v => {

  // When erasing the input field, cannot read toString() of null, can occur
  phoneControl.setValue((v && v.toString()) || null, { emitEvent: false });
});

Upvotes: 0

Prachi Shah
Prachi Shah

Reputation: 88

If you want to validate a field by multiple validators then, You should try this

phone: ['', Validators.compose([
        Validators.required, 
        Validators.minLength(10),
        Validators.maxLength(12)])
      ])],

Upvotes: -1

Jitendra G2
Jitendra G2

Reputation: 1206

Use Compose() method, compose multiple validators into a single function.

Update .TS file as below,

this.myForm = this.formBuilder.group({ phone: ['', Validators.compose([Validators.required, Validators.minLength(10), Validators.maxLength(12)])], message: ['', Validators.compose([Validators.required, Validators.minLength(10), Validators.maxLength(100)])] });

Upvotes: -2

Sampath Kumar
Sampath Kumar

Reputation: 4463

The Form Validation of multiple parameters or multiple conditions should be composed as single validator otherwise you will get observable or promise error:

phone: ['',  Validators.compose([Validators.required,Validators.min(10000000000), Validators.max(999999999999)])],

Upvotes: 1

Chris Halcrow
Chris Halcrow

Reputation: 31950

For a number field, you can validate min and max values using built in Angular validation, like this:

.ts

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

private myNumberFieldMin: number = 1;
private myNumberFieldMax: number = 1000000;

constructor() {
      this.myForm = this.formBuilder.group({
        myNumberField
      })

this.myForm.controls.myNumberField.setValidators([
  Validators.min(this.myNumberFieldMin),
  Validators.max(this.myNumberFieldMax)
]);

html

<form [formGroup]="myForm">
  <input type="number" formControlName="myNumberField">

  <div *ngIf="this.myForm.controls['myNumberField'].errors && this.myForm.controls['myNumberField'].errors.min">
    <span class="error-message">Value must be at least {{myNumberFieldMin}}</span>
  </div>
  <div *ngIf="this.myForm.controls['myNumberField'].errors && this.myForm.controls['myNumberField'].errors.max">
    <span class="error-message">Maximum value is {{myNumberFieldMax}}</span>
  </div>
</form>

Upvotes: 0

Tabish Zaman
Tabish Zaman

Reputation: 292

<div nz-col [nzXs]="24" [nzSm]="12" nz-form-control nzHasFeedback>
                                <nz-input formControlName="password" [nzPlaceHolder]="'password'" [nzType]="'password'" [nzSize]="'large'" (ngModelChange)="validateConfirmPassword()">
                                </nz-input>
                                <div nz-form-explain *ngIf="getFormControl('password').dirty&&getFormControl('password').hasError('minlength')">Your password must be at least 5 characters long. </div>
                                <div nz-form-explain *ngIf="getFormControl('password').dirty&&getFormControl('password').hasError('maxlength')">Your password cannot exceed 15 characters. </div>
                                <div nz-form-explain *ngIf="getFormControl('password').dirty&&getFormControl('password').hasError('required')">Please input your password!</div>
                            </div>

Upvotes: -1

Sajeetharan
Sajeetharan

Reputation: 222582

You should not use length here, for min and max use custom validator like this,

var numberControl = new FormControl("", CustomValidators.number({min: 10000000000, max: 999999999999 }))

Angular2 min/max validators

Upvotes: 8

Related Questions