2

I'm building a very simple Validation plugin that uses part of the Constraint validation API. I'm using 2 features of the API, valueMissing and patternMismatch like so:

var el = $(this)[0];

if ( el.validity.valueMissing || el.validity.patternMismatch )  {
        $errMsg.show();
} else {
        $errMsg.hide();
}

I'd like to write my own polyfill so these features work in older browsers as opposed to using an entire HTML5 validation library or plugin.

So I guess what I'm trying to achieve is something like this:

if (!typeof document.createElement( 'input' ).checkValidity == 'function'){
    validity.valueMissing = function(){
        // check for value
    }
}

However, I can't figure out how to go about this, nor how the element is used as the first part of the function:

el.validity.valueMissing

Thanks in advance for any help or suggestions!

2
  • what type of object is el from the first example ? Commented Jul 7, 2014 at 14:37
  • It's a JavaScript DOM element: var el = $(this)[0]; Commented Jul 7, 2014 at 15:12

2 Answers 2

2

There would be a bit of work involved for this poly, but what you need to do, is alter HTMLInputElement's prototype, so each new instance has those methods and propertyes (validity, checkValidity and so on).

Something along these lines:

HTMLInputElement.prototype.testMethod = function (e) { console.log(e) };
HTMLInputElement.prototype.testProp = 'foo';
var input = document.createElement('input');
input.testMethod(input.testProp);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your help Poelinca. This certainly pointed me in the right direction, so +1 for your answer. However, I cannot mark as correct as it's not the complete answer
1

So I finally figured this out with some help from Poelinca's answer...

if ( typeof document.createElement( 'input' ).checkValidity !== 'function' ) {
    Object.defineProperty( Element.prototype, 'validity', {
        get: function() {
            return this;
        }
    });

    Object.defineProperty( Element.prototype.validity, 'valueMissing', {
        get: function() {
            return this.value !== "";
        }
    });

    Object.defineProperty( Element.prototype.validity, 'patternMismatch', {
        get: function() {
            var pattern = this.getAttribute('pattern'),
                regEx = pattern !== null ? eval( "{/" + pattern + "/}" ) : "";
                value = this.value;

            if ( regEx !== "" ) {
                return regEx.test( value );
            } else {
                return true;
            }
            return false;
        }
    });
}

I used Object.defineProperty so I could call the function without using the parenthesis, which is how the native Constraint validation API works:

if ( el.validity.valueMissing || el.validity.patternMismatch )  { //...

From my research I learned that extending the DOM like this isn't really recommended as you can run into a lot of issues. For details read this article. The comments are particularly helpful as this article is quite dated.

In my case what I'm trying to do is quite simple and I only need to support IE8+. Maybe a little overkill but I like it.

Please feel free to improve / critique my answer!

Thanks!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.