10

I have a form (using Angular Material), and I want to disable some of the input fields based on selection values. My code looks as below:

HTML

<mat-form-field class="someclass">
   <mat-select placeholder="Select payment method" formControlName="paymentMethod">
      <mat-option *ngFor="let payment of paymentMethodOptions" [value]="payment.value">
         {{payment.viewValue}}
      </mat-option>
   </mat-select>
</mat-form-field>

<mat-form-field class="someclass">
   <input matInput placeholder="Some input" formControlName="testInput">
</mat-form-field>

TS

paymentMethodOptions: payment[] = [
   { value: "opt-1", viewValue: "somevalue" },
   { value: "opt-2", viewValue: "anothervalue" }
];

paymentForm = new FormGroup({
   paymentMethod: new FormControl("", Validators.required),
   testInput: new FormControl({ value: "", disabled: true }, [
      Validators.required
   ])
});

I want to disable testInput if the value of the selection is equal to "opt-1". I've tried several options, but got different errors and couldn't solve it. Is there any working solution to this? Thanks in advance!

1
  • I like a enabledDirective (it's looks like a work-around, but it have tha advantage that is the .html with control the enabled) stackoverflow.com/questions/47937639/… Commented Nov 21, 2018 at 7:49

3 Answers 3

7

You'll can listen to the valueChanges event of the form :

this.paymentForm.valueChanges.subscribe((value) => {
  if(value.paymentMethod == 'opt-1'){
   this.paymentForm.controls['testInput'].disable();
  }else{
   this.paymentForm.controls['testInput'].enable();
  }
});

So everytime the select changes , the valueChanges event is called , the conditions kick in and it will enable or disable the formControl.

Sign up to request clarification or add additional context in comments.

9 Comments

Looks like your solution works too. Thank you very much!
Why are you listening to valueChanges on the whole form? Won't it run every time there's any change on the form? We should only be concerned with the mat-select value change here.
Wouldn't it be safe to assume that OP was a mere abstraction of the original implementation and that there are going to be a lot more form controls in the form rather than just a mat-select?
Both solutions work good, will try using both of them and decide which one suits my case better. Thanks for your support :)
@Andrew happy coding :)
|
4

You can leverage the selectionChange @Output property on MatSelect and react accordingly:

onSelectionChanged({value}) {
  console.log(value);
  if(value === 'opt-1') {
    this.paymentForm.get('testInput').disable();
  } else {
    this.paymentForm.get('testInput').enable();
  }
}

And in template

<mat-select ... (selectionChange)="onSelectionChanged($event)">

Here's a Sample StackBlitz for your ref.

NOTE: In case there are more controls in your form than just mat-select, listening to valueChanges on the whole form could be expensive as this will get triggered every time there is a change in any of the form control. All we are concerned about is the change in the mat-select selection change.

1 Comment

@Andrew, if any of these answers helped you with your issue please consider marking any one of them as a solution to close the loop.
3

Though there are already answers provided, If any had stumbled with the same issue. You can directly disable a form field by directly accessing its control

Had created a Stackblitz demo link

  <!-- INPUT FIELD --> 
  <mat-form-field formControlName="testInput">
    <input matInput 
           placeholder="Some input"
           [disabled]="paymentForm.get('paymentMethod').value === 'opt-1'">   // Disables the input once paymentMethod's formControlName value is opt-1    
  </mat-form-field>     

3 Comments

Doesn't work. You'll have to use attr.disabled in this case. Also it did not change the disabled state if opt-1 was selected first and then opt-2 is selected.
Had accidentally removed the [disabled] on input from the Stackblitz demo link i sent. Now it actually changes its state, you can try it. You'll know it gets disabled when you can't click on the input anymore and it has a dotted border instead of solid stackblitz.com/edit/angular-nuygok
Indeed it works. So the trick is to use paymentForm.get('paymentMethod').value instead of paymentForm.value.paymentMethod

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.