Vous utilisez l'attribut HTML5 «obligatoire» pour un groupe de cases à cocher?

172

Lors de l'utilisation des nouveaux navigateurs prenant en charge HTML5 (FireFox 4 par exemple);
et un champ de formulaire a l'attribut required='required';
et le champ de formulaire est vide / vide;
et le bouton de soumission est cliqué;
les navigateurs détectent que le champ "obligatoire" est vide et ne soumet pas le formulaire;
à la place, le navigateur affiche un indice demandant à l'utilisateur de taper du texte dans le champ.

Maintenant, au lieu d'un seul champ de texte, j'ai un groupe de cases à cocher , parmi lesquelles au moins une doit être cochée / sélectionnée par l'utilisateur.

Comment puis-je utiliser l' requiredattribut HTML5 sur ce groupe de cases à cocher? (Étant donné qu'une seule des cases à cocher doit être cochée, je ne peux pas mettre l' requiredattribut sur chaque case à cocher)

ps. J'utilise simple_form , si cela compte.


METTRE À JOUR

L' attribut HTML 5multiple pourrait-il être utile ici? Quelqu'un l'a-t-il déjà utilisé pour faire quelque chose de similaire à ma question?

METTRE À JOUR

Il semble que cette fonctionnalité n'est pas prise en charge par la spécification HTML5: ISSUE-111: Que signifie input. @ Required pour @type = checkbox?

(Statut du problème: le problème a été marqué comme clos sans préjudice. ) Et voici l'explication .

MISE À JOUR 2

C'est une vieille question, mais je voulais clarifier que l'intention originale de la question était de pouvoir faire ce qui précède sans utiliser Javascript - c'est-à-dire en utilisant une manière HTML5 de le faire. Rétrospectivement, j'aurais dû rendre le "sans Javascript" plus évident.

Zabba
la source
4
C'est une excellente question, et s'applique à toute entrée de formulaire qui est un tableau (y compris les entrées de texte) où vous souhaitez avoir au moins un élément avec une valeur ou coché (mais pas un élément spécifique). Démo Je pense qu'il n'y a peut-être pas de moyen de le faire, mais j'espère que oui. (BTW peu importe la langue, le framework ou la bibliothèque, c'est strictement HTML5)
Wesley Murch
Merci d'avoir ajouté cette démo JSFiddle. Espérons qu'il existe un moyen HTML5 de le faire, sinon il faudra probablement mettre en place une solution en utilisant JQuery et un champ caché ou quelque chose.
Zabba
Si vous souhaitez revenir au javascript (et que vous utilisez jQuery), pas besoin de "roll up" quoi que ce soit, utilisez le plugin de validation hautement établi: bassistance.de/jquery-plugins/jquery-plugin-validation
Wesley Murch
5
@natedavisolds, je dirais que l'utilisation est utile dans certaines interfaces utilisateur - OMI, la sélection de plusieurs cases à cocher est plus intuitive pour l'utilisateur final, en particulier lorsque le nombre de cases à cocher est petit - plutôt qu'un clic + sélectionnez comme c'est le cas avec un boîte de sélection multiple.
Zabba
1
En remarque, vous n'avez pas besoin de tout ce bit required = 'required'; il suffit de mettre «requis».
William

Réponses:

85

Malheureusement, HTML5 ne fournit pas un moyen prêt à l'emploi de le faire.

Cependant, en utilisant jQuery, vous pouvez facilement contrôler si un groupe de cases à cocher a au moins un élément coché.

Considérez l'extrait de code DOM suivant:

<div class="checkbox-group required">
    <input type="checkbox" name="checkbox_name[]">
    <input type="checkbox" name="checkbox_name[]">
    <input type="checkbox" name="checkbox_name[]">
    <input type="checkbox" name="checkbox_name[]">
</div>

Vous pouvez utiliser cette expression:

$('div.checkbox-group.required :checkbox:checked').length > 0

qui renvoie truesi au moins un élément est vérifié. Sur cette base, vous pouvez implémenter votre contrôle de validation.

