Search code examples
angularangular-validation

Validation based on user selection in large form


I have a user form in which i have multiple fields and based on the type of the user, i have used angular reactive forms and want to validate my fields

Here is my component ts code:

export class AppComponent implements OnInit {

userformGroup: FormGroup;
        Types = [ "user","admin", "guest"];
type: string;

constructor(
    private formBuilder: FormBuilder){}

ngOnInit() {
 this.userformGroup = this.formBuilder.group({
      type: ['user'],
       userName : [''],
      firstName :[''],
      lastName :[''],
        email :[''],
        contactNumber :[''],
        licenseNo :[''],
        age:[''],
        birthDate :[''],
        city:[''],
        country:[''],
        zipCode :[''],
        countryCode:['']
        });
  }

    updateValidators() {
    if (this.type === 'user') {
      this.userformGroup.get('userName').setValidators([Validators.required]);
      this.userformGroup.get('firstName').setValidators([Validators.required]);
      this.userformGroup.get('lastName').setValidators([Validators.required]);
      this.userformGroup.get('email').setValidators([Validators.required]);
      this.userformGroup.get('contactNumber').setValidators([Validators.required]);
       this.userformGroup.get('licenseNo').setValidators([Validators.required]);
         this.userformGroup.get('age').setValidators([Validators.pattern('/^-?(0|[1-9]\d*)?$/')]);
       this.userformGroup.get('birthDate').setValidators([Validators.required]);
       this.userformGroup.get('city').setValidators([Validators.required]);
        this.userformGroup.get('country').setValidators([Validators.required]);
       this.userformGroup.get('zipCode').setValidators([Validators.pattern('/^-?(0|[1-9]\d*)?$/')]);
     this.userformGroup.get('countryCode').setValidators([Validators.minLength(3)]);
    }
      else if(this.type === 'admin')
    {
      this.userformGroup.get('userName').setValidators([Validators.required]);
      this.userformGroup.get('firstName').setValidators([Validators.required]);
      this.userformGroup.get('lastName').setValidators([Validators.required]);
      this.userformGroup.get('email').setValidators([Validators.required]);
      this.userformGroup.get('contactNumber').setValidators([]);
       this.userformGroup.get('licenseNo').setValidators([Validators.required]);
         this.userformGroup.get('age').setValidators([Validators.pattern('/^-?(0|[1-9]\d*)?$/')]);
       this.userformGroup.get('birthDate').setValidators([]);
       this.userformGroup.get('city').setValidators([Validators.required]);
        this.userformGroup.get('country').setValidators([]);
       this.userformGroup.get('zipCode').setValidators([Validators.pattern('/^-?(0|[1-9]\d*)?$/')]);
     this.userformGroup.get('countryCode').setValidators([Validators.minLength(3)]);    
    }
      else if(this.type === 'guest')
    {
      this.userformGroup.get('userName').setValidators([]);
      this.userformGroup.get('firstName').setValidators([]);
      this.userformGroup.get('lastName').setValidators([Validators.required]);
      this.userformGroup.get('email').setValidators([]);
      this.userformGroup.get('contactNumber').setValidators([]);
       this.userformGroup.get('licenseNo').setValidators([Validators.required]);
         this.userformGroup.get('age').setValidators([]);
       this.userformGroup.get('birthDate').setValidators([]);
       this.userformGroup.get('city').setValidators([Validators.required]);
        this.userformGroup.get('country').setValidators([]);
       this.userformGroup.get('zipCode').setValidators([Validators.pattern('/^-?(0|[1-9]\d*)?$/')]);
     this.userformGroup.get('countryCode').setValidators([Validators.minLength(3)]);    
    }
     this.userformGroup.get('userName').updateValueAndValidity();
    this.userformGroup.get('firstName').updateValueAndValidity();
    this.userformGroup.get('lastName').updateValueAndValidity();
    this.userformGroup.get('email').updateValueAndValidity();
    this.userformGroup.get('contactNumber').updateValueAndValidity();
    this.userformGroup.get('licenseNo').updateValueAndValidity();
    this.userformGroup.get('age').updateValueAndValidity();
    this.userformGroup.get('birthDate').updateValueAndValidity();
    this.userformGroup.get('city').updateValueAndValidity();
    this.userformGroup.get('country').updateValueAndValidity();
    this.userformGroup.get('zipCode').updateValueAndValidity();
    this.userformGroup.get('countryCode').updateValueAndValidity();
    }
    onChange(event: any) {
    this.type = event.target.value;
    this.updateValidators();
  }
}

This code is working fine, but I'm looking for a optimized way of validating it, how can i do that so that i dont have to repeatedly apply validation on the same fields?

Stackblitz


Solution

  • Instead of making custom validation functions or writing too much of code in the component, You can use validation based on user's selection by using conditional expression, Here i have used validation from @rxweb validators(RxwebValidators).

    The optimal code is :

    export class UserInfoAddComponent implements OnInit {
    
        userInfoFormGroup: FormGroup
            Types = [ "user","admin", "guest"];
        constructor(
            private formBuilder: RxFormBuilder
        ) { }
    
       ngOnInit(){
        this.userInfoFormGroup = this.formBuilder.group({
          type:[''],
          userName :['',RxwebValidators.required({conditionalExpression:(x) => x.type == 'user' })],
          firstName :['',RxwebValidators.required({conditionalExpression:(x) => x.type == 'user' })],
          lastName :['',RxwebValidators.required({conditionalExpression:(x) => x.type == 'user' })],
          email :['',RxwebValidators.required({conditionalExpression:(x) => x.type == 'user' })],     
            contactNumber :['',RxwebValidators.required({conditionalExpression:(x) => x.type == 'user' })],   
          licenseNo :['',RxwebValidators.required({conditionalExpression:(x) => x.type == 'user' })],  
         age:['', RxwebValidators.pattern({expression:{'onlyDigit': /^[0-9]*$/}  ,conditionalExpression:(x) => x.type == 'user' })], 
         birthDate:['',RxwebValidators.required({conditionalExpression:(x) => x.type == 'user' })],
          city:['',RxwebValidators.required({conditionalExpression:(x) => x.type == 'user' })],
          country:['',RxwebValidators.required({conditionalExpression:(x) => x.type == 'user' })],
          zipCode:['',RxwebValidators.pattern({expression:{'zipCode': /^-?(0|[1-9]\d*)?$/}  ,conditionalExpression:(x) => x.type == 'user' })], 
           countryCode:['',RxwebValidators.minLength({value:3,conditionalExpression:(x) => x.type == 'user' })], 
    
    
        });
    
    
        }
    }
    

    Stackblitz working example