jxycms
3/15/2019 - 12:58 AM

angular reactive form

HTML:
 
<div [formGroup]="addressFormGroup">
  <div formGroupName="addressGroup">
    <mat-form-field  [floatLabel]="'always'">
        <input matInput formControlName="companyName" placeholder="Company Name" (blur)="isNotValidField('addressGroup.companyName', account_validation_messages.companyName)"/>
    </mat-form-field>
    
    *** another way for validation message, when user start to input or operate the validation message will disappear ***
    <div
      *ngIf="((!addressFormGroup.controls.companyName?.pristine || triedToSubmitForm) && addressFormGroup['controls'].companyName?.value == null)"
      class="error__validation-message col-md-2">
      <div>This field is required</div>
    </div>
    
    <mat-checkbox formControlName="collectTheOrder" style="display: block;margin-left: 18px;">
      I will collect this order
    </mat-checkbox>
  </div>
</div>
 
model:
 
export interface SelectedAddress{
  companyName: string;
}
 
Component:
 
addressFormGroup: FormGroup;
account_validation_messages: any = {
  'companyName': [
    { class: 'companyNameValidate', message: 'Please enter company name' }
  ],
  'attnOrRef': [
    { class: 'attnOrRefValidate', message: 'Please enter attn or ref' }
  ],
  'address': [
    { class: 'addressValidate', message: 'Please enter address' }
  ],
  'suburb': [
    { class: 'suburbValidate', message: 'Please enter suburb' }
  ],
  'state': [
    { class: 'stateValidate', message: 'Please enter state' }
  ],
  'postCode': [
    { class: 'postcodeValidate', message: 'Please enter postcode' }
  ],
  'phone': [
    { class: 'phoneValidate', message: 'Please enter phone' }
  ]
}
 
account_maintain_validation_messages: any = {
  'companyName': [
    { class: 'companyNameMaintainValidate', message: 'Please enter company name' }
  ],
  'attnOrRef': [
    { class: 'attnOrRefMaintainValidate', message: 'Please enter attn or ref' }
  ],
  'address': [
    { class: 'addressMaintainValidate', message: 'Please enter address' }
  ],
  'suburb': [
    { class: 'suburbMaintainValidate', message: 'Please enter suburb' }
  ],
  'state': [
    { class: 'stateMaintainValidate', message: 'Please enter state' }
  ],
  'postCode': [
    { class: 'postcodeMaintainValidate', message: 'Please enter postcode' }
  ],
  'phone': [
    { class: 'phoneMaintainValidate', message: 'Please enter phone' }
  ]
}
 
constructor(private formBuilder: FormBuilder) {
  this.addressFormGroup = this.formBuilder.group({
    addressGroup: this.getAddressGroup(),
    collectTheOrder: new FormControl(false, [Validators.required]),
    cartId: new FormControl(0)
  });
}
 
ngOnInit() {
  *** model property name equal to formControlName, then could set model to form ***
  this.addressFormGroup.get('addressGroup').setValue(this.selectedAddress);
}
 
getAddressGroup(): FormGroup {
  return this.formBuilder.group({
    companyName: new FormControl({
          "",
          disabled: true
        }, Validators.compose([
		UsernameValidator.validUsername,
		Validators.maxLength(25),
		Validators.minLength(5),
		Validators.pattern('^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]+$'),
		Validators.required
	  ])),
	  addressInCatchment: [null, [conditionalValidator(() => this.aaa == 'sss', Validators.compose([Validators.required]))]], // conditional add form control
	  maintainNaType: new FormControl(0),
  });
}
 
isNotValidField(path: string, validation: any): void {
  if(!this.userFormGroup.get(path).valid)  or  if(!this.userFormGroup.get(path).hasError("required")){
    this.commonService.showValidator("." + validation[0].class, validation[0].message, "right", "error");
  }
}
 
submit form:
 
if (this.addressFormGroup.get('addressGroup').valid) {
}else{
  this.isNotValidField('addressGroup.companyName', this.account_validation_messages.companyName);
}
 
 
** cartId is an example to save value in formGroup when cartId is not set in the form
** set value
level 1:
this.addressFormGroup.controls['cartId'].setValue(this.cartId);
 
level 2:
this.addressFormGroup.get('addressGroup').get('maintainNaType').setValue('I');
** get value
this.addressFormGroup.controls['cartId'].value
this.addressFormGroup.get('addressGroup').get('maintainNaType').value
 
** set value to grandchild control (property is in the form)
this.addressFormGroup.get('addressGroup.companyName').setValue(this.startDate);
** get value(property is in the form)
this.addressFormGroup.get('addressGroup.companyName').value
 
** disable input box
Example: 
form = new FormGroup({
  first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
  last: new FormControl('Drew', Validators.required)
});
if (this.userFormGroup.get("userGroup").valid) {
//could get value from disabled input field and hidden field
  this.checkOutService.CreateCSPTenant(JSON.stringify(this.userFormGroup.get("userGroup").getRawValue())).subscribe((res: TenantResponse) => {
    console.info(res);
  },
    (error: any) => {
      console.error(error);
      this.commonService.showError(".saveuser", error.responseMessage, "right");
      this.ngProgress.done();
    });
}
 
in the backend
 
use code below to parse string and get value
 
var formData = JsonConvert.DeserializeObject<Dictionary<string, string>>(data);
string companyName = formData["companyName"];
import { ValidatorFn } from '@angular/forms';

export interface BooleanFn {
    (): boolean;
  }
  
  /**
   * A conditional validator generator. Assigns a validator to the form control if the predicate function returns true on the moment of validation
   * @example
   * Here if the myCheckbox is set to true, the myEmailField will be required and also the text will have to have the word 'mason' in the end.
   * If it doesn't satisfy these requirements, the errors will placed to the dedicated `illuminatiError` namespace.
   * Also the myEmailField will always have `maxLength`, `minLength` and `pattern` validators.
   * ngOnInit() {
   *   this.myForm = this.fb.group({
   *    myCheckbox: [''],
   *    myEmailField: ['', [
   *       Validators.maxLength(250),
   *       Validators.minLength(5),
   *       Validators.pattern(/.+@.+\..+/),
   *       conditionalValidator(() => this.myForm.get('myCheckbox').value,
   *                            Validators.compose([
   *                            Validators.required,
   *                            Validators.pattern(/.*mason/)
   *         ]),
   *        'illuminatiError')
   *        ]]
   *     })
   * }
   * @param predicate
   * @param validator
   * @param errorNamespace optional argument that creates own namespace for the validation error
   */
  export function conditionalValidator(predicate: BooleanFn,
                                validator: ValidatorFn,
                                errorNamespace?: string): ValidatorFn {
    return (formControl => {
      if (!formControl.parent) {
        return null;
      }
      let error = null;
      if (predicate() && validator && typeof(validator) === 'function') {
        error = validator(formControl);
      }
      if (errorNamespace && error) {
        const customError = {};
        customError[errorNamespace] = error;
        error = customError
      }
      return error;
    })
  }