Search code examples
jqueryasp.net-mvcvalidationclient-side-validation

Better way to handle client-side validation with placeholder workaround


I'm doing a javascript workaround for placeholders, such that for broswers that do not recognise it, I display the placeholder using the input/textarea value. But this messes my client side validation on the ASP.net MVC app.

I saw this SO article which is not something I'd like to implement as: (1) I have a few fields that use placeholders, (2) for my placeholder, I use a ModelMetaDataprovider which either returns the DisplayAttribute or the DescriptionAttribute or the name of the field (split into words and properly case-converted).

Now, I also read this, which suggests using a custom validation attribute. However, I think this is an overkill since all I wanted is a different client-side validation.


Solution

  • Aha! I should have read that second link better. A guy suggested changing the jquery.validate.js to check for the placeholder attribute of the element. But I took that as a bad solution as that will likely be overwritten with an upgrade of the jquery.validate.js.

    However, I discovered I could override the validator method in my our script. So I wrote this which appears to work. Basically, I copied the method but added the lines indicated below.

    In my own validation js, I added I replace check to see if the element has a placeholder attribute and if its equals the placeholder text:

    $.validator.addMethod(
        'required',
        function(value, element, param) {
            // check if dependency is met
            if ( !this.depend(param, element) )
                return "dependency-mismatch";
            switch( element.nodeName.toLowerCase() ) {
            case 'select':
                // could be an array for select-multiple or a string, both are fine this way
                var val = $(element).val();
                return val && val.length > 0;
            case 'input':
                if ( this.checkable(element) )
                    return this.getLength(value, element) > 0;
            default:
                // REPLACED THIS:
                //return $.trim(value).length > 0;
                // WITH THIS:
                return ($.trim(value).length > 0) && (value != element.getAttribute('placeholder'));
            }
        }, '');
    

    It appears to work. And running a script debug, I can see it replaces the 'required'.