¿Usa el atributo HTML5 "requerido" para un grupo de casillas de verificación?

172

Cuando se utilizan los navegadores más nuevos que admiten HTML5 (FireFox 4, por ejemplo);
y un campo de formulario tiene el atributo required='required';
y el campo del formulario está vacío / en blanco;
y se hace clic en el botón de enviar;
los navegadores detectan que el campo "requerido" está vacío y no envía el formulario;
en cambio, el navegador muestra una pista pidiéndole al usuario que escriba texto en el campo.

Ahora, en lugar de un solo campo de texto, tengo un grupo de casillas de verificación , de las cuales el usuario debe marcar / seleccionar al menos una.

¿Cómo puedo usar el requiredatributo HTML5 en este grupo de casillas de verificación? (Dado que solo una de las casillas de verificación debe estar marcada, no puedo poner el requiredatributo en cada casilla de verificación)

PD. Estoy usando simple_form , si eso importa.


ACTUALIZAR

¿Podría ser útil el atributo HTML 5multiple aquí? ¿Alguien lo ha usado antes para hacer algo similar a mi pregunta?

ACTUALIZAR

Se parece que esta característica no es compatible con la especificación HTML 5: NÚMERO-111: Lo que hace de entrada @ requiere media para @type = casilla de verificación.?

(Estado del problema: el problema se ha marcado cerrado sin perjuicio ) . Y aquí está la explicación .

ACTUALIZACIÓN 2

Es una pregunta antigua, pero quería aclarar que la intención original de la pregunta era poder hacer lo anterior sin usar Javascript, es decir, usar una forma HTML5 de hacerlo. En retrospectiva, debería haber hecho el "sin Javascript" más obvio.

Zabba
fuente
44
Esta es una gran pregunta y se aplica a cualquier entrada de formulario que sea una matriz (incluidas las entradas de texto) en la que desee tener al menos un elemento con un valor o marcado (pero no uno específico). Demostración Creo que puede que no haya una manera de hacer esto, pero espero que la haya. (Por cierto, no importa qué idioma o marco o biblioteca, es estrictamente HTML5)
Wesley Murch
Gracias por agregar esa demostración de JSFiddle. Con suerte, hay alguna forma HTML5 de hacer esto, de lo contrario, probablemente tenga que acumular alguna solución usando JQuery y un campo oculto o algo así.
Zabba
Si desea recurrir a javascript (y está usando jQuery), no necesita "enrollar" nada, use el complemento de validación altamente establecido: bassistance.de/jquery-plugins/jquery-plugin-validation
Wesley Murch
55
@natedavisolds, diría que el uso es útil en algunas IU: en mi opinión, seleccionar varias casillas de verificación es más intuitivo para el usuario final, especialmente cuando la cantidad de casillas de verificación es pequeña, en lugar de hacer clic + seleccionar, como es el caso de un cuadro de selección múltiple.
Zabba
1
Como nota al margen, no necesita todo ese bit required = 'required'; simplemente poner 'requerido' es suficiente.
William

Respuestas:

85

Lamentablemente, HTML5 no proporciona una forma inmediata de hacerlo.

Sin embargo, con jQuery, puede controlar fácilmente si un grupo de casillas de verificación tiene al menos un elemento marcado.

Considere el siguiente fragmento de DOM:

<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>

Puedes usar esta expresión:

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

que regresa truesi al menos un elemento está marcado. En base a eso, puede implementar su verificación de validación.

Luca Fagioli
fuente
@Clijsters la pregunta es sobre una forma HTML5 de hacerlo, no con Javascript (por supuesto, hay varias soluciones posibles en Javascript)
Zabba
66
@Zabba Pero esta respuesta dice. cómo hacerlo en html5 escribiendo Desafortunadamente HTML5 no proporciona una forma inmediata de hacerlo
Clijsters
Bastante justo @Clijsters
Zabba
18

Es un simple truco. Este es un código jQuery que puede explotar la validación html5 cambiando las requiredpropiedades si se marca alguna. El siguiente es su código html (asegúrese de agregar el requerido para todos los elementos en el grupo).

<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

El siguiente es el script jQuery, que desactiva la verificación de validación adicional si se selecciona alguno. Seleccione usando el elemento de nombre.

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

Pequeño problema aquí: dado que está utilizando la validación html5, asegúrese de ejecutar esto antes de que se valide, es decir, antes de enviar el formulario.

// 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
fuente
Si bien es posible hacerlo a través de Javascript, estaba buscando una solución sin usar Javascript.
Zabba
3
Creo que esta es la mejor respuesta hasta ahora. Sí, usa JavaScript, pero usa la validación de HTML5 en lugar de tener una alerta emergente de JavaScript. Otras respuestas usan JS y una ventana emergente JS.
Cruz Núñez
1
Esto es realmente bueno. Asegúrese de elegir una u otra en esas dos primeras líneas jQuery (la segunda cancela la primera). También asegúrese de cambiar "opción" al nombre de la opción.
Allen Gingrich
Dado que esto no es compatible de forma nativa en HTML5, esta debería ser la respuesta aceptada. No quiero implementar mi propia biblioteca de validación solo para un conjunto de campos de casilla de verificación en un solo formulario en mi sitio.
JamesWilson
11

Supongo que no hay una forma HTML5 estándar de hacer esto, pero si no le importa usar una biblioteca jQuery, he podido lograr una validación de "grupo de casillas de verificación" utilizando la función de validación " requerida por el grupo " de webshims :

Los documentos para grupo requerido dicen:

