I have a simple form that looks like this
<form (ngSubmit)="save()" #documentEditForm="ngForm">
...
</form>
and need to submit the the form and check its validity from outside
eg. Either submit it programatically, or with a <button type="submit">
that is outside the <form>
tags.
Important: if using Angular material form controls + reactive forms
Call
onSubmit(undefined)
to properly setsubmitted = true
on the[formGroup]
directiveHere's part of the sourcecode for the
[formGroup]
directive. (for reactive forms)You use it like this:
And you can get a reference to
ngForm
in yourts
file with:If you were to just call
this.ngForm.ngSubmit.emit()
as some other answers have suggested you won't get the all importantsubmitted = true
set.Why does this matter?
If you're using any Angular CDK or Angular Material controls the error condition isn't displayed unless the form field has been touched (clicked or gained focus) OR the form as a whole has been submitted.
So if you have a missing required field that the mouse/cursor has never entered then that field won't be shown in red even if you do
ngSubmit.emit()
(becausesubmitted = false
for the form and the control hastouched = false
).So how does it work normally with a regular submit button?
Normally if you have
<button type='submit'>Submit</button>
(inside the<form>
tag) it will trigger the standard HTML<form>
to submit (nothing to do with Angular) - and that raises a standardsubmit
event on the form tag.IF that
<form>
tag also has a[formGroup]
directive on it (as shown above) then the HTML formsubmit
event is 'caught' by the directive and that's what causes theonSubmit()
function above to be called.This in turn raises the
ngSubmit
event - which you can catch yourself if you need to do further processing - like showing an alert.So it's very important to call
onSubmit
and notngSubmit.emit
to get the validation handling to work when using material controls. The $event parameter can just be null or undefined.Further reading: Look at
ErrorStateMatcher
(for Angular CDK/Material only) to see the exact rules.Even more confusing: The
[formGroup]
directive is NOT the same object asFormGroup
which just holds data. Only the directive hassubmitted
on it - whereasFormGroup
has things liketouched
,pristine
,dirty
.Found out how to do it:
<formname>.ngSubmit.emit()
<formname>.form.valid
Example:
If you are using Reactive Forms use the formGroup invalid property to disable the submit button:
...
Below solution is working in my case, please try this simple solution. I am not sure, if it will be working into all the conditions:
The button should be declared outside the form like this:
The validation of the form should check into save() by following conditions
Hope this simple solution will help you.
A trick that worked for me using
was this:
The correct way of doing is actually
The form needs to have an ID
id="example-form"
and the submit button a matching ID in theform="example-form"