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?
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.
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')
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'
// 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;
});
});
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;
}
Je devais placer $.validator.setDefaults({ ignore: ":hidden:not(.chosen-select)" })
en dehors de $(document).ready(function()
afin de travailler avec selected.js.
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.
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"
});
@Anupal m'a mis sur la bonne voie, mais j'avais besoin d'une solution complexe
.chosen
à prendre en comptejavascript
$.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
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);
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);
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());
}
}
});
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
})
jQuery("#formID").validationEngine({
prettySelect : true,
useSuffix: "_chzn"
});
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 select
s.
$('.select-chosen').valid()
force la validation pour la select
s cachée
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')
.