简体   繁体   English

条件验证Angular 2 - 模型驱动表单

[英]Conditional Validation Angular 2 - Model Driven Forms

I have a form in Angular 2 in which I have a checkbox that changes some input[text] on the page. 我在Angular 2中有一个表单,其中有一个复选框,用于更改页面上的一些输入[文本]。 If the checkbox is checked an input that is called 'CPF' is changed to 'CNPJ'. 如果选中该复选框,则称为“CPF”的输入将更改为“CNPJ”。 I need CNPJ to be required only if the checkbox is checked since the user will not even see the 'CNPJ' input if its not checked. 我只有在选中复选框时才需要CNPJ,因为如果未选中,则用户甚至不会看到'CNPJ'输入。

Here's a snippet from the HTML code: 这是HTML代码的一个片段:

    <div class="wrap-acordo">
  <form [formGroup]="formDadosBancarios" novalidate class="" (ngSubmit)="enviarDados(formDadosBancarios.value)">

  <div class="row">
    <div class="col s12">
      <label> Titular: </label>
      <input type="text" formControlName="titular" name="titular" class="forms-econ" placeholder="Nome Completo do Titular">
         <div class="div-validar">
            <span [hidden]="formDadosBancarios.get('titular').hasError('required') || formDadosBancarios.controls.titular.valid || (formDadosBancarios.controls.titular.pristine && !submitted)">
              Titular Inválido (mínimo 3 caracteres).
            </span>
          <span *ngIf="formDadosBancarios.get('titular').hasError('required') && submitted">
            Campo titular obrigatório
          </span><br>
        </div>
    </div>
    <p class="check-margin">
      <input type="checkbox" [checked]="" formControlName="pessoa_juridica" #checkJuridica (change)="handleType(checkJuridica.checked)" class="filled-in check-negociacao" id="pessoaJuridica" />
      <label for="pessoaJuridica">Pessoa Jurídica</label>
    </p>
    <div *ngIf="checkJuridica.checked" class="col s12">
      <label> CNPJ: </label>
      <input type="text" formControlName="cnpj" name="cnpj" class="forms-econ" placeholder="Insira o CNPJ">
        <div class="div-validar">
          <span [hidden]="formDadosBancarios.get('cnpj').hasError('required') || formDadosBancarios.controls.cnpj.valid || (formDadosBancarios.controls.cnpj.pristine && !submitted)">
            CNPJ inválido
          </span>
          <span *ngIf="formDadosBancarios.get('cnpj').hasError('required') && submitted">
            CNPJ é obrigatório
          </span><br>
        </div>
    </div>
    <div *ngIf="!checkJuridica.checked" class="col s12 m6">
      <label> CPF: </label>
      <input type="text" formControlName="cpf" name="cpf" class="forms-econ" placeholder="Insira seu CPF">
        <div class="div-validar">
          <span [hidden]="formDadosBancarios.get('cpf').hasError('required') || formDadosBancarios.controls.cpf.valid || (formDadosBancarios.controls.cpf.pristine && !submitted)">
            CPF inválido
          </span>
          <span *ngIf="formDadosBancarios.get('cpf').hasError('required') && submitted">
            CPF é obrigatório
          </span><br>
        </div>
    </div>
    <div *ngIf="!checkJuridica.checked" class="col s12 m6">
      <label> Data de Nascimento: </label>
      <input type="text" class="forms-econ" formControlName="data_nasc" name="data_nasc" placeholder="ex.: Insira sua data de nascimento">
        <div class="div-validar">
          <span [hidden]="formDadosBancarios.controls.data_nasc.valid || (formDadosBancarios.controls.data_nasc.pristine && !submitted)">
            Data de nascimento é obrigatório
          </span>
        </div>
    </div>
    <div class="col s12 m6">
      <label> Banco: </label>
      <input type="text" class="forms-econ" formControlName="banco" name="banco" placeholder="Banco">
      <div class="div-validar">
        <span [hidden]="formDadosBancarios.controls.banco.valid || (formDadosBancarios.controls.banco.pristine && !submitted)">
         Banco é um campo obrigatório
        </span>
      </div>
    </div>
    <div class="col s12 m6">
      <label> Agência: </label>
      <input type="text" class="forms-econ" formControlName="agencia" name="agencia" placeholder="Agência">
       <div class="div-validar">
         <span [hidden]="formDadosBancarios.controls.agencia.valid || (formDadosBancarios.controls.agencia.pristine && !submitted)">
           Agência é um campo obrigatório
         </span>
       </div>
    </div>
    <div class="col s12 m6">
      <label> Conta: </label>
      <input type="text" class="forms-econ" name="conta" formControlName="conta" placeholder="Conta">
       <div class="div-validar">
         <span [hidden]="formDadosBancarios.controls.conta.valid || (formDadosBancarios.controls.conta.pristine && !submitted)">
           Conta é um campo obrigatório
         </span>
      </div>
    </div>
    <div class="col s12 m6">
      <label> Tipo: </label>
        <select name="tipo" formControlName="tipo" class="forms-econ">
          <option value="motivo_01">Tipo 01</option>
          <option value="motivo_02">Tipo 02</option>
        </select>
       <div class="div-validar">
         <span [hidden]="formDadosBancarios.controls.tipo.valid || (formDadosBancarios.controls.tipo.pristine && !submitted)">
           Tipo é um campo obrigatório
         </span>
       </div>
    </div>
  </div>
  <div class="row center-align">
    <div class="col s12 m6">
      <input type="submit" class="botao-medio btn-aceita" value="Aceitar">
    </div>

