web-dev-qa-db-ja.com

Angular 2チェックボックスの選択時にFormBuilderがフィールドを無効にする

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

フォームはコンストラクタの内部に構築されています。チェックボックスの選択時に上記のフィールドを無効/有効にする方法を教えてください。

13

最初は、isResetPasswordcheckboxが選択されている場合のみ、enableフィールドを有効にしたいと思いますよね?もしそうなら、ここに行きます:

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-userProfileForm内のformの参照が既にあるため、(ngSubmit)内のform valueを渡す必要はありません。

の代わりに:

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

デモ((change)を使用)

デモ(valueChangesを使用)

13
developer033

最も簡単な方法は、パスワードだけのフォームグループを作成することです。

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();
4
Fabio Antunes

この投稿のほとんどのメソッドは機能しますが、setTimeoutを使用して実行する必要があります。

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

Angularバグ、問題 ここ および ここ のように見えます

1
ranbuch

テンプレートのコントロールに[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
ADreNaLiNe-DJ