0

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 class="modal-descriptors" [formGroup]="filterValueForm">
    <mat-form-field appearance="outline" class="form-field">
      <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" class="modal-descriptors">
      <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" class="descriptors">
      <mat-label>{{ values }}</mat-label>
      <mat-chip-list #toChipList required>
        <mat-chip
          class="descriptors_label"
          *ngFor="let filterValue of selectedFiltersValue"
          [selectable]="selectable"
          [removable]="removable"
          (removed)="removeSelectedFilterValue(filterValue)">
          {{ filterValue.value }}
          <mat-icon class="iconicon" 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?

1
  • Why I need to set it off? @AliCelebi Commented Jan 17, 2023 at 14:26

2 Answers 2

0

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" <---
          >
Sign up to request clarification or add additional context in comments.

2 Comments

Thats dont work, secondField is enabled from the beginning
I reomoved that before try your explanation. So still not working
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.