I'm a big fan of HTML form validation because it replaces JavaScript code I've been writing for nearly twenty years. Unfortunately it still isn't supported in Safari (don't get me started on Apple and their priorities when it comes to the web), but I love the idea of being able to do stuff in HTML itself. In fact, a site recently launched that demonstrates many examples of this: You Might Not Need JavaScript. If you haven't checked it out, definitely give it a read. It is a great example of how HTML, and CSS, can replace JavaScript snippets we've used over the years.
So given all of that, this morning I thought of something that was exactly the opposite of moving from JavaScript to HTML. Can we use HTML-based form validation in a purely JavaScript form? Turns out you can (again, if the browser itself supports it). Given that you can dynamically create DOM items via createElement, could you use that to add easy email validation in JavaScript? Looks like you can:
var element = document.createElement('input');
element.setAttribute('type','email');
element.value = 'foo@foo.com';
console.log(element.validity.valid);
All this snippet does is create a virtual input element, set the type to email, and then sets a particular value. It then simply outputs the valid state. You can rewrite this into a simple function:
var elm;
function isValidEmail(s) {
if(!elm) {
elm = document.createElement('input');
elm.setAttribute('type', 'email');
}
elm.value = s;
return elm.validity.valid;
}
console.log(isValidEmail('foo'));
console.log(isValidEmail('goo@goo.com'));
console.log(isValidEmail('zoo'));
I don't like the fact that I set a global variable, but I thought it was a nice way to cache the DOM element. If this were wrapped up in a module then I'd store it local to that.
So again, it won't work in non-supported browsers, but it sure as heck is pretty simple, right? You could also use this to validate a URL and other values. Any comments on this approach?
You can run a JSBin of it here: https://jsbin.com/diqepa/edit?js,console
Archived Comments
Not sure the DOM creation is expensive enough to worry about caching, but here's how you can avoid the global variable leak:
var isValidEmail = (function (){
var elm;
return function (s) {
if(!elm) {
elm = document.createElement('input');
elm.setAttribute('type', 'email');
}
elm.value = s;
return elm.validity.valid;
}
})();
That's what I meant when I talked about turning it into a module. :)
I ran a comparison using an internal test script that I've been using over the years to compare against 290 known good/bad email addresses (per RFC rules). I itnegrated this HTML5 validation check as one of the tests it performed better than ColdFusion's built-in function, but not better than a CF regex or Java library that I use. (NOTE: The HTML5 technique is highly dependent on client-side browser support or it won't work.)
My response contained too much information to post in a Disqus comment, so I posted it on my blog:
https://gamesover2600.tumbl...
Pretty cool testing there. Thanks for sharing that.
Better using Regular Expression :)
Perhaps. Then again - I'd trust the browser vendor's regex internally built into the engine generally.
In 2012 I suggested this solution (with optional regex fallback) on StackOverflow: http://stackoverflow.com/a/...
But the advantage over a plain regex solution might be minimal. Everybody including browser vendors put their pants on one leg at a time, and the HTML5 spec even suggests a ready-to-use expression: https://html.spec.whatwg.or...
That's why I use exactly that pattern in my form validation API polyfill, too (and not my suggestion from SO): https://github.com/hyperfor...
I'm confused - if you think the strategy is minimally better, why do you prefer a regex?
What I wanted to say was, that the advantage of tapping into the browser's email validation might not be worth the hassle, if you can use the same regex directly yourself, that the browser uses (most probably) anyhow. (Especially because you might need a fallback anyway, depending on your browser support needs.)
I still think, it is a very nice idea to hijack a browser feature like this, though. A prime example is, e.g., URL manipulation using a virtual <a> and its methods:
The above client-side form validation API polyfill isn't consistent with the server-side OWASP validation regex and a full domain name can include up to 255 octets.
I've encountered deliverability issues where, even if the email is valid per the RFC, some technologies (CFMail, SMTP servers, transactional email API services, etc) won't agree that it's valid. Gmail appears to be able to send and receive using email addresses that have high-ASCII/UTF characters in the username, but no other SMTP servers I've reviewed will accept them as "valid".
I think it's important to remember that *all* client-side validations should be backed up by server-side validations as well. The fact is - if we can catch *most* issues on the client, even if it isn't 100%, we are still providing a benefit to the end user by giving them quicker turnaround.