Search code examples
javascriptangularangular2-forms

Angular 2 FormBuilder disable fields on checkbox select


I have build angular cli project and have a form with checkbox. Some of the fields must disable on checkbox select.

Form is as follows:

enter image description here

need to disable/enable password, new password and re type password fields on checkbox select event.

Html

<form [formGroup]="userProfileForm" (ngSubmit)="submitForm(userProfileForm.value)">

    <div class="row">
        <div class="col">
            <div class="form-group">
                <label> {{ 'USER_PROFILE_MODEL.USER_NAME' | translate }}</label>
                <input class="form-control" type="text" [formControl]="userProfileForm.controls['userName']">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.DISPLAY_NAME' | translate }}</label>
                <input class="form-control" type="text" [formControl]="userProfileForm.controls['displayName']">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.EMAIL' | translate }}</label>
                <input class="form-control" type="text" [formControl]="userProfileForm.controls['email']">
            </div>
        </div>
        <div class="col">
            <div class="form-group ">
                <label class="checkbox-inline">
                <input type="checkbox" value="isResetPassword" name="isResetPassword" [formControl]="userProfileForm.controls['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" [formControl]="userProfileForm.controls['password']">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.NEW_PASSWORD' | translate }}</label>
                <input class="form-control" type="password" [formControl]="userProfileForm.controls['newPassword']">
            </div>
            <div class="form-group ">
                <label>{{ 'USER_PROFILE_MODEL.RE_TYPE_PASSWORD' | translate }}</label>
                <input class="form-control" type="password" [formControl]="userProfileForm.controls['reTypePassword']">
            </div>

        </div>

    </div>
</form>

ts code

this.isResetPassword = true;
this.userProfileForm = formBuilder.group({
    'userName': [null, [Validators.required]],
    'displayName': [null],
    'email': [null, [Validators.required]],
    'isResetPassword': this.isResetPassword,
    'password': [{
        value: null,
        disabled: this.isResetPassword
    }],
    'newPassword': [{
        value: null,
        disabled: this.isResetPassword
    }],
    'reTypePassword': [{
        value: null,
        disabled: this.isResetPassword
    }]
})

Form has built inside the constructor. How can I disable/enable the above fields on check box select.


Solution

  • 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)