Usando o atributo "obrigatório" do HTML5 para um grupo de caixas de seleção?

172

Ao usar os navegadores mais novos compatíveis com HTML5 (FireFox 4, por exemplo);
e um campo de formulário tem o atributo required='required';
e o campo do formulário está vazio / em branco;
e o botão enviar é clicado;
os navegadores detectam que o campo "obrigatório" está vazio e não envia o formulário;
Em vez disso, o navegador mostra uma dica solicitando ao usuário que digite texto no campo.

Agora, em vez de um único campo de texto, tenho um grupo de caixas de seleção , das quais pelo menos uma deve ser marcada / selecionada pelo usuário.

Como posso usar o requiredatributo HTML5 nesse grupo de caixas de seleção? (Como apenas uma das caixas de seleção precisa ser marcada, não posso colocar o requiredatributo em todas as caixas de seleção)

ps. Estou usando simple_form , se isso importa.


ATUALIZAR

O atributo HTML 5 podemultiple ser útil aqui? Alguém já o usou antes para fazer algo semelhante à minha pergunta?

ATUALIZAR

Ele parece que este recurso não é suportado pela especificação HTML5: QUESTÃO-111: O que faz de entrada @ exigida média para @type = caixa.?

(Status do problema: o problema foi marcado como fechado sem prejuízo. ) E aqui está a explicação .

ATUALIZAÇÃO 2

É uma pergunta antiga, mas queria esclarecer que a intenção original da pergunta era poder fazer o que precede sem usar Javascript - ou seja, usando uma maneira HTML5 de fazê-lo. Em retrospecto, eu deveria ter tornado o "sem Javascript" mais óbvio.

Zabba
fonte
4
Essa é uma ótima pergunta e se aplica a qualquer entrada de formulário que seja uma matriz (incluindo entradas de texto) em que você deseja ter pelo menos um item com um valor ou verificado (mas não um específico). Demonstração Acho que pode não haver uma maneira de fazer isso, mas espero que exista. (BTW não importa que idioma ou estrutura ou biblioteca, é estritamente HTML5)
Wesley Murch
Obrigado por adicionar a demonstração do JSFiddle. Esperamos que exista uma maneira HTML5 de fazer isso; caso contrário, provavelmente será necessário criar alguma solução usando JQuery e um campo oculto ou algo assim.
Zabba
Se você quiser voltar ao javascript (e estiver usando o jQuery), não precisará "acumular" nada, use o plug-in de validação altamente estabelecido: bassistance.de/jquery-plugins/jquery-plugin-validation
Wesley Murch
5
@natedavisolds, eu diria que o uso é útil em algumas UIs - IMO, selecionar várias caixas de seleção é mais intuitivo para o usuário final, especialmente quando o número de caixas de seleção é pequeno - em vez de um clique + selecionar como é o caso de um caixa de seleção múltipla.
Zabba
1
Como uma observação lateral, você não precisa desse bit obrigatório = 'obrigatório'; basta colocar 'obrigatório' é suficiente.
William

Respostas:

85

Infelizmente, o HTML5 não fornece uma maneira imediata de fazer isso.

No entanto, usando o jQuery, você pode controlar facilmente se um grupo de caixas de seleção possui pelo menos um elemento marcado.

Considere o seguinte trecho 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>

Você pode usar esta expressão:

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

que retorna truese pelo menos um elemento estiver marcado. Com base nisso, você pode implementar sua verificação de validação.

Luca Fagioli
fonte
@Clijsters a pergunta é sobre uma maneira HTML5 para fazê-lo - não com Javascript (é claro, várias soluções são possíveis em Javascript)
Zabba
6
@ Zabba Mas esta resposta diz. como fazê-lo em html5 escrevendo Infelizmente HTML5 não fornece uma maneira out-of-the-box para fazer isso
Clijsters
Justo o suficiente @Clijsters
Zabba
18

É um truque simples. Este é o código jQuery que pode explorar a validação do html5 alterando as requiredpropriedades, se alguém estiver marcado. A seguir está o seu código html (certifique-se de adicionar o necessário para todos os elementos do 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

A seguir, está o script jQuery, que desabilita a verificação adicional da validação, se houver alguém selecionado. Selecione usando o elemento name.

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

Pequenas dicas aqui: Como você está usando a validação html5, execute-a antes que ela seja validada, ou seja, antes do envio do formulário.

// 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
fonte
Embora seja possível fazer isso via Javascript, eu estava procurando uma solução sem usar Javascript.
Zabba
3
Eu acho que essa é a melhor resposta até agora. Sim, ele usa javascript, mas usa a validação do HTML5 em vez de exibir um alerta JavaScript. Outras respostas usam JS e uma janela pop-up JS.
Cruz Nunez
1
Isto é muito bom. Certifique-se de escolher uma ou outra nessas duas primeiras linhas do jQuery (a segunda cancela a primeira). Também certifique-se de alterar "option" para o nome da opção.
27617 Allen Gingrich
Dado que isso não é suportado nativamente no HTML5, essa realmente deve ser a resposta aceita! Não quero implementar minha própria biblioteca de validação apenas para um conjunto de campos da caixa de seleção em um único formulário no meu site.
JamesWilson
11

Acho que não há uma maneira padrão de HTML5 para fazer isso, mas se você não se importa em usar uma biblioteca jQuery, consegui obter uma validação de "grupo de caixas de seleção" usando o recurso de validação " exigido por grupo " do webshims :

Os documentos para o grupo exigido dizem:

Se uma caixa de seleção possui a classe 'grupo obrigatório', pelo menos uma das caixas de seleção com o mesmo nome dentro do formulário / documento deve ser marcada.

E aqui está um exemplo de como você o usaria:

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

Eu uso principalmente webshims para polyfill recursos HTML5, mas também possui algumas ótimas extensões opcionais como esta.

Ele ainda permite que você escreva suas próprias regras de validade personalizadas. Por exemplo, eu precisava criar um grupo de caixas de seleção que não fosse baseado no nome da entrada, então escrevi minha própria regra de validade para isso ...

Tyler Rick
fonte
11

O HTML5 não suporta diretamente exigir que apenas uma / pelo menos uma caixa de seleção esteja marcada em um grupo de caixas de seleção. Aqui está minha solução 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;
                }
            }
        }

