web-dev-qa-db-fra.com

Comment utiliser la validation jQuery avec le plugin "choisi"?

J'ai quelques entrées <select> utilisant le plugin choisi que je veux valider en tant que "requis" du côté client. Dans la mesure où "choisi" masque l'élément select réel et crée un widget avec des divs et des span, la validation native HTML5 ne semble pas fonctionner correctement. Le formulaire ne sera pas soumis (ce qui est bon), mais le message d'erreur ne s'affiche pas et l'utilisateur n'a donc 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 je prévoyais d'utiliser de toute façon, de toute façon) mais je n'ai pas eu de chance jusqu'à présent. Voici mon test case :

<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();
});

Ceci laisse passer la select avec une valeur vide, sans valider ni afficher le message d'erreur. Lorsque je commente la ligne chosen(), cela fonctionne bien.

Comment valider les entrées chosen() avec le plug-in de validation jQuery et afficher le message d'erreur pour les entrées non valides?

70
Wesley Murch

jQuery validate ignore l'élément caché et, puisque le plug-in Chosen ajoute l'attribut visibility:hidden à la sélection, essayez:

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

OR

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

Ajoutez cette ligne juste avant la fonction validate(). Ça fonctionne bien pour moi.

117
Anupal

la validation jQuery ne détecte pas les éléments masqués, mais vous pouvez la forcer à valider des éléments individuels. Un peu de bidouille, mais ce qui suit fonctionnera: 

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

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

18
Mike Robinson

dans le mien.

ma fiche a la classe 'validate' et chaque élément d'entrée a la classe 'obligatoire' 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 choisi 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 d'entrée est null, l'erreur de classe sera ajoutée au parent 'div'

4
Acang Terpal

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

$(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;

    });
});
3
vikrant singh

cette règle CSS simple fonctionne sur l'implémentation de joomla 3

Choisi ajoute la classe non valide à l'entrée de sélection masquée, utilisez-la pour cibler la boîte de sélection choisie.

.invalid, .invalid + div.chzn-container a {
    border-color: red !important;
}
1
philip

Je devais placer $.validator.setDefaults({ ignore: ":hidden:not(.chosen-select)" })
en dehors de $(document).ready(function() afin de travailler avec selected.js.

https://stackoverflow.com/a/10063394/4063622

1
Tobi G.

Vous pourriez également rencontrer des problèmes si ce message d'erreur est affiché avant la liste déroulante choisie. J'ai trouvé la solution pour résoudre ce problème et coller mon code ici pour le partager avec vous.

HTML:

<label class="col-sm-3">Select sponsor level *</label>
<asp:DropDownList ID="ddlSponsorLevel" runat="server" CssClass="col-sm-4 required" ClientIDmode="Static" />
<label class="error" id="ddlSponsorLevel-error" for="ddlSponsorLevel"></label>

Javascript: 

if (!$('#ddlSponsorLevel').valid()) {
       $('#ddlSponsorLevel-error').text("You must choose a sponsor level");
            return false;
}

Jquery Validation a en fait ajouté un élément html avec une étiquette cachée. Nous pouvons redéfinir cet élément avec le même ID sur un emplacement différent pour écraser l'emplacement d'origine.

1
Gavin Tian

J'ai passé environ une journée à travailler là-dessus et je n'ai pas eu de chance du tout! Ensuite, j'ai regardé le code source que Vtiger utilisait et j'ai trouvé de l'or! Même s'ils utilisaient des versions plus anciennes, ils avaient la clé! vous devez utiliser 

data-validation-engine="validate[required]"

Si vous ne le faites pas et que vous l'avez où les classes sont passées à travers la classe pour que la sélection soit appliquée à l'élu et qu'il pense que votre élue n'est jamais mise à jour. Si vous ne transmettez pas la classe à la personne choisie, cela devrait poser un problème, MAIS si vous le faites, c'est la seule façon de fonctionner.

Ceci est avec choisi 1.4.2 validationEngine 2.6.2 et jquery 2.1.4

// binds form submission and fields to the validation engine
jQuery("#FORMNAME").validationEngine({
    prettySelect : true,
    useSuffix: "_chosen"
    //promptPosition : "bottomLeft"
});
1
Mav2287

@Anupal m'a mis sur la bonne voie, mais j'avais besoin d'une solution complexe

Activer .chosen à prendre en compte

javascript

$.validator.setDefaults({ ignore: ":hidden:not(.chosen)" })

Ou tout autre nom que vous donnez à celui que vous avez choisi. C'est la configuration globale. Envisager de placer au plus haut niveau

Créer une règle personnalisée pour choisi

Merci à BenG

html

<select id="field" name="field" class="chosen" data-rule-chosen-required="true">
    <option value="">Please select…</option>
</select>

javascript

Là encore, configuration globale pour l’objet $.validator. Peut être placé à côté de la commande précédente

$.validator.addMethod('chosen-required', function (value, element, requiredValue) {
    return requiredValue == false || element.value != '';
}, $.validator.messages.required);
1
Alwin Kesler

Merci cette réponse https://stackoverflow.com/a/40310699/4700162 i résoudre le problème: 

Dans le fichier Chosen.jquery.js, changez

this.form_field_jq.hide().after(this.container);

avec ça: 

this.form_field_jq.css('position', 'absolute').css('opacity', 0).after(this.container);
0
Antonio Faienza

vous pouvez utiliser la validation jQuery pour le plug-in "choisi". Travailler bien pour moi.

$('.chosen').chosen({
        allow_single_deselect: true
    });
    $.validator.setDefaults({ ignore: ":hidden:not(select)" });
        $('form').validate({
            highlight: function(element) {
                $(element).closest('.form-group').addClass('has-error');
        },
        unhighlight: function(element) {
            $(element).closest('.form-group').removeClass('has-error');
        },
        errorElement: 'span',
        errorClass: 'help-block text-danger',
        errorPlacement: function(error, element) {
            if(element.parent('.input-group').length) {
                error.insertAfter(element.parent());
            } else {
                error.insertAfter(element.parent());
            }
        }
    });
0
Altaf

Mon formulaire inclut des champs masqués conditionnellement, pour empêcher la validation des champs choisis masqués, j'ai étendu la valeur par défaut ignore: caché un peu plus loin

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

0
ecolema
jQuery("#formID").validationEngine({
     prettySelect : true,
     useSuffix: "_chzn"
});

Moteur de validation jQuery/demoChosenLibrary

0
dsmoreira

Vous pouvez aussi essayer ceci:

$('form').on('submit', function(event) {
    event.preventDefault();
    if($('form').valid() == true && $('.select-chosen').valid() == true){
        console.log("Valid form");
    } else {
        console.log("Invalid form");
    }
}); 

N'oubliez pas d'ajouter la classe .select-chosen sur chaque selects.

$('.select-chosen').valid() force la validation pour la selects cachée

http://jsfiddle.net/mrZF5/39/

0
Fred K

En 2018, je vérifie que jQuery validate se plaint d'un champ de saisie sans nom. Ce champ de saisie est ajouté par le script jQuery Chosen.

 enter image description here

Ce bogue survient avant toute autre chose lorsque vous utilisez choisi.

0
MarkSkayff

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...
});

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

0
noypiscripter