Home > other >  Observe a FormControl value to disable a mat-slide-toggle
Observe a FormControl value to disable a mat-slide-toggle

Time:12-15

I try to control a mat-slide-toggle, with a form, controlled by a FormControl. It means that the disabled attribute of my mat-slide-toggle depends on the FormControl value. More precisely, I want to disable the toggle if the FormControlValue is not set.

The form is as follow:

<mat-form-field>
  <mat-label i18n="@@main.level">Level</mat-label>
  <mat-select [formControl]="levelControl" >
     <mat-option *ngFor="let level of levelList" [value]="level.value">
       {{level.viewValue | titlecase}}
     </mat-option>
  </mat-select>
</mat-form-field>

I cannot directly use levelControl.value to set disabled or not my toggle, because this toggle generates a dynamic component, and this methods generates ChangedAfterItHasBeenChecked Errors.

So I defined an Observable in my component:

disableToggle: Observable<boolean>;

ngOnInit() {
  this.disableToggle = this.levelControl.valueChanges.pipe(filter(next => next.level === ''));
}

I use it into the toggle as it follows:

<mat-slide-toggle [disabled]="(disableToggle | async)"> </mat-slide-toggle>

But nothing happens, the toggle is always enabled. Has anybody a solution ? Thanks for your help !

CodePudding user response:

You can use ReactiveForms and add the toggle to the form and bind it. Once you've done that you can listen to the changes like:

form.toggle.value.subscribe((flag: boolean) => form.field.disable(flag));

If you don't use reactive forms and only have the levelControl as a property of type FormControl you'll need to add another one for your toggle field and pretty much do the same as above

CodePudding user response:

You are using filter to actually filter out non-values, thus it won't be disabled as the code will not be executed after filter if there is not a value. What you want to do, is to use map instead and return true or false based on if there is a value. Below I also trigger the initial valueChanges with the current value of the form control:

ngOnInit() {
  this.disableToggle = this.levelControl.valueChanges.pipe(
    startWith(this.levelControl.value),
    map(value => value ? false : true)
  );
}

Now it should work as you want.

STACKBLITZ DEMO

  • Related