Wednesday, 31 October 2018

Angular formbuilder example






















































Move validation logic to the component class in reactive form


formErrors = {
  'fullName''',
  'email''',
  'skillName''',
  'experienceInYears''',
  'proficiency'''
};

validationMessages = {
  'fullName': {
    'required''Full Name is required.',
    'minlength''Full Name must be greater than 2 characters.',
    'maxlength''Full Name must be less than 2 characters.',
  },
  'email': {
    'required''Email is required.'
  },
  'skillName': {
    'required''Skill Name is required.',
  },
  'experienceInYears': {
    'required''Experience is required.',
  },
  'proficiency': {
    'required''Proficiency is required.',
  },
};

ngOnInit() {

  this.employeeForm = this.fb.group({
    fullName: ['', [Validators.required, Validators.minLength(2), Validators.maxLength(10)]],
    email: ['', Validators.required],
    skills: this.fb.group({
      skillName: ['', Validators.required],
      experienceInYears: ['', Validators.required],
      proficiency: ['', Validators.required]
    }),
  });

  // When any of the form control value in employee form changes
  // our validation function logValidationErrors() is called
  this.employeeForm.valueChanges.subscribe((data) => {
    this.logValidationErrors(this.employeeForm);
  });

}

logValidationErrors(group: FormGroup = this.employeeForm): void {
  Object.keys(group.controls).forEach((key: string) => {
    const abstractControl = group.get(key);
    if (abstractControl instanceof FormGroup) {
      this.logValidationErrors(abstractControl);
    } else {
      this.formErrors[key] = '';
      if (abstractControl && !abstractControl.valid
          && (abstractControl.touched || abstractControl.dirty)) {
        const messages = this.validationMessages[key];
        for (const errorKey in abstractControl.errors) {
          if (errorKey) {
            this.formErrors[key] += messages[errorKey] + ' ';
          }
        }
      }
    }
  });
}



<div class="form-group" [ngClass]="{'has-error': formErrors.email}">
  <label class="col-sm-2 control-label" for="email">Email</label>
  <div class="col-sm-8">
    <input id="email" type="text" class="form-control"
           formControlName="email" (blur)="logValidationErrors()">
    <span class="help-block" *ngIf="formErrors.email">
      {{formErrors.email}}
    </span>
  </div>
</div>

<div class="well">
  <div formGroupName="skills">

    <div class="form-group" [ngClass]="{'has-error': formErrors.skillName}">
      <label class="col-sm-2 control-label" for="skillName">
        Skill
      </label>
      <div class="col-sm-4">
        <input type="text" class="form-control" id="skillName"formControlName="skillName"
               (blur)="logValidationErrors()" placeholder="C#, Java, Angular etc...">
        <span class="help-block" *ngIf="formErrors.skillName">
          {{formErrors.skillName}}
        </span>
      </div>
    </div>

    <div class="form-group" [ngClass]="{'has-error': formErrors.experienceInYears}">
      <label class="col-sm-2 control-label" for="experienceInYears">
        Experience
      </label>
      <div class="col-sm-4">
        <input type="text" class="form-control" id="experienceInYears"
               formControlName="experienceInYears" placeholder="In Years"
              (blur)="logValidationErrors()">
        <span class="help-block" *ngIf="formErrors.experienceInYears">
          {{formErrors.experienceInYears}}
        </span>
      </div>
    </div>

    <div class="form-group" [ngClass]="{'has-error': formErrors.proficiency}">
      <label class="col-md-2 control-label">Proficiency</label>
      <div class="col-md-8">
        <label class="radio-inline">
          <input type="radio" value="beginner" formControlName="proficiency"
                 (blur)="logValidationErrors()">Beginner
        </label>
        <label class="radio-inline">
          <input type="radio" value="intermediate" formControlName="proficiency"
                 (blur)="logValidationErrors()">Intermediate
        </label>
        <label class="radio-inline">
          <input type="radio" value="advanced" formControlName="proficiency"
                 (blur)="logValidationErrors()">Advanced
        </label>
        <span class="help-block" *ngIf="formErrors.experienceInYears">
          {{formErrors.proficiency}}
        </span>
      </div>
    </div>
  </div>
</div>

Dynamically adding or removing form control validators in reactive form


So here is our requirement  
  • Add the "required" validator to the Phone form control when the user selects "Phone" as their contact preference
  • On the other hand, remove the "required" validator from the Phone form control, when the user selects "Email" as their contact preference
  • So on the "Phone" form control, we have to dynamically add or remove the required validator function
This can be very easily achieved using the following 3 functions 
  • setValidators()
  • clearValidators()
  • updateValueAndValidity()

onContactPrefernceChange(selectedValue: string) {
  const phoneFormControl = this.employeeForm.get('phone');
  if (selectedValue === 'phone') {
    phoneFormControl.setValidators(Validators.required);
  } else {
    phoneFormControl.clearValidators();
  }
  phoneFormControl.updateValueAndValidity();
}


this.employeeForm.get('contactPreference')
                 .valueChanges.subscribe((data: string) => {
  this.onContactPrefernceChange(data);
});


Angular reactive form custom validator




function emailDomain(control: AbstractControl): { [key: string]: any } | null {
  const email: string = control.value;
  const domain = email.substring(email.lastIndexOf('@') + 1);
  if (email === '' || domain.toLowerCase() === 'pragimtech.com') {
    return null;
  } else {
    return { 'emailDomain'true };
  }
}




validationMessages = {
  'fullName': {...
  },
  'email': {
    'required''Email is required.',
    'emailDomain''Email domian should be pragimtech.com'
  },
  'phone': {...
  },
  'skillName': {...
  },
  'experienceInYears': {...
  },
  'proficiency': {...
  },
};

<div class="form-group" [ngClass]="{'has-error': formErrors.email}">
  <label class="col-sm-2 control-label" for="email">Email</label>
  <div class="col-sm-8">
    <input id="email" type="text" class="form-control"
            formControlName="email" (blur)="logValidationErrors()">
    <span class="help-block" *ngIf="formErrors.email">
      {{formErrors.email}}
    </span>
  </div>
</div>



Angular reactive form custom validator with parameter



email: ['', [emailDomain('pragimtech.com')]]

function emailDomain(domainName: string) {
  return (control: AbstractControl): { [key: string]: any } | null => {
    const email: string = control.value;
    const domain = email.substring(email.lastIndexOf('@') + 1);
    if (email === '' || domain.toLowerCase() === domainName.toLowerCase()) {
      return null;
    } else {
      return { 'emailDomain'true };
    }
  };
}


validationMessages = {
  'email': {
    'required''Email is required.',
    'emailDomain''Email domian should be dell.com'
  },
  'proficiency': {
    'required''Proficiency is required.',
  },
};
















IIS deployment support details

  Node JS - IIS deployment support details node: http://go.microsoft.com/?linkid=9784334 IISNode: https://github.com/azure/iisnode/releases/...