Luca Fagioli
la source
@Clijsters la question porte sur une façon HTML5 de le faire - pas avec Javascript (bien sûr, différentes solutions sont possibles en Javascript)
Zabba
6
@Zabba Mais cette réponse dit. comment le faire en html5 en écrivant Malheureusement, HTML5 ne fournit pas un moyen
Clijsters
Juste assez @Clijsters
Zabba
18

C'est un truc simple. C'est du code jQuery qui peut exploiter la validation html5 en modifiant les requiredpropriétés si l'une d'entre elles est cochée. Voici votre code html (assurez-vous d'ajouter les éléments requis pour tous les éléments du groupe.)

<input type="checkbox" name="option[]" id="option-1" value="option1" required/> Option 1
<input type="checkbox" name="option[]" id="option-2" value="option2" required/> Option 2
<input type="checkbox" name="option[]" id="option-3" value="option3" required/> Option 3
<input type="checkbox" name="option[]" id="option-4" value="option4" required/> Option 4
<input type="checkbox" name="option[]" id="option-5" value="option5" required/> Option 5

Voici le script jQuery, qui désactive la vérification de validation supplémentaire si l'un d'entre eux est sélectionné. Sélectionnez en utilisant l'élément de nom.

$cbx_group = $("input:checkbox[name='option[]']");
$cbx_group = $("input:checkbox[id^='option-']"); // name is not always helpful ;)

$cbx_group.prop('required', true);
if($cbx_group.is(":checked")){
  $cbx_group.prop('required', false);
}

Petit gotcha ici: Puisque vous utilisez la validation html5, assurez-vous de l'exécuter avant qu'il ne soit validé, c'est-à-dire avant l'envoi du formulaire.

// but this might not work as expected
$('form').submit(function(){
  // code goes here
});

// So, better USE THIS INSTEAD:
$('button[type="submit"]').on('click', function() {
  // skipping validation part mentioned above
});
thegauraw
la source
Bien qu'il soit possible de le faire via Javascript, je cherchais une solution sans utiliser Javascript.
Zabba
3
Je pense que c'est la meilleure réponse à ce jour. Oui, il utilise javascript, mais il utilise la validation de HTML5 au lieu de faire apparaître une alerte JavaScript. D'autres réponses utilisent JS et une fenêtre contextuelle JS.
Cruz Nunez
1
Ceci est vraiment bon. Assurez-vous de choisir l'un ou l'autre sur ces deux premières lignes jQuery (la seconde annule la première). Assurez-vous également de remplacer «option» par le nom de l'option.
Allen Gingrich
Étant donné que cela n'est pas pris en charge nativement dans HTML5, cela devrait vraiment être la réponse acceptée! Je ne souhaite pas implémenter ma propre bibliothèque de validation uniquement pour un ensemble de champs de case à cocher sur un seul formulaire sur mon site.
JamesWilson
11

Je suppose qu'il n'y a aucun moyen standard HTML5 pour ce faire, mais si cela ne vous dérange pas en utilisant une bibliothèque de jQuery, je suis en mesure de réaliser une validation « groupe de cases à cocher » en utilisant webshims ' " requis groupe " de :

Les documents pour les groupes requis disent:

Si une case à cocher a la classe «group-required», au moins une des cases à cocher avec le même nom dans le formulaire / document doit être cochée.

Et voici un exemple de la façon dont vous l'utiliseriez:

<input name="checkbox-group" type="checkbox" class="group-required" id="checkbox-group-id" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />

J'utilise principalement des webshims pour polyfill des fonctionnalités HTML5, mais il a également de superbes extensions optionnelles comme celle-ci.

Il vous permet même d'écrire vos propres règles de validité personnalisées. Par exemple, j'avais besoin de créer un groupe de cases à cocher qui n'était pas basé sur le nom de l'entrée, j'ai donc écrit ma propre règle de validité pour cela ...

Tyler Rick
la source
11

HTML5 ne prend pas directement en charge le fait d'exiger qu'une seule / au moins une case soit cochée dans un groupe de cases à cocher. Voici ma solution utilisant Javascript:

HTML

<input class='acb' type='checkbox' name='acheckbox[]' value='1' onclick='deRequire("acb")' required> One
<input class='acb' type='checkbox' name='acheckbox[]' value='2' onclick='deRequire("acb")' required> Two

JAVASCRIPT

       function deRequireCb(elClass) {
            el=document.getElementsByClassName(elClass);

            var atLeastOneChecked=false;//at least one cb is checked
            for (i=0; i<el.length; i++) {
                if (el[i].checked === true) {
                    atLeastOneChecked=true;
                }
            }

            if (atLeastOneChecked === true) {
                for (i=0; i<el.length; i++) {
                    el[i].required = false;
                }
            } else {
                for (i=0; i<el.length; i++) {
                    el[i].required = true;
                }
            }
        }

Le javascript s'assurera qu'au moins une case est cochée, puis supprimera l'intégralité du groupe de cases à cocher. Si la case à cocher qui est cochée devient non cochée, alors il faudra toutes les cases à cocher, encore une fois!

Brian Woodward
la source
Une solution très bonne et propre. Wish pourrait donner plus de +1 vote.
Sonal
D'accord @Sonal! Merci pour cette solution Brian!
NorahKSakal
3

J'ai eu le même problème et ma solution était la suivante:

HTML:

<form id="processForm.php" action="post">
  <div class="input check_boxes required wish_payment_type">
    <div class="wish_payment_type">
    <span class="checkbox payment-radio">
      <label for="wish_payment_type_1">
        <input class="check_boxes required" id="wish_payment_type_1" name="wish[payment_type][]" type="checkbox" value="1">Foo
      </label>
    </span>
    <span class="checkbox payment-radio">
      <label for="wish_payment_type_2">
        <input class="check_boxes required" id="wish_payment_type_2" name="wish[payment_type][]" type="checkbox" value="2">Bar
      </label>
    </span>
    <span class="checkbox payment-radio">
      <label for="wish_payment_type_3">
        <input class="check_boxes required" id="wish_payment_type_3" name="wish[payment_type][]" type="checkbox" value="3">Buzz
      </label>

      <input id='submit' type="submit" value="Submit">
  </div>
</form>

JS:

var verifyPaymentType = function () {
  var checkboxes = $('.wish_payment_type .checkbox');
  var inputs = checkboxes.find('input');
  var first = inputs.first()[0];

  inputs.on('change', function () {
    this.setCustomValidity('');
  });

  first.setCustomValidity(checkboxes.find('input:checked').length === 0 ? 'Choose one' : '');
}

$('#submit').click(verifyPaymentType);

https://jsfiddle.net/oywLo5z4/

Passalini
la source
2

Inspiré par les réponses de @thegauraw et @Brian Woodward, voici un peu que j'ai rassemblé pour les utilisateurs de JQuery, y compris un message d'erreur de validation personnalisé:

$cbx_group = $("input:checkbox[name^='group']");
$cbx_group.on("click", function() {
    if ($cbx_group.is(":checked")) {
        // checkboxes become unrequired as long as one is checked
        $cbx_group.prop("required", false).each(function() {
            this.setCustomValidity("");
        });
    } else {
        // require checkboxes and set custom validation error message
        $cbx_group.prop("required", true).each(function() {
            this.setCustomValidity("Please select at least one checkbox.");
        });
    }
});

Notez que certaines cases à cocher de mon formulaire sont cochées par défaut.

Peut-être que certains d'entre vous, les assistants JavaScript / JQuery pourraient renforcer encore plus cela?

ewall
la source
2

nous pouvons le faire facilement avec html5 également, il suffit d'ajouter du code jquery

Démo

HTML

<form>
 <div class="form-group options">
   <input type="checkbox" name="type[]" value="A" required /> A
   <input type="checkbox" name="type[]" value="B" required /> B
   <input type="checkbox" name="type[]" value="C" required /> C
   <input type="submit">
 </div>
</form>

Jquery

$(function(){
    var requiredCheckboxes = $('.options :checkbox[required]');
    requiredCheckboxes.change(function(){
        if(requiredCheckboxes.is(':checked')) {
            requiredCheckboxes.removeAttr('required');
        } else {
            requiredCheckboxes.attr('required', 'required');
        }
    });
});
Juned Ansari
la source
2

J'ai ajouté une radio invisible à un groupe de cases à cocher. Lorsqu'au moins une option est cochée, la radio est également configurée pour vérifier. Lorsque toutes les options sont annulées, la radio est également réglée pour annuler. Par conséquent, le formulaire utilise l'invite radio "Veuillez cocher au moins une option"

  • Vous ne pouvez pas utiliser display: nonecar la radio ne peut pas être focalisée.
  • Je rends la taille de la radio égale à la taille entière des cases à cocher, donc c'est plus évident lorsque vous y êtes invité.

HTML

<form>
  <div class="checkboxs-wrapper">
    <input id="radio-for-checkboxes" type="radio" name="radio-for-required-checkboxes" required/>
    <input type="checkbox" name="option[]" value="option1"/>
    <input type="checkbox" name="option[]" value="option2"/>
    <input type="checkbox" name="option[]" value="option3"/>
  </div>
  <input type="submit" value="submit"/>
</form>

Javascript

var inputs = document.querySelectorAll('[name="option[]"]')
var radioForCheckboxes = document.getElementById('radio-for-checkboxes')
function checkCheckboxes () {
    var isAtLeastOneServiceSelected = false;
    for(var i = inputs.length-1; i >= 0; --i) {
        if (inputs[i].checked) isAtLeastOneCheckboxSelected = true;
    }
    radioForCheckboxes.checked = isAtLeastOneCheckboxSelected
}
for(var i = inputs.length-1; i >= 0; --i) {
    inputs[i].addEventListener('change', checkCheckboxes)
}

CSS

.checkboxs-wrapper {
  position: relative;
}
.checkboxs-wrapper input[name="radio-for-required-checkboxes"] {
    position: absolute;
    margin: 0;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    -webkit-appearance: none;
    pointer-events: none;
    border: none;
    background: none;
}

https://jsfiddle.net/codus/q6ngpjyc/9/

Codus
la source
C'est une excellente solution. Fonctionne comme un charme. Cependant, dans Firefox, j'obtiens un gros contour rouge autour de la case du bouton radio lorsqu'elle est définie sur obligatoire sur tous les contrôles de formulaire à l'aide de ce bouton radio. Existe-t-il un moyen de styliser le contour pour ne pas être rouge lorsqu'il est invalide (bouton radio non coché si nécessaire) sauf lorsque l'utilisateur clique sur Soumettre et que la validation est effectuée?
gib65
Nous pouvons définir radiola valeur opacity0 et la valeur opacity1 lors de la soumission, afin de pouvoir contrôler si le contour rouge apparaît ou non.
Codus
Cette solution est géniale !! Dans mon cas, cela ne fonctionnait pas si j'utilise l'un visibility: hiddenou l' autre ou display: nonesimplement pour éviter de salir un peu la convivialité. Parce que les lecteurs d'écran et autres outils d'accessibilité trouveront probablement le bouton radio masqué.
hoorider
1

Salut, utilisez simplement une zone de texte supplémentaire au groupe de case à cocher.Lorsque vous cliquez sur une case à cocher, mettez des valeurs dans cette zone de texte.Faites en sorte que cette zone de texte soit requise et en lecture seule.

Abijith
la source
0

Je me rends compte qu'il existe une tonne de solutions ici, mais je n'ai trouvé aucune d'elles répondant à toutes les exigences que j'avais:

  • Aucun codage personnalisé requis
  • Le code fonctionne au chargement de la page
  • Aucune classe personnalisée requise (cases à cocher ou leur parent)
  • J'avais besoin de plusieurs listes de cases à cocher pour partager la même chose namepour soumettre des problèmes Github via leur API, et j'utilisais le nom label[]pour attribuer des étiquettes à de nombreux champs de formulaire (deux listes de cases à cocher et quelques sélections et zones de texte) - étant donné que j'aurais pu y parvenir sans leur partage le même nom, mais j'ai décidé de l'essayer et cela a fonctionné.

La seule exigence pour celui-ci est jQuery. Vous pouvez combiner cela avec l'excellente solution de @ ewall pour ajouter des messages d'erreur de validation personnalisés.

/* required checkboxes */
(function ($) {
	$(function () {
		var $requiredCheckboxes = $("input[type='checkbox'][required]");

		/* init all checkbox lists */
		$requiredCheckboxes.each(function (i, el) {
			//this could easily be changed to suit different parent containers
			var $checkboxList = $(this).closest("div, span, p, ul, td");

			if (!$checkboxList.hasClass("requiredCheckboxList"))
				$checkboxList.addClass("requiredCheckboxList");
		});

		var $requiredCheckboxLists = $(".requiredCheckboxList");

		$requiredCheckboxLists.each(function (i, el) {
			var $checkboxList = $(this);
			$checkboxList.on("change", "input[type='checkbox']", function (e) {
				updateCheckboxesRequired($(this).parents(".requiredCheckboxList"));
			});

			updateCheckboxesRequired($checkboxList);
		});

		function updateCheckboxesRequired($checkboxList) {
			var $chk = $checkboxList.find("input[type='checkbox']").eq(0),
				cblName = $chk.attr("name"),
				cblNameAttr = "[name='" + cblName + "']",
				$checkboxes = $checkboxList.find("input[type='checkbox']" + cblNameAttr);

			if ($checkboxList.find(cblNameAttr + ":checked").length > 0) {
				$checkboxes.prop("required", false);
			} else {
				$checkboxes.prop("required", true);
			}
		}

	});
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form method="post" action="post.php">
<div>
	Type of report:
</div>
<div>
	<input type="checkbox" id="chkTypeOfReportError" name="label[]" value="Error" required>
	<label for="chkTypeOfReportError">Error</label>

	<input type="checkbox" id="chkTypeOfReportQuestion" name="label[]" value="Question" required>
	<label for="chkTypeOfReportQuestion">Question</label>

	<input type="checkbox" id="chkTypeOfReportFeatureRequest" name="label[]" value="Feature Request" required>
	<label for="chkTypeOfReportFeatureRequest">Feature Request</label>
</div>

<div>
	Priority
</div>
<div>
	<input type="checkbox" id="chkTypeOfContributionBlog" name="label[]" value="Priority: High" required>
	<label for="chkPriorityHigh">High</label>


	<input type="checkbox" id="chkTypeOfContributionBlog" name="label[]" value="Priority: Medium" required>
	<label for="chkPriorityMedium">Medium</label>


	<input type="checkbox" id="chkTypeOfContributionLow" name="label[]" value="Priority: Low" required>
	<label for="chkPriorityMedium">Low</label>
</div>
<div>
	<input type="submit" />
</div>
</form>

Sean Kendle
la source
-1

Voici une autre astuce simple en utilisant Jquery !!

HTML

<form id="hobbieform">
        <div>
            <input type="checkbox" name="hobbies[]">Coding
            <input type="checkbox" name="hobbies[]">Gaming
            <input type="checkbox" name="hobbies[]">Driving
        </div>
</form>


JQuery

$('#hobbieform').on("submit", function (e) {
    var arr = $(this).serialize().toString();
    if(arr.indexOf("hobbies") < 0){
        e.preventDefault();
        alert("You must select at least one hobbie");
    }
});

C'est tout .. cela fonctionne car si aucune case n'est cochée, rien concernant le groupe de cases à cocher (y compris son nom) n'est posté sur le serveur

oluwatayo_
la source
-1

Essayer:

self.request.get('sports_played', allow_multiple=True)

ou

self.request.POST.getall('sports_played')

Plus précisement:

Lorsque vous lisez des données à partir du tableau de cases à cocher, assurez-vous que le tableau a:

len>0 

Dans ce cas:

len(self.request.get('array', allow_multiple=True)) > 0
Gjison Giocf
la source
Pourriez-vous peut-être élaborer un peu plus votre réponse?
Vingt
lorsque vous lisez des données à partir du tableau de cases à cocher, assurez-vous que le tableau a len> 0 dans ce cas: len (self.request.get ('array', allow_multiple = True))> 0
Gjison Giocf
Veuillez modifier votre question avec les informations contenues dans votre commentaire ci-dessus et je serai heureux de supprimer le vote défavorable.
Vingt
Merci d'avoir édité votre message, mais un peu plus de courtoisie serait approprié.
Vingt
semble totalement indépendante de la question. Questionne sur la validation html, et la solution ici est python. La question n'est même pas de poser des questions sur la validation côté serveur, c'est de se demander s'il existe un moyen de valider les groupes de cases à cocher pour vérifier si au moins 1 est coché.
Octavioamu