-
-
Save nuxodin/73a2c2423cbbf6818c28ad803985d5c7 to your computer and use it in GitHub Desktop.
/* Copyright (c) 2016 Tobias Buschor https://goo.gl/gl0mbf | MIT License https://goo.gl/HgajeK */ | |
if (!HTMLFormElement.prototype.reportValidity) { | |
HTMLFormElement.prototype.reportValidity = function() { | |
if (this.checkValidity()) return true; | |
var btn = document.createElement('button'); | |
this.appendChild(btn); | |
btn.click(); | |
this.removeChild(btn); | |
return false; | |
}; | |
} | |
if (!HTMLInputElement.prototype.reportValidity) { | |
HTMLInputElement.prototype.reportValidity = function(){ | |
if (this.checkValidity()) return true | |
var tmpForm; | |
if (!this.form) { | |
tmpForm = document.createElement('form'); | |
tmpForm.style.display = 'inline'; | |
this.before(tmpForm); | |
tmpForm.append(this); | |
} | |
var siblings = Array.from(this.form.elements).filter(function(input){ | |
return input !== this && !!input.checkValidity && !input.disabled; | |
},this); | |
siblings.forEach(function(input){ | |
input.disabled = true; | |
}); | |
this.form.reportValidity(); | |
siblings.forEach(function(input){ | |
input.disabled = false; | |
}); | |
if (tmpForm) { | |
tmpForm.before(this); | |
tmpForm.remove(); | |
} | |
this.focus(); | |
this.selectionStart = 0; | |
return false; | |
}; | |
} |
@nuxodin I think there is a bug. It looks like you still use this.form
when it could be undefined. You probably want this:
if (!HTMLInputElement.prototype.reportValidity) {
HTMLInputElement.prototype.reportValidity = function(){
if (this.checkValidity()) return true
var form = this.form;
var tmpForm;
if (!form) {
tmpForm = document.createElement('form');
tmpForm.style.display = 'inline';
this.before(tmpForm);
tmpForm.append(this);
}
var siblings = Array.from(form.elements).filter(function(input){
return input !== this && !!input.checkValidity && !input.disabled;
},this);
siblings.forEach(function(input){
input.disabled = true;
});
form.reportValidity();
siblings.forEach(function(input){
input.disabled = false;
});
if (tmpForm) {
tmpForm.before(this);
tmpForm.remove();
}
this.focus();
this.selectionStart = 0;
return false;
};
}
Although as far as I know html5 validation doesn't work without a form tag anyway. So it probably isn't necessary to support inputs that aren't inside form tags.
Also the focus() in my implementation is a fallback. The submit/reportValidity already does this. I could probably remove it entirely.
My Polyfill works at least in IE.
I use this.form and if this.form is undefined, I wrap it into a newly created form.
So this.form is always defined.
I don't know exactly how it is in the specification, but validation works without forms in current browsers:
https://jsfiddle.net/7jode1g5/
focus() and selectionstart=0 is needed in IE11
In line 19 you are definingvar tmpForm
, but it's already defined 2 lines above.
I recommend wrapping all that code in:
if (typeof HTMLFormElement !== 'undefined') {
// your polyfill
}
So then it'll be also compatible with server side rendering.
this is the form version, which and seems to work in IE11, and accounts for the case the form has a novalidate attribute, in which case the form would submit.
https://gist.github.com/mcshaz/c65040c11e6daffe356cbedb7ec84ce4
Is there anyway to intercept or listen if reportValidity
has been called?
@lukescott
Great Work!
I updated my gist with a similiar polyfill.