简体   繁体   中英

Disable a field in angular reactive form

In my angular 6 application, i am making a reactive form which has,

Html

<form [formGroup]="form">

    <h2>Click the add button below</h2>
    <button (click)="addCreds()">Add</button>
    <div formArrayName="credentials" >
      <div *ngFor="let creds of form.get('credentials').controls; let i = index" 
          [formGroupName]="i" style="display: flex">
          <select formControlName="action">
             <option *ngFor="let option of options" value="{{option.key}}">
               {{option.value}} 
             </option>
          </select>
          <input placeholder="Name" formControlName="name">
<div *ngIf="creds.value.action=='set' ||
      creds.value.action=='go'">
                   <input placeholder="Label" formControlName="label">
          </div>
      </div>
    </div>
    </form>

Here i have used

<div *ngIf="creds.value.action=='set' || creds.value.action=='go'"> <input placeholder="Label" formControlName="label"> </div>

which will display the field label if the condition is true or else it will not be displayed.

But i need to only disable that field and should not remove it completely..

For which i have tried,

<input [disabled]="creds.value.action != 'set' || creds.value.action != 'go' " placeholder="Label" formControlName="label">

But it doesn't works.

Stackblitz with *ngIf https://stackblitz.com/edit/angular-form-array-example-25y1ix

Stackblitz with disabled https://stackblitz.com/edit/angular-form-array-example-laftgu

Kindly help me how to disable the label field if the selected action (first dropdown) value is wait ..

Just create a CSS class:

.disabled {
  pointer-events:none;
  background-color: #D3D3D3;
}

Add a method to your Component:

getValueByIndex(index) {
  const actionValue = ( < FormArray > this.form.get('credentials')).at(index).value.action;
  return actionValue !== 'set' && actionValue !== 'go';
}

Use this method in your template:

<input 
    [class.disabled]="getValueByIndex(i)" 
    placeholder="Label" 
    formControlName="label">

Here's a Working Sample StackBlitz for your ref.


UPDATE:

Alternatively, you can do the following:

Make the label field disabled by default:

addCreds() {
  const creds = this.form.controls.credentials as FormArray;
  creds.push(this.fb.group({
    action: '',
    name: '',
    label: {
      value: '',
      disabled: true
    },
    state: 'na'
  }));
}

And then listen to the (ngModelChange) event on the form to update the state of the label field:

<select 
  formControlName="action"
  (ngModelChange)="($event === 'set' || $event === 'go') ? creds.controls.label.enable() : creds.controls.label.disable()">
  <option 
    *ngFor="let option of data" 
    [value]="option.key">
    {{option.value}} 
  </option>
</select>

Here's a Working Sample StackBlitz for this approach.


Thanks to A.Winnen for his comments on the performance implications of using the previous approach.

In Reactive Form you cannot use the disabled directive. Instead, you'll need to disable the formControl the 'reactive way' by calling enable() or disable() function.

addCreds() {
    const creds = this.form.controls.credentials as FormArray;
    const newGroup = this.fb.group({
      action: '',
      name: '',
      label: ''
    });
    newGroup.controls.action.valueChanges.subscribe((currentAction) => {
      if (typeof currentAction === "string" && currentAction.toLowerCase() === 'wait') {
        newGroup.controls.label.disable();
      } else {
        newGroup.controls.label.enable();
      }
    });
    creds.push(newGroup);
  }

I modified your stackblitz example: https://stackblitz.com/edit/angular-form-array-example-ymysw4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM