0

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

Sparky
  • 98,165
  • 25
  • 199
  • 285
jagamot
  • 5,348
  • 18
  • 59
  • 96
  • Please edit the OP to include the relevant HTML. Please do not rely on the jsFiddle link to stay live. Thanks. – Sparky Feb 27 '16 at 16:58

1 Answers1

3

... 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/

Sparky
  • 98,165
  • 25
  • 199
  • 285
  • #Sparky - Thanks for the hint! I already have this default value in the drop down in my actual application. When I posted, I had to tweak the actual example so i don't violate any company policies. Anyways, my jqueryValidation doesn't trigger validation error on the select dropdown when both id and name attributes are set. If I remove the id attribute, validation is being triggered but my dropdown doesn't render as a bootstrap dropdown. And if I have both attributes the jqueryValidation is not being triggered. Any advice? – jagamot Feb 29 '16 at 04:44
  • @jagamot, you have to post an example that fully replicates the issue. Otherwise, we're just guessing. – Sparky Feb 29 '16 at 15:07
  • @sparky- I was trying to further debug it and here is what is happening. In jqueryValidation.js under the elements function() [v 1.15 line 620] the framework filters out all the hidden elements - return $( this.currentForm) .find( "input, select, textarea, [contenteditable]" ) .not( ":submit, :reset, :image, :disabled" ) .not( this.settings.ignore ) .filter( function() { ... } 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 – jagamot Feb 29 '16 at 15:47
  • Looks like from version 1.9, hidden fields are ignored which is causing what I was seeing. Setting ignore to [] fixed my issue - http://stackoverflow.com/questions/8466643/jquery-validate-enable-validation-for-hidden-fields – jagamot Feb 29 '16 at 15:51
  • 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. – jagamot Feb 29 '16 at 16:12
  • @jagamot, but it IS displayed consistently. It's inserted *after* the hidden select. It's not the plugin's fault you've hidden and replaced the original element. – Sparky Feb 29 '16 at 20:24
  • I have not hidden it, bootstrap-multiselect plugin is doing it! – jagamot Feb 29 '16 at 21:06
  • @jagamot, obviously! The point is that the inconsistency is not by the plugin. – Sparky Feb 29 '16 at 21:11
  • Yes, it is the bootstrap-multiselect plugin, and not the jqueryValidator. – jagamot Mar 02 '16 at 13:58
  • @jagamot, your original OP only stated, *"validation is not triggered"*. The code in your OP did not show the root problem since a validation message was triggered [as soon as I only added the `value=""` attribute to the first `option` element](http://jsfiddle.net/vg6oLvxo/83/). However, I have edited my answer to fully address your latest comments. – Sparky Mar 02 '16 at 15:27