jQuery Validate & Nice Select consistent at all?

2019-08-15 00:46发布

问题:

Is Nice Select working with jQuery validate ? Because I get a strange bug, I'll try to explain it

  • Without yet having submitted the form, I'm able to select the the value from nice select plugin and it update correctly the (default select dropdown) value and I can submit the form without problem

  • Now if I refresh the page then I submit the form, the jQuery error validate appends as intended because I did not selected some value, so I select some value from (nice select value) and now it doesn't update the (default select) value so I can't submit the form

I thinks that when validate plug-in is called nice select is not dynamically updated, or maybe I miss some thing

FIDDLE

html :

<form id="MyForm">
   <select id="MySelect" name="select">
     <option value="">Select a value</option>
     <option value="1">1</option>
     <option value="2">2</option>
     <option value="3">3</option>
     <option value="4">4</option>
   </select>
   <button id="MyButton" type="submit">Submit</button>
</form>

jQuery :

$(document).ready(function() { 
    // Form Validate 
    $('#MyForm').validate({ 
        ignore: [],
        rules: {
            select: {
                selectcheck: true
            }
        }
    });

    jQuery.validator.addMethod('selectcheck', function (value) {
        return (value != '');
    }, "Value required");

    // Activate NiceSelect
    $('#MySelect').niceSelect(); 
});

Any help would be appreciated

Thanks in advance

回答1:

The jQuery Validate plugin automatically inserts the validation message after the select element. However in your case, the select element is hidden when the Nice Select div is dynamically created; the Validate plugin can no longer see or toggle this label.

Use the errorPlacement function to place the validation message after the Nice Select div element. My custom function is generic and applies to all hidden select elements in the form.

errorPlacement: function(error, element) {
    if (element.is('select:hidden')) {
        error.insertAfter(element.next('.nice-select'));
    } else {
        error.insertAfter(element);
    }        
}

However, this answer is not yet complete. The jQuery Validate plugin normally triggers validation based on the user interacting with the select element. Since your select element is hidden and the user is not directly interacting with it, validation is not triggered whenever the Nice Select element is changed.

Use a custom change handler function to ensure that the validation message is updated whenever the Nice Select element is changed...

$('#MySelect').on('change', function() {
    $(this).valid();
});

Working DEMO: https://jsfiddle.net/9yvz4ztv/


BTW: You do not need to write a custom rule to ensure a select element contains a value. Simply use the required rule.

rules: {
    select: {
        required: true
    }
}


回答2:

It's because of error label placement.
The label is placed directly after the <select> element, but the plugin uses this code to trigger changes of the <select>:

// .prev() in this case is the <label class="error">, not "select" ...
n.prev("select").val(s.data("value")).trigger("change")

You can change the placement of label, using errorPlacement option:

$('#MyForm').validate({ 
  ignore: [],
  rules: {
    select: {
      selectcheck: true
    }
  },
  errorPlacement: function(error, element) {
    if (element.attr("name") == "select") {
      // place the label after the .nice-select DIV, not <select>:
      error.insertAfter(".nice-select");
    } else {
      error.insertAfter(element);
    }
  }
});

JSFiddle demo