Si una casilla de verificación tiene la clase 'grupo requerido', se debe marcar al menos una de las casillas de verificación con el mismo nombre dentro del formulario / documento.

Y aquí hay un ejemplo de cómo lo usarías:

<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" />

Principalmente uso webshims para rellenar funciones HTML5, pero también tiene algunas extensiones opcionales geniales como esta.

Incluso le permite escribir sus propias reglas de validez personalizadas. Por ejemplo, necesitaba crear un grupo de casillas de verificación que no se basara en el nombre de la entrada, así que escribí mi propia regla de validez para eso ...

Tyler Rick
fuente
11

HTML5 no admite directamente que se requiera solo una / al menos una casilla de verificación en un grupo de casilla de verificación. Aquí está mi solución usando 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;
                }
            }
        }

El javascript asegurará que al menos una casilla de verificación esté marcada, luego eliminará la necesidad de todo el grupo de casillas de verificación. Si la casilla de verificación que está marcada no está marcada, ¡requerirá todas las casillas de verificación nuevamente!

Brian Woodward
fuente
Una solución muy buena y limpia. Wish podría dar más de +1 voto.
Sonal
De acuerdo @Sonal! Gracias por esta solución Brian!
NorahKSakal
3

Tuve el mismo problema y mi solución fue esta:

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
fuente
2

Inspirado por las respuestas de @thegauraw y @Brian Woodward, aquí hay un poco que reuní para los usuarios de JQuery, incluido un mensaje de error de validación personalizado:

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

Tenga en cuenta que mi formulario tiene algunas casillas marcadas de forma predeterminada.

¿Quizás algunos de ustedes magos de JavaScript / JQuery podrían reforzar eso aún más?

ewall
fuente
2

podemos hacer esto fácilmente con html5 también, solo necesitamos agregar un código jquery

Manifestación

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
fuente
2

Agregué una radio invisible a un grupo de casillas de verificación. Cuando al menos una opción está marcada, la radio también está configurada para verificar. Cuando se cancelan todas las opciones, la radio también se configura para cancelar. Por lo tanto, el formulario utiliza el mensaje de radio "Marque al menos una opción"

  • No se puede usar display: noneporque la radio no se puede enfocar.
  • Hago que el tamaño de la radio sea igual al tamaño completo de las casillas de verificación, por lo que es más obvio cuando se me solicita.

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
fuente
Esta es una gran solución. Funciona de maravilla. Sin embargo, en Firefox, aparece un gran contorno rojo alrededor del cuadro del botón de opción cuando está configurado como requerido en todos los controles de formulario que usan este botón de opción. ¿Hay alguna forma de diseñar el contorno para que no sea rojo cuando no es válido (el botón de opción no está marcado cuando es necesario) excepto cuando el usuario presiona enviar y se lleva a cabo la validación?
gib65
Podemos establecer radio's opacityen 0, y establecer opacityen 1 cuando se envía, para que podamos controlar si el contorno rojo aparece o no.
Codus
¡Esta solución es genial! En mi caso, no funcionó si uso cualquiera visibility: hiddeno display: nonesolo para evitar ensuciar un poco la usabilidad. Porque los lectores de pantalla y otras herramientas de accesibilidad probablemente encontrarán el botón de radio oculto.
hoorider
1

Hola, solo use un cuadro de texto adicional al grupo de la casilla de verificación. Al hacer clic en cualquier casilla de verificación, coloque los valores en ese cuadro de texto. Haga que ese cuadro de texto sea obligatorio y de solo lectura.

Abijith
fuente
0

Me doy cuenta de que hay un montón de soluciones aquí, pero descubrí que ninguna de ellas cumple con todos los requisitos que tenía:

  • No se requiere codificación personalizada
  • El código funciona al cargar la página
  • No se requieren clases personalizadas (casillas de verificación o sus padres)
  • Necesitaba varias listas de casillas de verificación para compartir lo mismo nameal enviar problemas de Github a través de su API, y estaba usando el nombre label[]para asignar etiquetas en muchos campos de formulario (dos listas de casillas de verificación y algunas selecciones y cuadros de texto), dado que podría haber logrado esto sin que compartieran el mismo nombre, pero decidí probarlo y funcionó.

El único requisito para este es jQuery. Puede combinar esto con la excelente solución de @ewall para agregar mensajes de error de validación personalizados.

/* 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
fuente
-1

¡Aquí hay otro truco simple con 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");
    }
});

Eso es todo ... esto funciona porque si ninguna de las casillas de verificación está seleccionada, nada en lo que respecta al grupo de casillas de verificación (incluido su nombre) se publica en el servidor

oluwatayo_
fuente
-1

Tratar:

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

o

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

Más específicamente:

Cuando esté leyendo datos de la matriz de casillas de verificación, asegúrese de que la matriz tenga:

len>0 

En este caso:

len(self.request.get('array', allow_multiple=True)) > 0
Gjison Giocf
fuente
¿Podrías explicar un poco más tu respuesta?
Veinte
cuando esté leyendo datos de la matriz de casilla de verificación, asegúrese de que la matriz tenga len> 0 en este caso: len (self.request.get ('array', allow_multiple = True))> 0
Gjison Giocf
Edite su pregunta con la información en su comentario anterior y me complacerá eliminar el voto negativo.
Veinte
Gracias por editar tu publicación, pero un poco más de cortesía sería apropiado.
Veinte
Parece totalmente ajeno a la pregunta. Pregunta acerca de la validación html, y la solución aquí es python. La pregunta ni siquiera es acerca de la validación del lado del servidor, es si hay una manera de validar los grupos de casillas de verificación para verificar si al menos 1 está marcado.
Octavioamu