Angular 2 FormBuilder disable fields on checkbox select
At first, I believe that you want to enable fields if and only if isResetPassword
checkbox is selected, right? If so, here we go:
1 - The construction of the form should be like this:
this.userProfileForm = this.formBuilder.group({
// ...
password: [{
value: null,
disabled: !this.isResetPassword
}],
newPassword: [{
value: null,
disabled: !this.isResetPassword
}],
reTypePassword: [{
value: null,
disabled: !this.isResetPassword
}]
});
Note that here I'm disabling inputs only when this.isResetPassword
is false.
2 - To detect changes on your <input type="checkbox">
, you can use either (change)
in template:
<label>
<input
type="checkbox"
[formControl]="userProfileForm.controls['isResetPassword']"
(change)="handleChange($event)">
{{ 'USER_PROFILE_MODEL.RESET_PASSWORD' | translate }}
</label>
... or even, in component, using valueChanges
:
this.userProfileForm.get('isResetPassword').valueChanges.subscribe(value => this.handleChange(value));
And, of course, here's the function
to manipulate the state of fields.
handleChange(value: boolean): void {
const passwordCtrl = this.userProfileForm.get('password');
const newPasswordCtrl = this.userProfileForm.get('newPassword');
const reTypePasswordCtrl = this.userProfileForm.get('reTypePassword');
if (value) {
passwordCtrl.enable();
newPasswordCtrl.enable();
reTypePasswordCtrl.enable();
} else {
passwordCtrl.disable();
newPasswordCtrl.disable();
reTypePasswordCtrl.disable();
}
}
Some tips:
1 - Although it's only a matter of preference, it's worth to mention that you don't need to use [formControl]
like this:
[formControl]="userProfileForm.controls['isResetPassword']"
Instead, you can simply use formControlName
:
formControlName="isResetPassword"
Note that you can do the same for all your controls.
2 - You don't need to pass the form value in (ngSubmit)
since you've already the reference of userProfileForm
in form
.
Instead of:
(ngSubmit)="submitForm(userProfileForm.value)"
submitForm(value: any) { console.log(value); }
This:
(ngSubmit)="submitForm()"
submitForm() { console.log(this.userProfileForm.value); }
3 - If you want to see the value
of disabled inputs, instead of .value
, you should use .getRawValue()
, like this:
this.userProfileForm.getRawValue();
DEMO (using (change)
)
DEMO (using valueChanges
)
The easiest way would be to create a form group just for the passwords:
this.userProfileForm = formBuilder.group({
'userName': [null, [Validators.required]],
'displayName': [null],
'email': [null, [Validators.required]],
password: formBuilder.group({
'isResetPassword': this.isResetPassword,
'password': [null],
'newPassword': [null],
'reTypePassword': [null]
})
})
Then on your template change the passwords col to this:
<div class="col" formGroupName="password>
<div class="form-group ">
<label class="checkbox-inline">
<input type="checkbox" formControlName="isResetPassword">
{{ 'USER_PROFILE_MODEL.RESET_PASSWORD' | translate }}
</label>
</div>
<div class="form-group ">
<label>{{ 'USER_PROFILE_MODEL.PASSWORD' | translate }}</label>
<input class="form-control" type="password" formControlName="password" >
</div>
<div class="form-group ">
<label>{{ 'USER_PROFILE_MODEL.NEW_PASSWORD' | translate }}</label>
<input class="form-control" type="password" formControlName="newPassword">
</div>
<div class="form-group ">
<label>{{ 'USER_PROFILE_MODEL.RE_TYPE_PASSWORD' | translate }}</label>
<input class="form-control" type="password" formControlName="reTypePassword">
</div>
</div>
on your component:
//when value changes, to disable all the fields just do this
this.userProfileForm.controls.password.disable();
// to enable them back
this.userProfileForm.controls.password.enable();
Most of the methods on this post works but you need to do it with a setTimeout
:
setTimeout(() => {
if (this.disable) {
this.userProfileForm.controls.password.disable();
}
else {
this.userProfileForm.controls.password.enable();
}
});
Looks like an Angular bug, issues here and here