19

I design my HTML selectbox using bootstrap select plugin. Now, i add jQueryvalidation Plugin for validate my form But, Validation form not work with bootstrap select plugin.

DEMO HERE

HTML:

<form id="myform">
    <select name="year" class="selectpicker">
        <option value="">Year</option>
        <option value="1">1955</option>
        <option value="2">1956</option>
    </select>
    <br/>
    <input type="submit" />
</form>

JS:

$(document).ready(function () {
$('select').selectpicker();
    $('#myform').validate({ // initialize the plugin
        rules: {
            year: {
                required: true,
            }
        },
        submitHandler: function (form) { // for demo
            alert('valid form submitted'); // for demo
            return false; // for demo
        }
    });

});

NOTE: For check this conflict, remove Line 2 from JS, jQuery Validation Worked.

EDIT: adeneo Fix Problem Using ignore[] method : FIDDLE

$('#myform').validate({ // initialize the plugin
    ignore: [],
    rules: {
        year: {
            required: true
        }
    },
    errorPlacement: function(error, element) {
        if (element.attr("name") == "year") {
          error.insertAfter(".bootstrap-select");
        } else {
          error.insertAfter(element);
        }
    },
    submitHandler: function (form) { // for demo
        alert('valid form submitted'); // for demo
        return false; // for demo
    }
});

Now This Worked but I have New Problem: In normal Validation after select fields, error message This field is required auto Hide( OR with add any css, show success message) but Now, error message is show after fix required field. in act: when we choose years, error message not hide.

How do fix This?

Community
  • 1
  • 1
ಠ_ಠ
  • 1,235
  • 2
  • 17
  • 29
  • This might help: http://stackoverflow.com/questions/17893433/twitter-bootstrap-selectpicker-onchange-function-not-being-called – matpol Jan 09 '14 at 11:47

3 Answers3

19

The select plugin hides the original select and creates a new one with an unordered list that updates the hidden selects value, but hidden elements are not validated by default by the validation plugin, you have to use the ignore rule and turn on validation for hidden elements

$('#myform').data("validator").settings.ignore = "";

FIDDLE

or

$('#myform').validate({ // initialize the plugin
    ignore: [],
    rules: {
        year: {
            required: true
        }
    },
    submitHandler: function (form) { // for demo
        alert('valid form submitted'); // for demo
        return false; // for demo
    }
});

FIDDLE

The Bootstrap select plugin creates a new dropdown from an unordered list, and the original select is hidden and it's value is updated when the user interacts with the unordered list.

This has the disadvantange of also moving the error message, as the original, now hidden select is the element being validated, and the new visible dropdown made up of an unordered list is inserted by Bootstrap below the original select in the DOM, the error message is inserted after the original select, but before the unordered list, so it appears above the custom dropdown, not below it like it would if the original select was used.

To fix it you can move the error message for any given element rather easily

$('#myform').validate({ // initialize the plugin
    ignore: [],
    rules: {
        year: {
            required: true
        }
    },
    errorPlacement: function(error, element) {
        if (element.attr("name") == "year") {
          error.insertAfter(".bootstrap-select");
        } else {
          error.insertAfter(element);
        }
    },
    submitHandler: function (form) { // for demo
        alert('valid form submitted'); // for demo
        return false; // for demo
    }
});

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • This work perfectly!Thanks. Small Problem: why error message `This field is required.` show in top of input form? – ಠ_ಠ Jan 09 '14 at 12:17
  • Because the new select based on an unordered list is placed below the original select element in the DOM, and then the validator inserts the error message right after the original select, which is what it validates, and it ends up right before the unordered list you now see as the custom select, – adeneo Jan 09 '14 at 12:22
  • 2
    Sure, In normal Validation after select fields, error message `This field is required` auto Hide( OR with add any css, show seccess message) but Now, error message is show after fix required field. – ಠ_ಠ Jan 09 '14 at 12:28
  • There is still a problem with validation. It should be validated on change of bootstrap select as default select input, however it does not. Check this out as well... http://www.ivanthevariable.com/using-bootstrap-select-selectpicker-jquery-validate/ – dvlden Sep 14 '14 at 19:51
3

I had a similar issue so here's how I kind of extended @adeneo's answer together with lessons learnt from (the post here).

Note: For those who bump into this post, please read @adeneo's answer and (the post here) to understand the scope of this solution.

The resulting code that very well functions flawlessly for me looks as follows:

jQuery / javascript:

$(document).ready(function() {
    $.validator.setDefaults({
        /*OBSERVATION (1): note the options used for "ignore"*/
        ignore: ':not(select:hidden, input:visible, textarea:visible)',

        /*...other options omitted to focus on the OP...*/

        errorPlacement: function (error, element) {
            /*OBSERVATION (2): note how selection is on the class "selectpicker"*/
            if (element.hasClass('selectpicker')) {
                error.insertAfter('.bootstrap-select');
            } else {
                error.insertAfter(element);
            }
            /*Add other (if...else...) conditions depending on your
            * validation styling requirements*/
        }
    });

    $('#myform').validate({ 
        rules: {
            'year': {
                required: true
            }
        },
        messages: {
            'year': {
                required: 'Please select a year from the dropdown'
            }
        }
    });
});

HTML:

<form id="myform">
    <select name="year" class="selectpicker">
        <option value="">Year</option>
        <option value="1">1955</option>
        <option value="2">1956</option>
    </select><br/>
    <input type="submit" />
</form>

Explanation:

OBSERVATION (1): ignore: ':not(select:hidden, input:visible, textarea:visible)' simply means to ignore validation for all elements that's not a hidden <select>, that's not a visible <input> and that's not a visible <textarea>.

In simpler English, it just says to validate hidden <select>, ignore hidden <input> and ignore hidden <textarea> which is what we usually want in many cases. This I think is a better way to target what validation should be ignored or not.

Based on @Alvin Lee's answer here, setting the ignore options on the form element as follows was ok, but had its caveats;

$('#myform').validate().settings.ignore = 
    ':not(select:hidden, input:visible, textarea:visible)';

The Problem: The bootstrap select element got validated but showed the default message This field is required on every other input element instead of overriding it with all the custom validation messages that were previously configured.

The fix: move the ignore setting into $.validator.setDefaults({...}) block... Voila! ! !

OBSERVATION (2):

Instead of doing if (element.attr("name") == "year") {...} like @adeneo pointed, I rather decided to select on class='selectpicker'... then in the javascript, check if the element had this class by doing if (element.hasClass('selectpicker')) {...}. This just ensures that this rule can be applied to all bootstrap-select elements as long as they're decorated with the class selectpicker.

Hope this is clear enough and helpful to somebody who has similar issues!

Community
  • 1
  • 1
SourceVisor
  • 1,868
  • 1
  • 27
  • 43
1

If you use 'selectpicker' class to initialize bootstrap-select widget, I recommend to partially solve the issue via changing default ignore settings for jquery validate:

$.validator.setDefaults({ ignore: ':hidden:not(.selectpicker)' });

before you validate your form. This is a bit better approach, and you also need to move error messages as adeneo supposed. And still it will not have a similar validation behavior as select would have. The problem arise when the parent container is hidden. In case you do not use bootstrap-select your select will not validate when container is hidden, but when you use it still validates.

Community
  • 1
  • 1
Vladislav Kostenko
  • 1,155
  • 11
  • 18