One attribute makes form validation frameworks completely redundant: <form novalidate>
is the star of the show, but it doesn't do what you think!
But first, why do we have custom validation if html 5 has a huge plethora of validation attributes? I believe it's 2 fold, you cannot style the browser native validation messages, or the user has to support pre html 5 browsers (at this point, this ask is just sheer cruelty to frontend developers).
novalidate
is similar to preventDefault()
in that it prevents native browser behaviour, specifically validation messages, it actually hides the ugly native browser html 5 messaging you get if you use any html 5 validation attributes, such as required
, min
, max
, type
, pattern
and instead does nothing...
Soo you broke my form.. how is this validation?
It's still validating but you have to switch over to JavaScript and manage the validation yourself...
Kind of like a form validation framework but without any dependencies, loading, weight or new syntax?
Yep, 😊 because HTMLFormElement and all inputs have a few methods and less well known tricks, tricks you might not know, you can easily pull of validation.
Tricks 🐰🎩
Let's see, to do this we will need:
- HTMLFormElement.checkValidity()
- HTMLInputElement.checkValidity()
- new FormData(someFormEl);
- all html 5 accessible validation attributes
Above are all the pieces you need in order to create accessable, JavaScript enabled, simple yet powerful form.
But React, Vue, Angular
People, your submit and on change events all have target
references to the actual element 😱, you can call these methods just like any other JavaScript that ever has, or ever will be. You can even ref too if you like.
Do I use these techniques? yes I do in all of the above.
Simple validation on submit
So because it's hard to describe for everything, let's do a React example
function onSubmit(e) {
e.preventDefault();
const form = e.target;
if (!form.checkValidity()) {
// form invalid!
... Stuff happens
}
}
Okay from here we could just report some none specific error that might be fine in some cases and actually a security requirement in say a login form, but what if we want to check all the values of the form and find the broken thing. Off the top of my head there are a few ways, we could use HTMLFormElement.elements
to return a Node list of all elements in the array but that uses the DOM and might not fit with idiomatic styles of your given framework even though it's way easier! even so you could call element[I]checkValidity()
inside of a loop, that could help you work it out... Or we could do this:
function onSubmit(e) {
e.preventDefault();
const form = e.target;
if (!form.checkValidity()) {
// form invalid!
const data = new FormData(form);
const formEntries = Object.fromEntries(data.entries());
// Loop through and validate
formEntries
}
}
That's it. Nothing more to say, no framework needed ♥️