DEV Community

Adam Crockett
Adam Crockett

Posted on

The free from Validation Framework cookbook 🌽

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
    }
}
Enter fullscreen mode Exit fullscreen mode

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.elementsto 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
    }
}
Enter fullscreen mode Exit fullscreen mode

That's it. Nothing more to say, no framework needed β™₯️

Discussion (2)

Collapse
tqbit profile image
tq-bit
    if (!form.checkValidity()) {
        // form invalid!
        ... Stuff happens
    }
Enter fullscreen mode Exit fullscreen mode

^this

I didn't know this. Thanks for the article :-)

Collapse
adam_cyclones profile image
Adam Crockett Author

Same until recently, I knew about: input.checkValidity() but not form.checkValidity() Its a really nice time saver, otherwise as I say break out the loops.

Bonus: I also found this HTMLFormElement.reset() which is yet another time saver - makes you think, I must keep an eye out on these native elements methods.