Submitting a form after asynchronous validation
This week a colleague reached out to me to get my opinion on how he should validate and submit a form.
Now I know what you are probably thinking: "This is basic JS", but let me reassure you that in the context of the application it was a lot harder to figure out.
After examining our options and some back and forth we agreed on my proposed solution.
Goal and explanation
The goal of my example is to
- prevent the form from being submitted immediately,
- perform some asynchronous validation and
- actually submit the form once the validation is done.
Using a submit
handler is a pretty common way to validate forms. When the submit button is clicked by the user, the submit
handler prevents the form from being submitted by calling e.preventDefault()
.
Now is the perfect time to fire of an AJAX request to validate some data on the server side.
In the response callback (simulated by the setTimeout
) all that is left to do, is to actually submit the form by calling submit()
on the exampleForm
element.
Solution
The following snippet is the most basic example I could come up with to demonstrate the solution I proposed.
<form id="example-form" action="some-action" method="post"> <button type="submit">Submit</button> </form> <script> const exampleForm = document.querySelector("#example-form"); document.addEventListener("DOMContentLoaded", function () { exampleForm.addEventListener("submit", function (e) { e.preventDefault(); // Prevent default form submission setTimeout(() => { exampleForm.submit() // Skips the JS event handler and immediately submits the form }, 10000); }) }) </script>
Gotchas
Make sure none of your form inputs are named "submit", otherwise you'll run into a "submit is not a function" error. That is something we had to learn the hard way, thankfully, stackoverflow had our backs.
Conclusion
By preventing the default event propagation and submitting the form manually you are able to asynchronously validate your form. I hope this post helps you out should you ever need to implement something like this yourself.