Reputation: 155
I am having trouble updating a reactive form so that an input that was enabled is then disabled. I am using Angular 8 and have tested using FF, Chrome, and Edge.
I have a component that shows a form. The form represents an object that the component receives via an EventEmitter. When an object is emitted, a new form is created. Under certain conditions, controls that were enabled should be disabled after an update/new object. However, on the web page, the input field stays enabled. I've tried simplifying the case below. I have verified that disable command to the form control for field2 below is called, but the input on the page does not disable. Code on stackblitz here: https://stackblitz.com/edit/angular-xjqmjc
If there is a better way to accomplish this functionality, please let me know! Thanks!
import {Component, EventEmitter, Input, OnInit} from "@angular/core";
import {FormBuilder, FormGroup} from "@angular/forms";
import {MyObject} from '../my-object';
@Component({
selector: 'my-form',
templateUrl: './my-form.component.html'
})
export class MyFormComponent implements OnInit {
@Input() objectStream: EventEmitter<MyObject>;
form: FormGroup = new FormGroup({});
initialized: boolean = false;
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.objectStream.subscribe( (obj: MyObject) => {
this.setupForm(obj);
});
}
private setupForm(obj: MyObject): void {
console.log("setting up form for", obj);
let form: FormGroup = this.fb.group({
field1: [obj.field1],
field2: [obj.field2],
field3: [obj.field3]
});
form.get("field1").disable(); //always disabled
if(obj.condition) {
form.get('field2').disable();
console.log("the field was disabled!");
}
setTimeout( () => {
this.form = form;
this.initialized = true;
});
}
}
The form html code:
<div *ngIf="initialized && form">
<form novalidate [formGroup]="form">
<div>
<div>
<label>Field One</label>
<div>
<input type="text" formControlName="field1">
</div>
</div>
<div>
<label>Field Two</label>
<div>
<input type="text" formControlName="field2">
</div>
</div>
<div>
<label>Field Three</label>
<div>
<input type="text" formControlName="field3">
</div>
</div>
</div>
</form>
</div>
Upvotes: 2
Views: 6636
Reputation: 1288
The reason your form is not being disabled is because you are calling the setup form let form
rather than the FormGroup
that was created: this.form
. If we take a look at how your app is run, we can find the issue.
In the my-form.component
, you are subscribing to the object stream, and once this comes in, you are setting up a form with the obj
: setupForm(obj: MyObject)...
Within this function you are setting up the form, and then checking if the obj
has a condition. If so, you want to disable the form, but the form has already been created (on the first OnInit instance).
The simple change to get this to work is to change your if()
statement within the setupForm(...
function to the following:
In my-form.component.ts
in the private setupForm(...
change from:
if(obj.condition) {
form.get('field2').disable();
console.log("the field was disabled!");
}
to:
if(obj.condition) {
this.form.get('field2').disable();
console.log("the field was disabled!");
}
This will now disable the actual FormGroup rather than the variable you set up within the statement. Since you are using an if condition after setting up the form variable, this is the best approach to disable the FormGroup being used (this.form).
HERE is the updated StackBlitz, let me know if you have any questions
Upvotes: 3