首页 文章

Angular 2 FormBuilder禁用复选框选择上的字段

提问于
浏览
5

我已经构建了角度cli项目并且有一个带复选框的表单 . 某些字段必须在复选框选择时禁用 .

表格如下
enter image description here

需要在复选框选择事件上禁用/启用密码,新密码和重新键入密码字段 .

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代码

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
    }]
})

表单已在构造函数内部构建 . 如何在复选框选中禁用/启用上述字段 .

5 回答

  • 4

    首先,我相信你想要启用字段,当且仅当选择了 isResetPassword 复选框时,对吗?如果是这样,我们走了:

    1 - 表单的构造应该是这样的:

    this.userProfileForm = this.formBuilder.group({
      // ...
      password: [{
        value: null,
        disabled: !this.isResetPassword
      }],
      newPassword: [{
        value: null,
        disabled: !this.isResetPassword
      }],
      reTypePassword: [{
        value: null,
        disabled: !this.isResetPassword
      }]
    });
    

    请注意,这里我只在 this.isResetPassword 为false时禁用输入 .

    2 - 要检测 <input type="checkbox"> 上的更改,您可以在 template 中使用 (change)

    <label>
      <input 
        type="checkbox" 
        [formControl]="userProfileForm.controls['isResetPassword']" 
        (change)="handleChange($event)">
      {{ 'USER_PROFILE_MODEL.RESET_PASSWORD' | translate }}
    </label>
    

    ......甚至在 component 中,使用 valueChanges

    this.userProfileForm.get('isResetPassword').valueChanges.subscribe(value => this.handleChange(value));
    

    而且,当然,这是操纵字段状态的 function .

    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();
      }
    }
    

    一些技巧:

    1 - 虽然它值得一提,你不需要像这样使用 [formControl]

    [formControl]="userProfileForm.controls['isResetPassword']"
    

    相反,你可以简单地使用 formControlName

    formControlName="isResetPassword"
    

    请注意,您可以对所有控件执行相同操作 .

    2 - 您不需要在 (ngSubmit) 中传递表单值,因为您已经在 form 中引用了 userProfileForm .

    代替:

    (ngSubmit)="submitForm(userProfileForm.value)"
    
    submitForm(value: any) { console.log(value); }
    

    这个:

    (ngSubmit)="submitForm()"
    
    submitForm() { console.log(this.userProfileForm.value); }
    

    3 - 如果要查看 value 的禁用输入,而不是 .value ,则应使用 .getRawValue() ,如下所示:

    this.userProfileForm.getRawValue();
    

    DEMO (using (change))

    DEMO (using valueChanges)

  • 1

    最简单的方法是为密码创建一个表单组:

    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]
      })
    })
    

    然后在您的模板上将密码col更改为:

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

    在您的组件上:

    //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();
    
  • -1

    这篇文章的大部分方法都有效,但你需要用 setTimeout 来做:

    setTimeout(() => {
        if (this.disable) {
           this.userProfileForm.controls.password.disable();
        }
        else {
            this.userProfileForm.controls.password.enable();
        }
    });
    

    看起来像Angular bug,问题herehere

  • 13

    不要使用 [formControl] 作为模板中的控件,而是使用 formControlName .

    您的表单将如下所示:

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

    你必须像这样定义你的表单:

    this.userProfileForm = formBuilder.group({
        'userName': [null, [Validators.required]],
        'displayName': [null],
        'email': [null, [Validators.required]],
        'isResetPassword': [false],
        'password': [null],
        'newPassword': [null],
        'reTypePassword': [null]
    })
    
  • 0

    您需要在单击 (click)="checkBoxClicked()" 之类的复选框时编写一个callBack,并在组件中定义回调函数,如下所示

    checkBoxClicked() {
     if(!this.userProfileForm.controls.isResetPassword.value) {
       this.userProfileForm.controls.password.disable();
       this.userProfileForm.controls.newPassword.disable();
       this.userProfileForm.controls.reTypePassword.disable();
     }else {
       this.userProfileForm.controls.password.enable();
       this.userProfileForm.controls.newPassword.enable();
       this.userProfileForm.controls.reTypePassword.enable();
     }
    }
    

相关问题