how to remove a control's invalid/dirty state in angular 4 from code behind

323 Views Asked by At

I have stuck in a situation where I have to remove the invalid state of a control based on the other control. I have 2 date picker controls "StartDate" and "EndDate". Here validation are applied as

  • Startdate should be less than equal to Enddate

  • EndDate should be greater than equal Startdate

validation message appear as expected The problem arises when both the validation fail and when I try to make a date equal to other the other control validation should also trigger. For validation i have implemented a CustomValidatorDirective

/**
 * Class which provide validation functionalities
 */
export class CustomValidatorDirective implements Validator {
  @Input('validations') validations: Array<Object> = [];
  @Input('fields') fields: Array<Object> = [];
  validator: ValidatorFn;

  constructor(private translate: TranslateService) { }
  validate(control: AbstractControl): { [key: string]: any } {
    const isValid = false;
    return this.Validate(control, control.value);
  }  

/**
   * A function which do custom validation for the control
   */
  Validate(control: AbstractControl, value): { [key: string]: any } {
    let validators = []
    validators = _.chain(this.validations).values().pluck('Key').value();
    const message = '';

     if (_.contains(validators, 'Gte')) {
  const label = _.findWhere(this.validations, {Key: 'Gte'})['Value'];      
  if (value && value < control.parent.controls[label.toString()].value){
    return { 'Gte': { valid: false, message: 'Validations.GREATER_THAN_EQUAL', data: label } };
  } else if (control.parent.controls[label.toString()]!== undefined && control.parent.controls[label.toString()].dirty && value && value >= control.parent.controls[label.toString()].value){
    control.parent.controls[label.toString()].errors=[];
  }
}

if (_.contains(validators, 'Lte')) {
  const label = _.findWhere(this.validations, {Key: 'Lte'})['Value'];  
  if (value && value > control.parent.controls[label.toString()].value){//this.fields[index]['Value'] ) {
    return { 'Lte': { valid: false, message: 'Validations.LESS_THAN_EQUAL', data: label } };
  } else if (control.parent.controls[label.toString()]!== undefined && control.parent.controls[label.toString()].dirty && value && value <= control.parent.controls[label.toString()].value){
    control.parent.controls[label.toString()].errors=[];
  }
}  

<form #dynamicform="ngForm" (ngSubmit)="onSubmit(dynamicform.value, dynamicform)">
      <div *ngIf="isDropDownDataLoading" class="dynamic-loader-section" appSetHeight [offset]="305" [property]="'line-height'">
        <img src="./assets/images/loader.gif" />
      </div>
      <div class="accordion" *ngFor="let key of keys(data);let $index = index">
        <mat-accordion>
          <mat-expansion-panel class="custom-expansion-panel" [expanded]="true" hideToggle="false">
            <mat-expansion-panel-header expandedHeight="48px">
              <!-- <mat-panel-title>{{key === 'null'? ('CONFIGURATION_MANAGER.DYNAMIC_GENERAL' | translate): key}}</mat-panel-title> -->
              <mat-panel-title>{{key === 'null'? 'General': key}}</mat-panel-title>
            </mat-expansion-panel-header>
            <mat-panel-description>
              <div class="container no-pad no-margin full-width">
                <div class="row no-pad no-margin" *ngFor="let chunk of data[key];let last = last">
                  <div class="col-4 no-pad no-margin height-50"
                       [ngClass] = "{'col-12':(field?.EditorKind == 'Dictonary'),'height-35':(field?.EditorKind == 'DropDownList' || field?.EditorKind == 'MultiSelect')}"
                       *ngFor="let field of chunk">
                    <div class="form-field-container" [ngSwitch]="field?.EditorKind">


     <mat-form-field *ngSwitchCase="'Email'">
                          <input  matInput [placeholder]="field['Label']" [(ngModel)]="field['Value']" [name]="field.Key" [readonly]="field['ReadOnly'] || !hasPermission"
                          appCustomValidator [validations]="field.Validations" autocomplete="off"/>
                            <mat-error *ngIf="dynamicform?.invalid && dynamicform.controls[(field.Key).toString()]?.invalid">
                              {{ (dynamicform.controls[(field.Key).toString()]?.errors.Required?.message | translate) ||
                                 (dynamicform.controls[(field.Key).toString()]?.errors.Email?.message | translate)}}
                            </mat-error>
                          </mat-form-field>


     <mat-form-field *ngSwitchCase="'Date'">
                        <input matInput [matDatepicker]="picker1" [placeholder]="field['Label']" [(ngModel)]="field['Value']" [name]="field.Key"  autocomplete="off"
                        appCustomValidator [validations]="field.Validations" [fields]="chunk" [disabled]="field['ReadOnly'] || !hasPermission" >
                        <mat-datepicker-toggle matSuffix [for]="picker1"></mat-datepicker-toggle>
                        <mat-datepicker #picker1></mat-datepicker>
                        <mat-error *ngIf="dynamicform?.invalid && dynamicform.controls[(field.Key).toString()]?.invalid ">
                          {{(dynamicform.controls[(field.Key).toString()]?.errors.Required?.message| translate)||
                           (dynamicform.controls[(field.Key).toString()]?.errors.Gte?.message | translate:{'1': dynamicform.controls[(field.Key).toString()]?.errors.Gte?.data})||
                           (dynamicform.controls[(field.Key).toString()]?.errors.Lte?.message | translate:{'1': dynamicform.controls[(field.Key).toString()]?.errors.Lte?.data})||}}
                        </mat-error>
                      </mat-form-field>
    </div>
                  </div>
                </div>
              </div>

            </mat-panel-description>
          </mat-expansion-panel>
        </mat-accordion>
      </div>
    </form>

0

There are 0 best solutions below