it-swarm.com.de

Angular 4 Reaktive Formulare Umschalten der Validierung für ausgeblendete Formularelemente

Ich habe ein reaktives Formular, bei dem unter Last keine Felder erforderlich sind. Wenn eine Option ausgewählt wird, die zusätzliche Formularelemente zur formGroup hinzufügt, sind alle neu angezeigten Felder erforderlich. Wenn das Kurznamensfeld ausgeblendet ist, sollten Sie das Formular problemlos abschicken können. Wenn der Kurzname angezeigt wird, ist das Kurznamensfeld erforderlich, und die Schaltfläche zum Senden ist deaktiviert, bis das Kurznamensfeld voll ist. Hier ist ein Beispiel für das, was ich tun möchte.

Meine Frage ist, wie kann ich die Validierung aktivieren/deaktivieren, wenn das Formularelement angezeigt/ausgeblendet wird?

App.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule, ReactiveFormsModule ],
  declarations: [ AppComponent, HelloComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

App.component.ts

import { Component, OnInit } from '@angular/core';
import { Validators, FormControl, FormGroup, FormBuilder } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {
  name = 'My Reactive Form';

  constructor(
    private fb: FormBuilder
  ) {}

  myForm: FormGroup;
  showNick: boolean = false;

  ngOnInit() {
    this.myForm = this.fb.group({
      'firstName': new FormControl(),
      'nickName': new FormControl('', Validators.required),
      'lastName': new FormControl()
    })
  }

  toggleNick() {
    this.showNick = !this.showNick;
  }
}

app.component.html

<form [formGroup]="myForm">
  <div class="my-box">
    <label>
      First Name
      <input type="text" formControlName="firstName">
    </label>
  </div>
  <div class="my-box nickname">
    Nickname? &nbsp; <a (click)="toggleNick()">yes / no</a>
  </div>
  <div class="my-box" *ngIf="showNick">
    <label>
      Nickname
      <input type="text" formControlName="nickName">
      <span class="validation-message" *ngIf="!myForm.controls['nickName'].valid && myForm.controls['nickName'].dirty">
    This field is invalid
  </span>
    </label>
  </div>
  <div class="my-box">
    <label>
      Last Name
      <input type="text" formControlName="lastName">
    </label>
  </div>
  <button [disabled]="myForm.invalid">Submit</button>
</form>
3
iChido

In meiner Bewerbung habe ich eine ähnliche Anforderung. Wenn der Benutzer verlangt, per Text benachrichtigt zu werden, ist das Telefon erforderlich. Ansonsten ist die Telefonnummer optional.

Ich habe diese Methode geschrieben:

setNotification(notifyVia: string): void {
    const phoneControl = this.customerForm.get('phone');
    if (notifyVia === 'text') {
        phoneControl.setValidators(Validators.required);
    } else {
        phoneControl.clearValidators();
    }
    phoneControl.updateValueAndValidity();
}

Es wird von diesem Code aus aufgerufen, der sich in ngOnInit befindet:

    this.customerForm.get('notification').valueChanges
                     .subscribe(value => this.setNotification(value));

Wenn der Benutzer das Benachrichtigungsfeld (ein Optionsfeld) ändert, ruft er die setNotification-Methode auf und übergibt den Wert. Wenn es sich bei dem Wert um eine Benachrichtigung über 'Text' handelt, wird die Gültigkeit des Telefons als erforderlich festgelegt.

Andernfalls wird die Bestätigung des Telefonfelds gelöscht.

Dann muss muss updateValueAndValidity aufgerufen werden, um die Formularinformationen mit dieser neuen Überprüfung zu aktualisieren.

10
DeborahK

Sogar die Felder sind vor dem Benutzer verborgen, von dem die Felder im Reaktiven aktiv sind. Sie müssen das Feld also einfach mit folgendem Code vom reaktiven aus deaktivieren

this.myForm.get("nickName").disable();

Ändern Sie die Funktion toggleNick () wie unten angegeben

toggleNick() {
    this.showNick = !this.showNick;
    if(showNick) {
         this.myForm.get("nickName").enable();
    } else {
         this.myForm.get("nickName").disable();
    }
}
8
vivekkurien

Ich denke, die beste Option dafür ist es, Felder zu einem Teil der ursprünglichen Form mit all ihren Validierungen zu machen und wann Sie Felder oder verschachtelte Formulare programmgesteuert deaktivieren und aktivieren möchten.

Beispiel: https://stackblitz.com/edit/angular-ojebff

https://stackblitz.com/edit/angular-ojebff?embed=1&file=app/input-errors-example.html

2
andy

Ich habe diese Lösungen nicht gefunden, wenn Sie viele optionale Felder in einer komplexen Form haben.

Was ich getan habe, ist so etwas:

export class MyComponent implements AfterViewChecked {

 @ViewChildren(FormControlName) allFormControlInDOM: QueryList<FormControlName>;

 // ...

  ngAfterViewChecked(): void {
    // We must disable the controls that are not in the DOM
    // If we don't, they are used for validating the form
    if (this.allFormControlInDOM) {
      const controls: { [p: string]: AbstractControl } = this.myForm.controls;
      for (const control in controls) {
        if (controls.hasOwnProperty(control) && controls[control] instanceof FormControl) {
          const found = this.allFormControlInDOM.find((item: FormControlName) => item.name === control);
          if (found) {
            controls[control].enable();
          } else {
            controls[control].disable();
            controls[control].setValue(null);
          }
        }
      }
    }
  }

// ...

}

Ich hoffe das kann helfen :)

0
Klem231188