Search code examples
jquerytwitter-bootstrapjquery-validatebootstrap-multiselect

jQuery Validate not working for Multi-select dropdown


I am using Bootstrap with Bootstrap Multi-select plugin along with jQueryValidation for validating the fields.

Unfortunately, when I render the dropdown as a single select, validation is not triggered.

Any Ideas?

Javascript

        $( "#signupForm" ).validate( {
            rules: {
                firstname: "required",
                lastname: "required",
      food: "required",
                username: {
                    required: true,
                    minlength: 2
                },
                password: {
                    required: true,
                    minlength: 5
                },
                confirm_password: {
                    required: true,
                    minlength: 5,
                    equalTo: "#password"
                },
                email: {
                    required: true,
                    email: true
                },
                agree: "required"
            },
            messages: {
                firstname: "Please enter your firstname",
                lastname: "Please enter your lastname",
      food: "Fruit is required to enter",
                username: {
                    required: "Please enter a username",
                    minlength: "Your username must consist of at least 2 characters"
                },
                password: {
                    required: "Please provide a password",
                    minlength: "Your password must be at least 5 characters long"
                },
                confirm_password: {
                    required: "Please provide a password",
                    minlength: "Your password must be at least 5 characters long",
                    equalTo: "Please enter the same password as above"
                },
                email: "Please enter a valid email address",
                agree: "Please accept our policy"
            },
            errorElement: "em",
            errorPlacement: function ( error, element ) {
                // Add the `help-block` class to the error element
                error.addClass( "help-block" );

                if ( element.prop( "type" ) === "checkbox" ) {
                    error.insertAfter( element.parent( "label" ) );
                } else {
                    error.insertAfter( element );
                }
            },
            highlight: function ( element, errorClass, validClass ) {
                $( element ).parents( ".col-sm-5" ).addClass( "has-error" ).removeClass( "has-success" );
            },
            unhighlight: function (element, errorClass, validClass) {
                $( element ).parents( ".col-sm-5" ).addClass( "has-success" ).removeClass( "has-error" );
            }
        } );
$('.multiselect').multiselect();

JSFIDDLE


Solution

  • ... when I render the dropdown as a single select, validation is not triggered.

    Your select element is not triggering validating because there is no validation error. Since you load the page with "cheese" already selected, the required rule is satisfied; there is no error, so there is no reason to see an error message.

    <select name="food" class="multiselect">
        <option value="cheese"> Cheese </option>
        <option value="tomatoes"> Tomatoes </option>
        <option value="mozarella"> Mozzarella </option>
        <option value="mushrooms"> Mushrooms </option>
        <option value="pepperoni"> Pepperoni </option>
        <option value="onions"> Onions </option>
    </select>
    

    Otherwise, add an <option> at the top that contains an empty value and you'll see the required rule in action.

    <select name="food" class="multiselect">
        <option value="">please select...</option>
        <option value="cheese"> Cheese </option>
        ....
    

    DEMO: http://jsfiddle.net/vg6oLvxo/83/


    EDIT:

    OP's comment on this answer:

    This is essentially causing my multiselect dropdown to be removed because when bootstrap-multiselect plugin generates the multi-select dropdown it add display:none to the main select tag

    Whenever you use a plugin that manipulates the DOM to hide the default form elements, you must use the ignore option of jQuery Validate to ensure that the hidden form elements are still validated. ignore: [] ensures that nothing is ignored.

    $("#signupForm").validate({
        ignore: [],  // ignore nothing, validate everything
        rules: { ....
    

    But it is little inconsistent in the sense the validation message for dropdown is being displayed before the dropdown where as for other fields it is displayed after the field.

    The jQuery Validate plugin is inserting the message after the form element. Since the Bootstrap Multiselect plugin has hidden the original element and created a new one, the message is inserted after the hidden element, but appears before the new element. This can be fixed by using a conditional within the errorPlacement option.

    errorPlacement: function(error, element) {
        if (element.hasClass('multiselect')) {
            // custom placement for hidden select
            error.insertAfter(element.next('.btn-group'))
        } else {
            // message placement for everything else
            error.insertAfter(element);
        }
    }
    

    DEMO 2: http://jsfiddle.net/vg6oLvxo/85/