79 votes

Comment puis-je utiliser la validation jQuery avec le plugin "chosen" ?

J'ai quelques <select> les entrées en utilisant le plugin choisi que je veux valider comme "obligatoire" du côté client. Puisque "chosen" masque l'élément de sélection réel et crée un widget avec des divs et des spans, la validation native HTML5 ne semble pas fonctionner correctement. Le formulaire ne se soumet pas (ce qui est bien), mais le message d'erreur n'est pas affiché, de sorte que l'utilisateur n'a aucune idée de ce qui ne va pas (ce qui n'est pas bien).

Je me suis tourné vers le plugin de validation jQuery (que j'avais prévu d'utiliser de toute façon) mais je n'ai pas eu de chance jusqu'à présent. Voici mon cas de test :

<form>
    <label>Name: <input name="test1" required></label>
    <label>Favorite Color:
        <select name="test2" required>
            <option value=""></option>
            <option value="red">Red</option>
            <option value="blue">Blue</option>
            <option value="green">Green</option>
        </select>
    </label>
    <input type="submit">
</form>

$(document).ready(function(){
    $('select').chosen();
    $('form').validate();
});

C'est laisser le select avec une valeur vide, sans valider ni afficher le message d'erreur. Lorsque je commente l'élément chosen() la ligne, cela fonctionne bien.

Comment puis-je valider chosen() avec le plugin de validation jQuery, et afficher le message d'erreur pour les entrées invalides ?

1 votes

Vérifiez ce plugin dehors. Ce n'est pas vraiment une solution mais vous pouvez essayer.

0 votes

@elclanrs : Merci, mais j'aimerais m'en tenir à la bibliothèque de validation jQuery de facto pour le moment, surtout à ce stade du projet (j'essaie de conclure). Peut-être dans un futur projet.

0 votes

Ce post a résolu mon problème : stackoverflow.com/questions/10387553/ Simple et élégant.

124voto

anupalusoft Points 435

JQuery validate ignore l'élément caché, et puisque le plugin Chosen ajoute visibility:hidden à la sélection, essayez :

$.validator.setDefaults({ ignore: ":hidden:not(select)" }) //for all select

OU

$.validator.setDefaults({ ignore: ":hidden:not(.chosen-select)" }) //for all select having class .chosen-select

Ajoutez cette ligne juste avant validate() fonction. Elle fonctionne bien pour moi.

1 votes

Cela a été tout à fait suffisant dans mon cas. Merci.

1 votes

Où avez-vous mis cette ligne ? Elle ne semble pas fonctionner pour moi :/

1 votes

Juste au-dessus de la fonction JQuery validate().

19voto

Mike Robinson Points 12273

La validation jQuery ne va pas détecter les éléments qui sont cachés, mais vous pouvez le forcer à valider des éléments individuels. C'est un peu compliqué, mais ce qui suit fonctionnera :

$('form').on('submit', function(e) {
    if(!$('[name="test2"]').valid()) {
        e.preventDefault();
    }
});  

Pour ne sélectionner que les éléments "choisis", vous pouvez utiliser $('.chzn-done')

2 votes

Il semble que le e.preventDefault() n'est même pas nécessaire, il suffit d'appeler $("element").valid() . J'ai utilisé ce code et cela semble fonctionner parfaitement : $('form').on('submit', function() {$('.chzn-done').valid();}); . Merci pour l'information.

4 votes

.chzn-done n'est plus ajouté aux éléments "choisis" à partir de Chosen 1.0.

5voto

Acang Terpal Points 1

Dans le mien.

mon formulaire a la classe "validate". et chaque élément de saisie a la classe "required". code html :

<form id="ProdukProdukTambahForm" class="validate form-horizontal" accept-charset="utf-8" method="post" enctype="multipart/form-data" action="/produk-review/produk/produkTambah" novalidate="novalidate">
     <div class="control-group">
        <label class="control-label" for="sku">SKU</label>
        <div class="controls">
           <input id="sku" class="required span6" type="text" name="sku">
        </div>
     </div>
     <div class="control-group">
        <label for="supplier" class="control-label">Supplier</label>
        <div class="controls">
            <select name="supplier" id="supplier" class='cho span6 {required:true} '>                                           
                <option value=''>-- PILIH --</option>
                <?php
                foreach ($result as $res)
                    {
                    echo '<option value="'.$res['tbl_suppliers']['kode_supplier'].'">'.$res['tbl_suppliers']['nama_supplier'].'</option>';
                    }
                ?>
            </select>
         </div>
      </div>
</form>

et code javascript pour le choix avec validation jquery

$(document).ready(function() {
    // - validation
    if($('.validate').length > 0){
        $('.validate').validate({
            errorPlacement:function(error, element){
                    element.parents('.controls').append(error);
            },
            highlight: function(label) {
                $(label).closest('.control-group').removeClass('error success').addClass('error');
            },
            success: function(label) {
                label.addClass('valid').closest('.control-group').removeClass('error success').addClass('success');
            },
            //validate choosen select (select with search)
            ignore: ":hidden:not(select)"
        });
    }
    // - chosen, add the text if no result matched
    if($('.cho').length > 0){
        $(".cho").chosen({no_results_text: "No results matched"});
    }
});

note : si la valeur de l'entrée est nulle, l'erreur de classe sera ajoutée au parent 'div'.

3voto

vikrant singh Points 1512

//Vous pouvez résoudre ce problème en utilisant un autre moyen de masquer l'élément choisi. eg....

$(document).ready(function() {
 $.validator.addMethod(     //adding a method to validate select box//
            "chosen",
            function(value, element) {
                return (value == null ? false : (value.length == 0 ? false : true))
            },
            "please select an option"//custom message
            );

    $("form").validate({
        rules: {
            test2: {
                chosen: true
            }
        }
    });
    $("[name='test2']").css("position", "absolute").css("z-index",   "-9999").chosen().show();

    //validation.....
    $("form").submit(function()
    {
        if ($(this).valid())
        {alert("valid");
    //some code here 
        }
        return false;

    });
});

0 votes

This answer only works if you don't call .chosen(). Il semble qu'il y ait un bug (une fonctionnalité ?) dans la bibliothèque chosen qui fait que lorsque vous activez un <select>, il le cache - il n'interagit donc plus avec les règles de validation.

0voto

noypiscripter Points 569

Je pense que c'est la meilleure solution.

//trigger validation onchange
$('select').on('change', function() {
    $(this).valid();
});

$('form').validate({
    ignore: ':hidden', //still ignore Chosen selects
    submitHandler: function(form) { //all the fields except Chosen selects have already passed validation, so we manually validate the Chosen selects here            
        var $selects = $(form).find('select'),
            valid = true;
        if ($selects.length) {
            //validate selects
            $selects.each(function() {
                if (!$(this).valid()) {
                    valid = false;
                }
            });
        }
        //only submit the form if all fields have passed validation
        if (valid) {
            form.submit();
        }
    },
    invalidHandler: function(event, validator) { //one or more fields have failed validation, but the Chosen selects have not been validated yet
        var $selects = $(this).find('select');     
        if ($selects.length) {
            validator.showErrors(); //when manually validating elements, all the errors in the non-select fields disappear for some reason

            //validate selects
            $selects.each(function(index){
                validator.element(this);
            })
         }
    },
    //other options...
});

Note : Vous devrez également modifier le errorPlacement pour gérer l'affichage de l'erreur. Si votre message d'erreur se trouve à côté du champ, vous devrez utiliser la fonction .siblings('.errorMessageClassHere') (ou d'autres moyens selon le DOM) au lieu de .next('.errorMessageClassHere') .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X