简体   繁体   中英

Angular2 Form : trigger or update validation properly & programmatically

I'm building a Wizard in Angular2 - Redux. I'm using Reactive Forms to handle & submit data for every step inside. I need to trigger form validation programmatically, because the declaration of my call-to-action button, in order to go to the next step, is in a separated component from the stepComponent. See wireframe below

Components's wireframe

在此处输入图片说明

Current Behavior

  1. Only when a change has ocurred on a form's control, its own validation runs. And it's touched & valid property is updated accordingly.

  2. As I am in a Redux environment, I dispatch an action to get the current-step form data in order to be applied to the payload. When that's is finished, I trigger another action to save data.

  3. Actually, I know when the form is valid or invalid by using:

     submitForm(form: FormGroup):void{ if(form.valid){ this.actionsStep.saveStep(form.value); }else{ console.log('Form invalid ') } }
  4. As my forms uses controls's properties to render a custom message when a error has happened, I want to re-run validation by submit the form or by using another function to be able to use the control's properties again to notify where an error has occurred.

StepComponent.ts : Form declaration

this.stepForm = this.formBuilder.group({
  name: ['', Validators.required],
  email: ['', Validators.required]
});

step-component.html : Form HTML

<form id="ngForm" [formGroup]="stepForm" (ngSubmit)="submitForm(stepForm.value)" class="form-horizontal form-box-content">
    <div class="form-group row" [ngClass]="{'has-danger' :name.invalid && name.touched}">
      <label class="col-md-2 col-form-label">Name:</label>
      <div class="col-md-10">
        <input 
        name="titulo" class="form-control required" 
               formControlName="name" placeholder="" type="text"  [ngClass]="{'form-control-danger' :name.invalid && name.touched}" >
        <small class="form-control-feedback text-danger" *ngIf="name.invalid && name.touched && name.hasError('required')">
          The name is required
        </small>
      </div>
  </div>

Attemps

I tried to use

  1. Update Validity:

    this.stepForm.updateValueAndValidity();

  2. Update Validity providing params:

    this.stepForm.updateValueAndValidity({ onlySelf: false, emitEvent: true });

  3. Mark each control as touched (To trigger event as I've typed something)

    for (var i in this.stepForm.controls) { this.stepForm.controls[i].markAsTouched(); }

  4. The solutions which requires submit function to be called from the HTML will not work for me because the button and the form are in separated components.

5. Is there any way to trigger or update validation programmatically or at least to submit a form properly in a function?

Previous Research

I found many help links to achieve this, however,those solutions work only when the button is declared in the same component. And also, when button is inside the form tag:

我基本上有相同的设置,并通过做相当于

(this.stepForm as any).submitted = true

In case someone else is still trying to do this. I did this by using ViewChild to grab references to the referenced components and stepper. Then control the next button click and do not have matStepperNext on the button.

<button mat-button (click)="onStepOneNextClick()">Next</button>

@ViewChild(MatStepper) stepper: MatStepper;
@ViewChild(StepOneComponent, { static: true }) stepOneComponent: StepOneComponent;

onStepOneNextClick() {
  if (this.stepOneComponent.form.invalid) {
    this.stepOneComponent.form.markAllAsTouched();
  }
  else {
    this.stepper.next();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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