14
votes

I am using validate.jquery.js : works fine. But when I'm adding chosen.js , validation on the select dropdowns doesn't work anymore.

Here is the JS I'm using http://pastebin.com/S9AaxdEN

And here is my select form :

<select name="category" id="category" placeholder="" class="{validate:{required:true}}">
<option value=""><?php echo lang('category_choice'); ?></option>
<option value="vtt">VTT</option>
<option value="autre">Autre type de v&eacute;lo</option>
</select>

Don't know why chosen.js disable the validation, any idea ?

4
A possible answer I found, that can help if you have the same problem : Make sure the validator doesn't ignore :hidden elements. The original `` is hidden when chosen applies its drop-down to the DOM.Phmarc
I think stackoverflow prefers if you post the solution you found on your own as an answer and than accept it so the question shows up as answered and accepted in the search page.Peter Lyons
I tried to, but as I am a new user, I'm not trusted yet and can't do it unfortunately :(Phmarc

4 Answers

18
votes

You can fix this by adding the class "chzn-done" that does not take the property "ignore" to "validate.settings":

var settings = $.data($('#myform')[0], 'validator').settings;
settings.ignore += ':not(.chzn-done)';

example

HTML:

<form method="post" id="form1" action="">
    <fieldset>
        <legend>Login Form</legend>
        <div>
            <label>datos</label>
            <select name="data-select" title="data-select is required" class="chzn-select {required:true}" style="width:150px;">
                <option></option>
                <option value="1">uno</option>
                <option value="2">dos</option>
            </select>
        </div>
        <div>
            <label for="phone">Phone</label>
            <input id="phone" name="phone" class="some styles {required:true,number:true, rangelength:[2,8]}" />
        </div>
        <div>
            <label for="email">Email</label>
            <input id="email" name="email" class="{required:true,email:true}">
        </div>

        <div class="error"></div>
        <div>
            <input type="submit" value="enviar datos"/>
        </div>
    </fieldset>
</form>

JS:

$(function() {

    var $form = $("#form1");

    $(".chzn-select").chosen({no_results_text: "No results matched"});
    $form.validate({
        errorLabelContainer: $("#form1 div.error"),
        wrapper: 'div',
    });

    var settings = $.data($form[0], 'validator').settings;
    settings.ignore += ':not(.chzn-done)';

    $('form').each(function(i, el){

        var settings = $.data(this, 'validator').settings;
        settings.ignore += ':not(.chzn-done)';

    });

});
6
votes

I would just add that for the error placement, it will append the element right next to hidden, therefore you may want to change the placement by using the following code on your validate function as an option argument

errorPlacement: function(error,element) {
        if (element.is(":hidden")) {
            //console.log(element.next().parent());
            element.next().parent().append(error);
        }
        else {
            error.insertAfter(element);
        }

    }
4
votes

This will solve not only the issue of not being able to see the validation but it will also apply the standard "input-validation-error" class to the chosen.js styled select.

There are two cases where it needs to be applied both when the form is submitted and on a select change. See the three sections of code below.

  1. The first sets the form validation to validate hidden elements.
  2. The second checks the chosen validation on submit.
  3. The third checks the chosen validation on a change.

Sets up the form validation to show hidden:

var validator = $("#FormID").data('validator');
validator.settings.ignore = ":hidden:not(select)";

Checks on form submit:

$('#FormID').on('submit', function () {
    var ChosenDropDowns = $('.chzn-done');
    ChosenDropDowns.each(function (index) {
        var ID = $(this).attr("id");
        if (!$(this).valid()) 
        {
            $("#" + ID + "_chzn a").addClass("input-validation-error");
        }
        else 
        {
            $("#" + ID + "_chzn a").removeClass("input-validation-error");
        }
    });
});

Checks on select change:

$(".chzn-select").chosen().change(function () {
    var ID = $(this).attr("id");
    if (!$(this).valid()) {
        $("#" + ID + "_chzn a").addClass("input-validation-error");
    }
    else {
        $("#" + ID + "_chzn a").removeClass("input-validation-error");
    }
});
1
votes

There is also an issue of validating the chosen select menus after the form has been submitted. If you have a validation error on the menu then change the menu to be valid the validation error will not go away. The form can still be submitted, but it's not obvious given that there is a validation error showing.

Here's one example to fix it using the invalidHandler and valid().

// We'll use this flag so we don't have to validate fields before
// the form has been submitted.
var validatingForm = false;

// This line before validate() is called allows
// chosen menus to be validated
$.validator.setDefaults({ ignore: ":hidden:not(select)" });

$("#yourForm").validate({
    invalidHandler: function() {
        // Now we can validate the fields onChange
        validateForm = true;
    },
        rules: {
            // Probably your validation rules here
        }
    });

//  Now set an onChange event for the chosen menu
$("yourChosenMenu").change(function(){

    // Check that we've tried to submit the form
    if(validateForm) {
        // We tried to submit the form, re-validate on change
        $("yourChosenMenu").valid();
    }
});