2

In my reactive form, I have a textbox and a checkbox. I want that when the checkbox is checked, then textbox can be null or empty. If checkbox is not checked then validation message should be shown for required value. So I have written a custom validator with parameter. But the validator is not working The form code is below:

<form [formGroup]="frmExpenseHead">
  <div class="form-group row">
    <label for="Code" class="col-sm-12 col-form-label">Code</label>
    <div class="col-sm-10">
      <input type="text" class="form-control" [(ngModel)]="txtCode" id="code" name="code" formControlName="code"
        [ngClass]="{ 'is-invalid': submitted && f.code.errors }">
      <div *ngIf="submitted && f.code.errors" class="invalid-feedback">
        <div *ngIf="f.code.errors.conditionRequired">Code is required</div>
      </div>
    </div>

    <div class="col-sm-2 form-check">
      <input class="form-check-input" type="checkbox" [(ngModel)]="chkAutoCode" id="autoCode" name="autoCode"
        formControlName="autoCode">
      <label class="form-check-label" for="autoCode">
        Auto Generate
      </label>
    </div>
  </div>

  <div class="text-center">
    <button class="btn btn-primary mr-1" (click)="onSubmit()">Register</button>
    <button class="btn btn-secondary" type="reset" (click)="onReset()">Cancel</button>
  </div>
</form>

The ts file code is:

@Component({
  selector: 'app-expense-head',
  templateUrl: './expense-head.component.html',
  styleUrls: ['./expense-head.component.css']
})
export class ExpenseHeadComponent implements OnInit {
  frmExpenseHead: FormGroup;
  today = this.calendar.getToday();
  submitted = false;

  txtCode: string;
  chkAutoCode: boolean = false;
  txtDate: NgbDateStruct;
  txtTitle: string;
  txtDescription: string;

  constructor(private calendar: NgbCalendar) { }

  ngOnInit() {    
    this.frmExpenseHead = new FormGroup({
      code: new FormControl("", [conditionalRequired(this.chkAutoCode)]),
      autoCode: new FormControl("")          
    });
  }

  get f() { return this.frmExpenseHead.controls; }

  onSubmit() {
    this.submitted = true;

    if (this.frmExpenseHead.invalid) {
      return;
    }

    alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.frmExpenseHead.value, null, 4));
  }

  onReset() {
    this.submitted = false;
    this.frmExpenseHead.reset();
  }
}

And the custom validator is:

export function conditionalRequired(bValue: boolean): ValidatorFn {  
  return (control: AbstractControl): ValidationErrors | null => {

    let controlValue = control.value;    

    if (bValue === true) {      
      return null;
    }
    
    if (controlValue === "" || controlValue === null || controlValue === undefined) {
      return { "conditionRequired": true }
    }

    return null;
  }
}

Can anybody let me know where is the problem? Please follow the below link for a workable example.

DEMO

mnu-nasir
  • 1,642
  • 5
  • 30
  • 62

1 Answers1

1

You don't have to create a custom validator for that, use the availible tools. It'll be much easier for you.

You can subscribe to any change of value of your checkbox FormControl and then change and update your input FormControl. Here's an example for you:

@Component({
  selector: 'app-my',
  templateUrl: './my.component.html',
  styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {
  public fg: FormGroup;
  public checkbox: FormControl = new FormControl(false);
  public input: FromControl = new FormControl('', Validators.required);

  public constructor() { }

  public ngOnInit(): void {    
    this.fg = new FormGroup({
      checkbox: this.checkbox,
      input: this.input          
    });
    this.checkbox.valueChanges.subscribe(value => {
      if (value) {
        this.input.setValidators(null);
      } else {
        this.input.setValidators(Validators.required);
      }
      this.input.updateValueAndValidity();
    });
  }
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Leccho
  • 467
  • 5
  • 23
  • thanks for your answer. Yes it helps. But still I want to know what is the wrong in my code. As I am new to angular, I am trying to learn it better. Can you please help me to show where the wrong is in my code – mnu-nasir Jan 06 '21 at 18:31
  • Can't find what's wrong sorry. Maybe if you look at this post you can find it yourself: https://dzone.com/articles/how-to-create-custom-validators-in-angular . You should still use the method shown above. – Leccho Jan 06 '21 at 18:58