Home > Net >  How to disable mat-autocomplete on formBuilder?
How to disable mat-autocomplete on formBuilder?

Time:01-18

I am trying to create a form in which once an option is selected in the first field, this selection gives the options of the second field, which is a mat-autocomplete, also when value from the mat-autocomplete is selected, it is filled with mat-chips.

The problem is that I am not able to make the second field disabled until the first field is filled.

I have tried both different ways, like the indicated by the console warning:

"It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true
  when you set up this control in your component class, the disabled attribute will actually be set in the DOM for
  you. We recommend using this approach to avoid 'changed after checked' errors.

  Example:
  // Specify the `disabled` property at control creation time:
  form = new FormGroup({
    first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
    last: new FormControl('Drew', Validators.required)
  });

  // Controls can also be enabled/disabled after creation:
  form.get('first')?.enable();
  form.get('last')?.disable();"

I tried the response of this question too:

Angular mat-autocomplete disable input FormControl not working

But in the end I had to do it like this (that give me the warning):

HTML

<div  [formGroup]="filterValueForm">
    <mat-form-field appearance="outline" >
      <mat-label>tag</mat-label>
      <mat-select (selectionChange)="onFilterChange($event)" formControlName="filterSelectCtrl" required>
        <mat-option *ngFor="let filter of filters" [value]="filter.code">{{ filter.code }}</mat-option>
      </mat-select>
    </mat-form-field>

    <mat-form-field appearance="outline" >
      <mat-label>condition</mat-label>
      <mat-select formControlName="filterConditionCtrl" required>
        <mat-option value="true">{{ apply$ | async }}</mat-option>
        <mat-option value="false">{{ notApply$ | async }}</mat-option>
      </mat-select>
    </mat-form-field>

    <mat-form-field appearance="outline" >
      <mat-label>{{ values }}</mat-label>
      <mat-chip-list #toChipList required>
        <mat-chip
          
          *ngFor="let filterValue of selectedFiltersValue"
          [selectable]="selectable"
          [removable]="removable"
          (removed)="removeSelectedFilterValue(filterValue)">
          {{ filterValue.value }}
          <mat-icon  matChipRemove *ngIf="removable">close</mat-icon>
        </mat-chip>
        <input type="text"
          matInput
          #filterValueInput
          formControlName="filterValueCtrl"
          [matAutocomplete]="autoTo"
          [matChipInputFor]="toChipList"
          [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
          [matChipInputAddOnBlur]="addOnBlur"
          (matChipInputTokenEnd)="add($event)"
          [disabled] = "isFilterValueSelected"
          >
      </mat-chip-list>
      <mat-autocomplete  #autoTo="matAutocomplete" (optionSelected)="selected($event)">
        <mat-option *ngFor="let filterValue of filteredValues" [value]="filterValue">{{ filterValue.value }}</mat-option>
      </mat-autocomplete>
    </mat-form-field>

TS

ngOnInit() {
    this.filterValueForm = this.fb.group({
      filterSelectCtrl: [null, Validators.required],
      filterConditionCtrl: [null, Validators.required],
      filterValueCtrl: [{value: '', disabled: true}, Validators.required], /*this object inside array do nothing*/ 
    })
};

get isFilterValueSelected() {
    return !this.filterValueForm.get('filterSelectCtrl').value ? true : false;
  }

Does anyone know what is wrong or knows a better way to do it?

CodePudding user response:

Disable the second field on the formGroup declaration.

    this.filterValueForm = this.fb.group({
      firstField: ['', Validators.required],
      secondField: [{value: '', disabled: true}, Validators.required], 
    })

Then, when you select an option from the autocomplete, you are calling the selected($event) function from your ts. In this function, you can enable the second field like this:

selected() {
    \*Do whatever logic you want to do when an autocomplete element is selected*\
    this.filterValueForm.controls['secondField'].enable();
  }

Edit:

You are overriding the ts configuration on the html with the line

<input type="text"
          matInput
          #filterValueInput
          formControlName="filterValueCtrl"
          [matAutocomplete]="autoTo"
          [matChipInputFor]="toChipList"
          [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
          [matChipInputAddOnBlur]="addOnBlur"
          (matChipInputTokenEnd)="add($event)"
          [disabled] = "isFilterValueSelected" <---
          >

CodePudding user response:

I found a solution.

Dont know why but when creating the formGroup like this dont work:

filterValueCtrl: [{value: '', disabled: true}, Validators.required]

And after try some other solutions I found that one:

this.filterValueForm.controls.filterValueCtrl.disable();

But dont know why dont work if its used after create the formGroup that its inside ngOnInit()

So I made method that its triggered when the mouse is over the <mat-form-field>

TS:

enableOrDisableField(){
    this.filterValueForm.get('filterSelectCtrl').value ? this.filterValueForm.controls.filterValueCtrl.enable() : this.filterValueForm.controls.filterValueCtrl.disable();
  }

HTML:

<mat-form-field appearance="outline" (mouseenter)="enableOrDisableField()">
...
...
<mat-form-field>

Maybe its not the best solution but its working and no warning at console...so I think its fine for me.

Hope can help someone, and tanks to all who have tryed to help.

  • Related