Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MDL + jQuery validate integration: Work-around needed for mdl-radio__button validation

What would seem to be a normal use-case of jQuery.validate with MDL has gone awry. See this gist.

This works fine:

<h1>Without MDL</h1>
<form id="foo">
  <input type="radio" name="bar" value="1" /> 1
  <input type="radio" name="bar" value="2" /> 2
<input type="submit" />
</form>
<script>
     $(function() {
         $('#foo').validate({
             rules: {
                 "bar": {
                     required: true
                 },
             },
             errorPlacement: function(error, element) {
                 console.log(element);
             }
         });
     });
</script>

This does nothing:

<h1>With MDL</h1>
<form id="zha">
    <label for="baz__1" class="mdl-radio mdl-js-radio">
        <input type="radio" name="baz" value="1" id="baz__1" class="mdl-radio__button" /> 1
    </label>
    <label for="baz__2" class="mdl-radio mdl-js-radio">
        <input type="radio" name="baz" value="2" id="baz__2" class="mdl-radio__button" /> 2
    </label>
    <input type="submit" id="butt"/>
</form>
<script>
     $(function() {
         $('#zha').validate({
             rules: {
                 "baz": {
                     required: true
                 },
             },
             errorPlacement: function(error, element) {
                 console.log(element);
             }
         });
     });
</script>

Attaching jQuery.validator.setDefaults({ debug: true }) has no effect -- as in zero debug output -- in the MDL version. Removing either mdl-js-radio or mdl-radio__button makes it work as expected. My intuition is that MDL is updating the DOM in a way that disconnects jQuery's access to name= attributes, but I can't find any evidence to support that in the MDL source code.

Anybody got an integration that works here?

like image 943
BrianTheLion Avatar asked Jan 21 '16 02:01

BrianTheLion


People also ask

What is JQuery validation used for?

Form validation is a process of confirming the relevant information entered by the user in the input field.

Does JQuery validate require a form?

The jquery validate plugin requires a form element to function, so you should have your form fields (no matter how few) contained inside a form. You can tell the validation plugin not to operate on form submission, then manually validate the form when the correct submit button is clicked.

How we can use JQuery validation plugins in MVC?

UnobtrusiveJavaScriptEnabled" property value back to false and create a new file in "Scripts" folder and name it "script-custom-validator. js". Add the Jquery validator code in it as shown below i.e. The above piece of code attaches my account register form with jQuery form validator by using form ID.


1 Answers

After some research, I think I found a solution to your problem. It's an interesting one.
For me, your code works on Firefox but not on Chrome and Safari. The reason is pretty simple. MDL remove the CSS default style of your input radio buttons to hide them (not display: none, only height: 0, width: 0, opacity...). Chrome and Safari consider that like there are "hidden". Browsing the jQuery.validate code, I realized that the input radio buttons was never discovered. (your code works with a classic input on Chrome and safari). And why ? Because if you take a look at the default settings of jQuery.validate you can see that he ignore the input hidden.

defaults: {
   ...
   ignore: ":hidden",
   ...
onfocusin: function( element, event ) {

And the filter function

elements: function() {
    var validator = this,
        rulesCache = {};

    // select all valid inputs inside the form (no submit or reset buttons)
    return $(this.currentForm)
    .find("input, select, textarea")
    .not(":submit, :reset, :image, [disabled]")
    .not( this.settings.ignore ) // This line
    .filter(function() {
        if ( !this.name && validator.settings.debug && window.console ) {
            console.error( "%o has no name assigned", this);
        }

        // select only the first element for each name, and only those with rules specified
        if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) {
            return false;
        }

        rulesCache[this.name] = true;
        return true;
    });
},

To prevent this just add this piece of code :

jQuery.validator.setDefaults({
    ignore: ""
});

It works for me. Hope it works for you.

like image 171
smdsgn Avatar answered Nov 02 '22 22:11

smdsgn