Angular 4如何显示隐藏的嵌套表单组验证

时间:2019-02-14 12:28:02

标签: javascript angular forms validation angular-forms

我正在做角度4验证。我有一个反应式表单,其中有两个单选按钮和两个表单组。如果用户选择的第一个单选按钮,它将从第二个表单组中删除验证,并在第一个表单组中添加验证;当用户的第二个单选按钮时,它将在第二个窗体组中添加验证,并从第一个表单组中删除。

下面是我的表单组示例

this.mainForm = this.formBuilder.group({
    cardOrBank: new FormControl(''),
    cardDetails: new FormGroup({
        cardNo: new FormControl(''),
        cvv: new FormControl('')
    }),
    bankDetails: new FormGroup({
        accNo: new FormControl(''),
        ifsc: new FormControl('')
    })
});

HTML

<form [formGroup]="mainForm" (ngSubmit)="onFormSubmit()">
    <div>
        Select: <input type="radio" formControlName="cardOrBank"> card
        <input type="radio" formControlName="cardOrBank"> bank
    </div>
    <div formGroupName="cardDetails">
        <div>
            Card No: <input formControlName="cardNo">
        </div>
        <div>
            CVV: <input formControlName="cvv">
        </div>
    </div>
    <div formGroupName="bankDetails">
        <div>
            ACC No: <input formControlName="accNo">
        </div>
        <div>
            IFSC: <input formControlName="ifsc">
        </div>
    </div>
    <div>
        <button type="submit">Submit</button>
    </div>
</form>

如果从单选按钮中选择卡,它将在cardDetails表单上添加验证,并从bankDetails中删除验证,反之亦然。

P.S:根据要求,表单字段可能更多。

谢谢。

4 个答案:

答案 0 :(得分:1)

您可以这样做

addValidation() {
   this.form.get('title').setValidators([Validators.required, Validators.minLength(3)]);
   this.form.get('title').updateValueAndValidity();
}

removeValidation() {
 this.form.get('title').clearValidators();
 this.form.get('title').updateValueAndValidity();
}

答案 1 :(得分:1)

经过大量工作,我终于能够实现这一目标。

下面是您需要在代码中进行的更改:

// in component.ts file  : 


// Write two genric methods which sets and clears the validator 

setRequireValidator(form:any){
  for (const field in form.controls) { // 'field' is a string
   let con = form.get(field); // 'control' is a FormControl
    con.setValidators([Validators.required]);
    con.updateValueAndValidity();
}

}

removeValidator(form:any){
  console.log('form contro',form);
  
  for (const field in form.controls) { // 'field' is a string
   let con = form.get(field); // 'control' is a FormControl
    con.clearValidators();
    con.updateValueAndValidity();
}
  
 
 // while initiallizing the form ragister the event for value changed on `cardOrBank`

// check which value user has selected and accordingly toggle between them 


 this.mainForm.get('cardOrBank').valueChanges.subscribe((val) => {
        const cardControl = this.mainForm.get('cardDetails');
        const bankControl = this.mainForm.get('bankDetails');
           if(val === 'card') {
           alert('card sletecd')
           this.removeValidator(bankControl);
          this.setRequireValidator(cardControl);

        } else{
             alert('bank sletecd')
          this.removeValidator(cardControl);
          this.setRequireValidator(bankControl);      
        }
   
 });
 
 
 
<!-- In component.html file-->


<form [formGroup]="mainForm" (ngSubmit)="onFormSubmit()">
    <div>
      <label>
      <!-- You missed value attribute --> 
     <input type="radio" value="card" formControlName="cardOrBank">
       <span>Card</span>
   </label>
   <label>
     <input type="radio" value="bank" formControlName="cardOrBank">
       <span>Bank</span>
   </label>
    </div>
    <div formGroupName="cardDetails">
        <div>
            Card No: <input formControlName="cardNo">
        </div>
        <div>
            CVV: <input formControlName="cvv">
        </div>
    </div>
    <div formGroupName="bankDetails">
        <div>
            ACC No: <input formControlName="accNo">
        </div>
        <div>
            IFSC: <input formControlName="ifsc">
        </div>
    </div>
    <div>
        <button type="submit" [disabled]="!mainForm.valid">Submit</button>
    </div>
</form>

  

这是您要求的工作示例:

     

Working demo

答案 2 :(得分:0)

我假设cardOrBank表单控件具有两个值'card'和'bank'。在您的 ngOnInit 中,应该订阅单选按钮表单控件的 valueChanges

ngOnInit() {
 this.mainForm.get('cardDetails').valueChanges.subscribe((cardOrBank) => {
   if(cardOrBank === 'card') {
     this.mainForm.get('cardDetails').setValidators(Validators.required); 
     this.mainForm.get('bankDetails').removeValidators(Validators.required);

   } else {
     this.mainForm.get('bankDetails').setValidators(Validators.required); 
     this.mainForm.get('cardDetails').removeValidators(Validators.required);

   }                
   this.mainForm.get('bankDetails')updateValueAndValidity();                
   this.mainForm.get('cardDetails')updateValueAndValidity();

 });
}

您的单选按钮应具有值属性

 <div>
      Select: <input type="radio" value="card" formControlName="cardOrBank"> card
      <input type="radio" value="bank" formControlName="cardOrBank"> bank
 </div>

答案 3 :(得分:0)

您可以做两件事,要么可以放置显式方法,要么可以订阅formControlName发生的更改以执行此验证器切换。

如果您要订阅,请订阅ngOnInit()生命周期挂钩:

      ngOnInit() {
         this.mainForm.get('cardDetails').valueChanges.subscribe((val) => {
           if(val === 'card') {
             this.mainForm.get('cardDetails').setValidators(Validators.required);
           } else {
             this.mainForm.get('bankDetails').removeValidators(Validators.required);
           }
         this.mainForm.get('bankDetails').updateValueAndValidity();
         });
        }

**add Value attribute in the html.**

**2nd Option :**



Select: <input type="radio" formControlName="cardOrBank (change)="changedPayment('card')"> card
 <input type="radio" formControlName="cardOrBank (change)="changedPayment('bank')> bank


    changedPayment(val) {
     if(val === 'card') {
             this.mainForm.get('cardDetails').setValidators(Validators.required);
           } else {
             this.mainForm.get('bankDetails').removeValidators(Validators.required);
           }
         this.mainForm.get('bankDetails').updateValueAndValidity();
    }