O javascript garantirá que pelo menos uma caixa de seleção esteja marcada e, portanto, exigirá todo o grupo de caixas de seleção. Se a caixa de seleção marcada estiver desmarcada, serão necessárias todas as caixas de seleção novamente!

Brian Woodward
fonte
Uma solução muito boa e limpa. O desejo pode dar mais de um voto.
Sonal 28/11
Concordou @Sonal! Obrigado por esta solução Brian!
NorahKSakal 10/09/19
3

Eu tive o mesmo problema e minha solução foi a seguinte:

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

Inspirado nas respostas de @thegauraw e @Brian Woodward, aqui está um pouco que eu reuni para os usuários do JQuery, incluindo uma mensagem de erro de validação personalizada:

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

Observe que meu formulário tem algumas caixas de seleção marcadas por padrão.

Talvez alguns de vocês assistentes JavaScript / JQuery possam aumentar ainda mais isso?

ewall
fonte
2

também podemos fazer isso facilmente com o html5, basta adicionar algum código jquery

Demo

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

Adicionei um rádio invisível a um grupo de caixas de seleção. Quando pelo menos uma opção está marcada, o rádio também está configurado para verificar. Quando todas as opções são canceladas, o rádio também está definido para cancelar. Portanto, o formulário usa o prompt de rádio "Verifique pelo menos uma opção"

  • Você não pode usar display: noneporque o rádio não pode ser focado.
  • Como o tamanho do rádio é igual ao tamanho inteiro das caixas de seleção, fica mais óbvio quando solicitado.

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
fonte
Esta é uma otima soluçao. Funciona como um encanto. No entanto, no Firefox, recebo um grande contorno vermelho em torno da caixa do botão de opção quando ela é definida como necessária em todos os controles de formulário usando esse botão de opção. Existe uma maneira de estilizar o contorno para não ficar vermelho quando inválido (botão de opção não marcado quando necessário), exceto quando o usuário clicar em enviar e a validação for realizada?
precisa saber é o seguinte
Podemos definir radio's opacitya 0, e set opacitya 1 quando submetidos, para que possamos controlar se aparece contorno vermelho ou não.
Codus 13/09/19
Esta solução é genial !! No meu caso, não funcionou se eu usar um visibility: hiddenou display: noneapenas para evitar que a usabilidade fique um pouco suja. Como os leitores de tela e outras ferramentas de acessibilidade provavelmente encontrarão o botão de opção oculto.
hoorider 9/03
1

Olá, basta usar uma caixa de texto adicional ao grupo de caixas de seleção. Ao clicar em qualquer caixa de seleção, insira valores nessa caixa de texto.

Abijith
fonte
0

Sei que há várias soluções aqui, mas não encontrei nenhuma delas que atendesse a todos os requisitos que eu tinha:

  • Nenhuma codificação personalizada necessária
  • O código funciona no carregamento da página
  • Não são necessárias classes personalizadas (caixas de seleção ou seus pais)
  • Eu precisava de várias listas de caixas de seleção para compartilhar o mesmo namepara enviar problemas do Github por meio de sua API e estava usando o nome label[]para atribuir rótulos em vários campos de formulário (duas listas de caixas de seleção e algumas caixas de seleção e de texto) - desde que eu pudesse ter conseguido isso sem compartilhar. o mesmo nome, mas decidi tentar e funcionou.

O único requisito para este é o jQuery. Você pode combinar isso com a ótima solução do @ ewall para adicionar mensagens de erro de validação personalizadas.

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

Aqui está outro truque simples usando o 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");
    }
});

Isso é tudo .. isso funciona porque, se nenhuma das caixas de seleção estiver marcada, nada em relação ao grupo de caixas de seleção (incluindo o nome) será publicado no servidor

oluwatayo_
fonte
-1

Experimentar:

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

ou

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

Mais especificamente:

Ao ler dados da matriz da caixa de seleção, verifique se a matriz possui:

len>0 

Nesse caso:

len(self.request.get('array', allow_multiple=True)) > 0
Gjison Giocf
fonte
Você poderia elaborar sua resposta um pouco mais?
20 de
ao ler dados da matriz da caixa de seleção, verifique se a matriz possui len> 0 neste caso: len (self.request.get ('array', allow_multiple = True))> 0
Gjison Giocf
Edite sua pergunta com as informações do seu comentário acima e teremos prazer em remover o voto negativo.
20 de
Obrigado por editar sua postagem, mas um pouco mais de cortesia seria apropriado.
Twenty
parece totalmente não relacionado à questão. Está perguntando sobre a validação de html, e a solução aqui é python. A questão nem está perguntando sobre a validação do lado do servidor, está perguntando se existe uma maneira de validar grupos de caixas de seleção para verificar se pelo menos 1 está marcada.
Octavioamu