Materialize: Jquery Validate does not work with Selects

Created on 31 Jul 2016  路  10Comments  路  Source: Dogfalo/materialize

JQuery Validate (https://jqueryvalidation.org/) does not work with the Selects. It only works if browser-default class is selected. I assume this is because Materialize does some fancy stuff that breaks it.

thirdparty

Most helpful comment

Another workaround is

$.validator.setDefaults({
        ignore: []
  });

This enables validation on hidden fields as well, which enables on our select fields.

But in either of the cases, the error field do not fade away when an option is selected. :(

All 10 comments

I love jquery validation, i love materializecss but this error is so painful for my projects created with materializecss. Please fix this problem.

I'm having the same problem.
We trusted it and using, but there are problems.
Please, can you fix bugs?

Bugs : Select box don't send data.

Just in case anyone else has this issue, I have spent a while looking into this today and have come up with the following solution which seems to be working for me so far. I have added a class to my css that does the following:

select {
    visibility: hidden;
    display: block;
    position: absolute;
}

The issue is being caused by the original select element being hidden by materialize (which causes jquery validation to ignore the element). Setting the display to block is the actual bit that fixed the issue and allowed the select to be validated again. The other 2 rules are there as a way for me to make the associated messages appear inline with the other fields etc.

Someone can probably suggest a better solution than this but it suits what I need for now, would be great if someone could get round to sorting this in the framework itself.

Another workaround is

$.validator.setDefaults({
        ignore: []
  });

This enables validation on hidden fields as well, which enables on our select fields.

But in either of the cases, the error field do not fade away when an option is selected. :(

same problem, but nothing worked for me on firefox or chrome

I do something like this on configuration jqueryValidate to resolve validates class and jqueryValidate with unobtrusive:

VALIDATOR CONFIGURATION:

$(function () {

$.validator.setDefaults({
    onfocusout: function () { return true; },
    onfocusin: function (element) {

        this.lastActive = element;
        if (this.settings.focusCleanup) {
            if (this.settings.unhighlight) {
                this.settings.unhighlight.call(this, element, this.settings.errorClass, this.settings.validClass);
            }

            if ($(element).hasClass('select-dropdown')) {

                $("span[data-valmsg-for='" + $(element).siblings('select').attr("name") + "']").empty();

            }
            else {
                $("span[data-valmsg-for='" + this.idOrName(element) + "']").empty();
            }
        }
    },
    focusCleanup: true,
    highlight: function (element) {

        var errorClass = 'input-validation-error';
        var validClass = 'valid';

        if (element.type === "radio") {
            this.findByName(element.name).addClass(errorClass).removeClass(validClass);
        }
        else if (element.type === "select-one") {
            $(element).siblings('input').addClass(errorClass).removeClass(validClass);
        }
        else if (element.type === "textarea") {
            $(element).addClass(errorClass).removeClass(validClass);
            $(element).siblings('span').addClass("span-error-text-area");
        }
        else {
            $(element).addClass(errorClass).removeClass(validClass);
        }

        //#region Rolagem para input-validation-error

        var inputErro = $('.input-validation-error').first().parent();

        if ($(element).parent()[0] == inputErro[0]) {

            var conteudoBody = $("div:cssContains('overflow=auto')").has(element).last();

            conteudoBody.animate({

                scrollTop: conteudoBody.scrollTop() + inputErro.position().top - inputErro.height()

            });

        }
        //#endregion
    },
    unhighlight: function (element) {

        var errorClass = 'input-validation-error';
        var validClass = 'valid';
        if (element.type === "radio") {
            this.findByName(element.name).removeClass(errorClass);
        }
        else if (element.type === "select-one") {
            $(element).siblings('input').removeClass(errorClass);
        }
        else if (element.type === "textarea") {
            $(element).removeClass(errorClass);
            $(element).siblings('span').removeClass("span-error-text-area");
        }
        else {
            $(element).removeClass(errorClass);
        }


    },
    ignore: ":hiddenSelect,:not(select):hidden"
});

});

SELECTORS IN JQUERY:
$(function () {

jQuery.extend(jQuery.expr[':'], {
    cssContains: function (a, i, m) {

        var attr = m[3].split('=');
        var value = $(a).css(attr[0]);

        if (attr[1] == value)
            return true;

        return false;


    }
});

jQuery.extend(jQuery.expr[':'], {
    hiddenSelect: function (a, i, m) {


        if ($(a).is("select")) {
            return $(a).parent().is(":hidden");
        }

        return false;
    }
});

});

Solution cited by @stap123 doesn't work for me, but change visibility to opacity does.

select[required] {
  opacity: 0;
  display: block;
  position: absolute;
  height: 0;
  border: none;
  margin-top: -50px;
}

captura de tela 2017-02-17 as 21 14 13

@mirzavu Your solution Would be awesome when you can just add the below line with your code
$('select').change(function(){ $('select').valid(); })

So these lines automatically fade away the error messages.

So the full code to overcome this problem is as follows
$.validator.setDefaults({ ignore: [] }); $('select').change(function(){ $('select').valid(); })

That's it and there we go! Good luck guys... Happy coding!

@svinesh3691 Thx for your solution.
One more tricky problem is that, even the error message show up when selecting back the default, the select-field hightlight does not turn from green to red.
how can I solve it?

This works for me with Jquery Validation Plugin v1.17.0 and Materialize v1.0.0

 $.validator.setDefaults({
   ignore: []
});

$(form).validate({
      onfocusout: false,
      onkeyup: false,
      rules: {
       select: "required"
      },
      messages: {
        select: "This field is required."
      },
      errorClass: "form-error",
      errorElement: "div",
      errorPlacement: function(error, element) {
        if(element[0].nodeName.toLowerCase() == "select" ){
          element.siblings( "input" ).addClass("invalid");
          error.insertAfter(element.siblings( "input" )).slideDown(400).fadeIn("slow");
        }else{
          element.addClass("invalid");
          error.insertAfter(element.next()).slideDown(400).fadeIn("slow");
        } 
      }
    });

CSS:

 div.form-error {
    display: none;
    color: #ef4040;
    font-weight: bold;
    margin-bottom: 28px;
    -webkit-transform: translatez(0);
    -moz-transform: translatez(0);
    -ms-transform: translatez(0);
    -o-transform: translatez(0);
    transform: translatez(0);
  }

Also, i overwrite a 'hideThese' function of jquery.validate.js fo animation

hideThese: function( errors ) {
    //this.addWrapper( errors ).hide();

   errors.not( this.containers ).animate({ height: 0, opacity:0 },function(){ $(this).siblings( "input" ).removeClass("invalid"); $(this).text( "" ).removeAttr("style"); });

},

I hope it works !

EDIT:
you need to put required attribute in your select tag

<select name="select" required>
<option value="">Select.. </option>
...
</select>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Robouste picture Robouste  路  3Comments

heshamelmasry77 picture heshamelmasry77  路  3Comments

MickaelH974 picture MickaelH974  路  3Comments

hartwork picture hartwork  路  3Comments

SoproniOli713 picture SoproniOli713  路  3Comments