and here's a snippet from the component's code: 这是组件代码的片段:

  import { Component } from '@angular/core';
import {Http} from '@angular/http';
import { FormBuilder, FormGroup, Validators, FormArray, FormsModule, ReactiveFormsModule, AbstractControl, ValidatorFn } from '@angular/forms';
import {FinalizaNegociacaoService} from '../services/finaliza-negociacao.service';
import {dadosAcordo} from '../model/dados-acordo.interface';

@Component({
  moduleId: module.id,
  selector: 'detalhes',
  templateUrl: `finaliza-negociacao.component.html`,
  providers: [FinalizaNegociacaoService]
})

    export class FinalizaNegociacaoComponent  {

      public dados:dadosAcordo;
      public formDadosBancarios: FormGroup;

      public submitted: boolean; 
      public events: any[] = []; 
      public servError:any;
      public servSuccess:any;  
      cpf_REGEXP =  /^\d+$/;

      constructor(private _fb: FormBuilder, private finalizaAcordo:FinalizaNegociacaoService) { } 

        ngOnInit() {  
          this.formDadosBancarios = this._fb.group({
            titular: ['', [<any>Validators.required, <any>Validators.minLength(3)]],
            cpf: ['', [<any>Validators.required, Validators.pattern(this.cpf_REGEXP)]], 
            cnpj: ['', [<any>Validators.required, Validators.pattern(this.cpf_REGEXP)]],
            data_nasc: ['', <any>Validators.required],
            agencia: ['', <any>Validators.required ],
            banco: ['', <any>Validators.required],
            conta: ['', <any>Validators.required],
            tipo:  ['', <any>Validators.required],
            id: ['']
          })      
        }
    enviarDados(model: dadosAcordo, isValid: boolean) {
        this.submitted = true; 
        model.id = Math.floor((Math.random()*100));
        if(this.formDadosBancarios.valid){
          console.log("valid form")
         this.finalizaAcordo.enviaDadosBancarios(model)
          .subscribe(
            res => console.log("Sucesso"),
            error => console.log("ERRO")
          );
        }else{
          console.log("invalid form")
        }
      }

Can someone help me? 有人能帮我吗? Thanks in advance :) 提前致谢 :)

You can do the following: 您可以执行以下操作:

  1. Create a method to handle the changes of your checkbox : 创建一个方法来处理复选框的更改:
handleType(isJuridica: boolean): void {
  const cpfCtrl: AbstractControl = this.formDadosBancarios.get('cpf');
  const cnpjCtrl: AbstractControl = this.formDadosBancarios.get('cnpj');
  const reqValidators: ValidatorFn[] = [Validators.required, Validators.pattern(this.cpf_REGEXP)];
  const nullValidator: ValidatorFn = Validators.nullValidator;

  // Set validators accordingly
  if (isJuridica) {
    cpfCtrl.setValidators(nullValidator);
    cnpjCtrl.setValidators(reqValidators);
  } else {
    cpfCtrl.setValidators(reqValidators);
    cnpjCtrl.setValidators(nullValidator);
  }

  // Clean values (if you want to)
  cpfCtrl.patchValue('');
  cnpjCtrl.patchValue('');
  cpfCtrl.updateValueAndValidity();
  cnpjCtrl.updateValueAndValidity();
}
  1. Call it in template: 在模板中调用它:
...
<input type="checkbox" #checkJuridica (change)="handleType(checkJuridica.checked)" class="filled-in check-negociacao" id="pessoaJuridica" />
<label for="pessoaJuridica">Pessoa Jurídica</label>
...

You can check a simple demo below: 您可以查看下面的简单演示:

PLUNKER PLUNKER

In addition, there is this tutorial which can help you to understand better. 此外,本教程可以帮助您更好地理解。

your code is bit complicated but i'll give you tip,may help you to solve your problem. 你的代码有点复杂,但我会给你小费,可以帮助你解决问题。

  • no need to add validators.required on conditional field like cpf or cnpj, else you have to add validation on event fired on checkbox click. 无需在cpf或cnpj等条件字段上添加validators.required ,否则必须在复选框点击时触发的事件上添加验证。

  • if you have to disable submit button (in this case better is to call function in disabled attribut like this [disabled]=''checkValidation() and check there your all required fields. 如果你必须禁用提交按钮(在这种情况下更好的是在这个[disabled]=''checkValidation()中禁用attribut调用函数,并检查你所有必需的字段。

i hope this will put some light on your problem if still not please post full code either recreate your problem on plunker. 我希望这会对你的问题有所启发,如果仍然没有,请发布完整的代码或者在plunker上重新创建你的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM