it-swarm.com.de

Angular2 - Formular von außen prüfen und absenden

Ich habe eine einfache Form, die so aussieht

<form (ngSubmit)="save()" #documentEditForm="ngForm">
...
</form>

und müssen das Formular übermitteln und seine Gültigkeit von außen überprüfen 

z.B. Senden Sie es entweder programmgesteuert oder mit einem <button type="submit"> außerhalb der <form>-Tags.

27
Philipp

Finden Sie heraus, wie es geht:

  • auslösen mit <formname>.ngSubmit.emit() absenden
  • formularstatus mit <formname>.form.valid abrufen

Beispiel:

<form (ngSubmit)="save()" #documentEditForm="ngForm">
...
</form>

<button class="btn-save button primary"
(click)="documentEditForm.ngSubmit.emit()"
[disabled]="!documentEditForm.form.valid">SAVE</button>

Bearbeiten: Wie @ yuriy-yakovenko darauf hingewiesen hat, sollten Sie Ihrem Komponentencode Folgendes hinzufügen:

@ViewChild('documentEditForm') documentEditForm: FormGroupDirective; 

Vergessen Sie nicht, die FormGroupDirective zu importieren, falls Sie dies noch nicht getan haben

52
Philipp

Die richtige Vorgehensweise ist eigentlich

<form (ngSubmit)="save()" id="ngForm" #documentEditForm="ngForm"> 
    ... 
</form>

<button class="btn-save button primary" form="ngForm" [disabled]="!documentEditForm.form.valid">
    SAVE
</button>

Das Formular muss über eine ID id="example-form" verfügen, und der Submit-Button muss mit einer übereinstimmenden ID im form="example-form" übereinstimmen.

57
Yodacheese

Wenn Sie reaktive Formulare verwenden, deaktivieren Sie die Schaltfläche "Senden" mit der ungültigen Eigenschaft formGroup:

<button  
  form="ngForm"
  [disabled]=" editor.invalid>Enviar</button> 

...

<form [formGroup]="editor"  id="ngForm"   (ngSubmit)="save()" novalidate >
...
</form>
3
Javier Rojano

Ein Trick, der für mich funktioniert hat 

  • Reaktive Formen
  • Angular2
  • inkl. IE

war das:

<!-- real button will simulate click on invisible button (cf. form) -->
<button onclick="document.getElementById('hiddenSaveButtonForMicrosoftWithLove').click()">
  The Real Button outside forms
</button>

<form>
  <!-- will be called in the background and is never visible -->
  <button id="hiddenSaveButtonForMicrosoftWithLove" type="submit" style="display: none;">hiddenSaveButtonForMicrosoftWithLove</button>
</form>
3
Marcel

Wichtig: Bei Verwendung von Angular-Materialkontrollen + reaktiven Formen

Rufen Sie onSubmit(undefined) auf, um submitted = true in der [formGroup]-Direktive richtig einzustellen

Hier ist ein Teil des Sourcecodes für die [formGroup]-Direktive . (für reaktive Formen)

 onSubmit($event: Event): boolean {
    (this as{submitted: boolean}).submitted = true;
    syncPendingControls(this.form, this.directives);
    this.ngSubmit.emit($event);
    return false;
 }

Du erklärst es so:

<form [formGroup]="form" #ngForm="ngForm">

Und Sie können einen Verweis auf ngForm in Ihrer ts-Datei erhalten mit:

@ViewChild('ngForm') 
ngForm: NgForm;

Du verwendest es so:

this.formRef.onSubmit(undefined)

Beispiel:

// html
<form [formGroup]="form" #formRef="ngForm">
    // ...Form Controls
</form>

// component.ts
export class MyComponent {

    @ViewChild('formRef')
    formRef: FormGroupDirective;

    form: FormGroup = new FormGroup({
        myInput: new FormControl(''),
        //etc...
    });

    submitFormProgrammatically() {
        this.formRef.onSubmit(undefined);
    }
}

Wenn Sie einfach this.ngForm.ngSubmit.emit() anrufen würden, da einige andere Antworten nahelegen, erhalten Sie nicht den wichtigen submitted = true-Satz.

Warum ist das wichtig? 

Wenn Sie Angular CDK- oder Angular Material-Steuerelemente verwenden, wird die Fehlerbedingung nicht angezeigt, es sei denn, das Formularfeld wurde berührt (angeklickt oder hat den Fokus erhalten) OR, und das gesamte Formular wurde übermittelt.

Wenn Sie also ein fehlendes erforderliches Feld haben, das der Mauszeiger/Cursor nie eingegeben hat, wird dieses Feld nicht rot angezeigt, auch wenn Sie ngSubmit.emit() ausführen (weil submitted = false für das Formular und das Steuerelement touched = false hat).

Wie funktioniert es also normalerweise mit einem normalen Senden-Button?

Wenn Sie <button type='submit'>Submit</button> (innerhalb des <form>-Tags) haben, wird normalerweise der Standard-HTML-<form> zum Senden ausgelöst (nichts mit Angular zu tun) - und dies führt zu einem Standardereignis submit im Form-Tag.

Wenn dieses <form>-Tag auch eine [formGroup]-Direktive enthält (wie oben gezeigt), wird das HTML-Formular submit -Ereignis von der Direktive 'abgefangen' und bewirkt, dass die onSubmit()-Funktion oben aufgerufen wird. 

Dies wiederum löst das ngSubmit-Ereignis aus, das Sie sich selbst einfangen können, wenn Sie eine weitere Verarbeitung durchführen möchten, z. B. eine Warnmeldung.

Daher ist es sehr wichtig, onSubmit und nicht ngSubmit.emit aufzurufen, damit die Validierungsbehandlung bei der Verwendung von Materialsteuerelementen funktioniert. Der $ event-Parameter kann nur null oder undefiniert sein.

Weiterführende Literatur: Sehen Sie sich ErrorStateMatcher (nur für Angular CDK/Material) an, um die genauen Regeln zu sehen.

Noch verwirrender: Die [formGroup]-Direktive ist NICHT das gleiche Objekt wie FormGroup, das nur Daten enthält. Nur die Direktive enthält submitted - während FormGroup Dinge wie touched, pristine, dirty enthält.

2
Simon_Weaver

Die folgende Lösung funktioniert in meinem Fall. Bitte versuchen Sie diese einfache Lösung. Ich bin mir nicht sicher, ob es unter allen Bedingungen funktionieren wird:

<form #documentEditForm="ngForm" id="ngForm" (ngSubmit)="save(documentEditForm.valid)"> 
    ...Your Input Elements... 
</form>

Die Schaltfläche sollte außerhalb des Formulars wie folgt deklariert werden:

<button form="ngForm">Submit</button>

Die Validierung des Formulars sollte in save () anhand der folgenden Bedingungen überprüft werden

save(isValid:boolean){
    if(isValid) {
        ...Your code to save details...
    }
}

Hoffen Sie, dass diese einfache Lösung Ihnen helfen wird.

0
ChintanThummar

Dieses Beispiel funktioniert in Angular 6 und höher

<form (ngSubmit)="save()" id="ngForm" [formGroup]="form"> 
    ... 
</form>

<button type="submit" class="btn-save button primary" form="ngForm">Save</button>
0
Vince