Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Polyfill for reportValidity()
/* 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
Copy link
Author

nuxodin commented Jun 13, 2019

@lukescott
Great Work!
I updated my gist with a similiar polyfill.

  • handles Inputs without a form
  • extended Native HTMLInputElement
  • reused the form.reportValidity-polyfill
  • no es6 for ie11
  • but it needs some polyfills for ie11 (Array.from, Element-Methods: before, after and remove)
  • tested in ie11 but not in old safaris

@lukescott
Copy link

lukescott commented Jun 13, 2019

@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.

@nuxodin
Copy link
Author

nuxodin commented Jun 13, 2019

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

@BrodaNoel
Copy link

BrodaNoel commented Sep 10, 2019

In line 19 you are definingvar tmpForm , but it's already defined 2 lines above.

@BrodaNoel
Copy link

BrodaNoel commented Sep 10, 2019

I recommend wrapping all that code in:

if (typeof HTMLFormElement !== 'undefined') {
 // your polyfill
}

So then it'll be also compatible with server side rendering.

@mcshaz
Copy link

mcshaz commented Apr 17, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment