As entradas da caixa de seleção somente publicam dados se estiverem marcadas?

184

É um comportamento padrão para os navegadores enviarem apenas os dados do valor de entrada da caixa de seleção se estiverem marcados no envio do formulário?

E se nenhum dado de valor for fornecido, o valor padrão está sempre "ativado"?

Supondo que o que foi dito acima esteja correto, esse comportamento é consistente em todos os navegadores?

Marca
fonte

Respostas:

187

Sim, o comportamento padrão é que o valor será enviado apenas se a caixa de seleção estiver marcada. Isso normalmente significa que você precisa lembrar de quais caixas de seleção espera no lado do servidor, pois nem todos os dados retornam do formulário.

O valor padrão é sempre "ativado", isso deve ser consistente entre os navegadores.

Isso é coberto na recomendação HTML 4 do W3C :

Caixas de seleção (e botões de opção) são botões liga / desliga que podem ser alternados pelo usuário. Uma opção está "ligada" quando o atributo verificado do elemento de controle está definido. Quando um formulário é enviado, apenas os controles da caixa de seleção "ativado" podem se tornar bem-sucedidos.

John C
fonte
18
Infelizmente, essa é uma verdade dolorosa, apenas as caixas de seleção marcadas são enviadas ao servidor, e não as desmarcadas. Se você souber com antecedência quais caixas de seleção estão na página, não será problema no script do lado do servidor gerenciá-las. O problema é quando você não sabe disso com antecedência - caixas de seleção criadas dinamicamente na página, dependendo de alguma lógica comercial. Em seguida, você deve fazer truques e usar campos de entrada paralelos hiden para essas caixas de seleção e preenchê-los com JavaScript.
Sbrbot
A chave para criar um validador consistente com "controles mal-sucedidos permitidos (ou seja, tipo =" caixa de seleção ") é designar esses controles de formulário como transitórios . Quando não tiverem êxito, altere dinamicamente o desinfetante e o validador de acordo.
Anthony Rutledge
3
Solução alternativa: use <select>com duas opções one off:-)
andy
83

Em HTML, cada <input />elemento é associado a um único par de nomes e valores (mas não exclusivo). Este par é enviado na solicitação subseqüente (neste caso, um corpo de solicitação POST) somente se a <input />"for bem-sucedida".

Portanto, se você tiver essas entradas no seu <form>DOM:

<input type="text"     name="one"   value="foo"                        />
<input type="text"     name="two"   value="bar"    disabled="disabled" />
<input type="text"     name="three" value="first"                      />
<input type="text"     name="three" value="second"                     />

<input type="checkbox" name="four"  value="baz"                        />
<input type="checkbox" name="five"  value="baz"    checked="checked"   />
<input type="checkbox" name="six"   value="qux"    checked="checked" disabled="disabled" />
<input type="checkbox" name=""      value="seven"  checked="checked"   />

<input type="radio"    name="eight" value="corge"                      />
<input type="radio"    name="eight" value="grault" checked="checked"   />
<input type="radio"    name="eight" value="garply"                     />

Irá gerar estes pares nome + valor que serão enviados ao servidor:

one=foo
three=first
three=second
five=baz
eight=grault

Notar que:

  • twoe sixforam excluídos porque tinham o disabledatributo definido.
  • three foi enviado duas vezes porque tinha duas entradas válidas com o mesmo nome.
  • fournão foi enviado porque é um checkboxque não foichecked
  • sixnão foi enviado, apesar de ser checkedporque o disabledatributo tem uma precedência mais alta.
  • sevennão possui um name=""atributo enviado, portanto não é enviado.

Com relação à sua pergunta: você pode ver que uma caixa de seleção que não está marcada, portanto, não terá seu par de nome + valor enviado ao servidor - mas outras entradas que compartilham o mesmo nome serão enviadas com ele.

Estruturas como o ASP.NET MVC contornam isso (sub-repticiamente) emparelhando cada checkboxentrada com uma hiddenentrada no HTML renderizado, da seguinte maneira:

@Html.CheckBoxFor( m => m.SomeBooleanProperty )

Renderiza:

<input type="checkbox" name="SomeBooleanProperty" value="true" />
<input type="hidden"   name="SomeBooleanProperty" value="false" />

Se o usuário não marcar a caixa de seleção, o seguinte será enviado ao servidor:

SomeBooleanProperty=false

Se o usuário marcar a caixa de seleção, os dois serão enviados:

SomeBooleanProperty=true
SomeBooleanProperty=false

Mas o servidor ignorará a =falseversão porque a vê =truee, se não a vir , =truepode determinar que a caixa de seleção foi renderizada e que o usuário não a verificou - em oposição às SomeBooleanPropertyentradas que não foram renderizadas.

Dai
fonte
Vale ressaltar que se você tiver vários campos, como na caixa de texto extra oculta, o back-end receberá uma matriz de valores.
Salami
Ele recebe apenas uma matriz se você usar []no final do nome da entrada, o comportamento padrão é enviar apenas o último elemento com esse nome, desde que a entrada oculta esteja antes da caixa de seleção, ela funcionará.
precisa saber é o seguinte
Ao ter dois campos com o mesmo nome (campo oculto + campo da caixa de seleção) e marcar a caixa de seleção, o valor da postagem é uma sequência de valores separados por vírgula, ou seja. algo como "0,1"
5/16
1
@beeglebug O que você está descrevendo é como o PHP lida com nomes e valores, o []sufixo não faz parte da especificação HTML e os navegadores não o tratam especialmente. Sem o []PHP, apenas será permitido o acesso a um único valor (o último valor) em vez de todos os valores.
DaiJul
1
O uso da propriedade oculta antes da caixa de seleção está funcionando para mim em todos os navegadores que testei usando GET e POST com PHP. Quando eu o colocava após o controle da caixa de seleção, ele sempre tornava o resultado falso.
adrianwadey
16

Se a caixa de seleção não estiver marcada, ela não contribuirá para os dados enviados no envio do formulário.

A seção HTML5 4.10.22.4 A construção do conjunto de dados do formulário descreve a maneira como os dados do formulário são construídos:

Se alguma das seguintes condições for atendida, pule essas subetapas para este elemento: [...]

O elemento field é um elemento de entrada cujo atributo type está no estado Checkbox e cuja verificação é falsa.

e o valor padrão oné especificado se valueestiver ausente:

Caso contrário, se o elemento do campo for um elemento de entrada cujo atributo type esteja no estado Checkbox ou no botão Botão de opção, execute estas subetapas aninhadas adicionais:

Se o elemento do campo tiver um atributo value especificado, permita que value seja o valor desse atributo; caso contrário, deixe o valor ser a sequência "on".

Assim, as caixas de seleção desmarcadas são ignoradas durante a construção dos dados do formulário.

Um comportamento semelhante é necessário no HTML4 . É razoável esperar esse comportamento de todos os navegadores compatíveis.

Adam Zalcman
fonte
10

As caixas de seleção estão lançando valor 'on' se e somente se a caixa de seleção estiver marcada. Em vez de capturar o valor da caixa de seleção, você pode usar entradas ocultas

JS :

var chk = $('input[type="checkbox"]');
    chk.each(function(){
        var v = $(this).attr('checked') == 'checked'?1:0;
        $(this).after('<input type="hidden" name="'+$(this).attr('rel')+'" value="'+v+'" />');
    });

chk.change(function(){ 
        var v = $(this).is(':checked')?1:0;
        $(this).next('input[type="hidden"]').val(v);
    });

HTML :

<label>Active</label><input rel="active" type="checkbox" />
Lanister
fonte
8

É um comportamento padrão para os navegadores enviarem apenas os dados do valor de entrada da caixa de seleção se estiverem marcados após o envio do formulário?

Sim, porque, caso contrário, não haveria uma maneira sólida de determinar se a caixa de seleção estava realmente marcada ou não (se ela alterou o valor, o caso pode existir quando o valor desejado, se marcado, seria o mesmo que aquele que estava. trocado para).

E se nenhum dado de valor for fornecido, o valor padrão está sempre "ativado"?

Outras respostas confirmam que "ativado" é o padrão. No entanto, se você não estiver interessado no valor, basta usar:

if (isset($_POST['the_checkbox'])){
    // name="the_checkbox" is checked
}
Jay
fonte
7

Da especificação do HTML 4, que deve ser consistente em quase todos os navegadores:

http://www.w3.org/TR/html401/interact/forms.html#checkbox

Caixas de seleção (e botões de opção) são botões liga / desliga que podem ser alternados pelo usuário. Uma opção está "ligada" quando o atributo verificado do elemento de controle está definido. Quando um formulário é enviado, apenas os controles da caixa de seleção "ativado" podem se tornar bem-sucedidos.

Bem sucedido é definido da seguinte forma:

Um controle bem-sucedido é "válido" para envio. Todo controle bem-sucedido tem seu nome de controle emparelhado com seu valor atual como parte do conjunto de dados do formulário enviado. Um controle bem-sucedido deve ser definido dentro de um elemento FORM e deve ter um nome de controle.

Alex W
fonte
5

tipo de entrada = nome "oculto" = "is_main" value = "0"

tipo de entrada = "caixa de seleção" nome = "is_main" value = "1"

para que você possa controlar assim como eu fiz no aplicativo. se verificar, envie o valor 1 caso contrário 0

Muhammad Amir Shahzad
fonte
3

Nenhuma das respostas acima me satisfez. Eu achei a melhor solução é incluir uma entrada oculta antes de cada entrada da caixa de seleção com o mesmo nome.

<input type="hidden" name="foo[]" value="off"/>

<input type="checkbox" name="foo[]"/>

No lado do servidor, usando um pequeno algoritmo, você pode obter algo mais que o HTML deve fornecer.

function checkboxHack(array $checkbox_input): array
{
    $foo = [];
    foreach($checkbox_input as $value) {
        if($value === 'on') {
            array_pop($foo);
        }
        $foo[] = $value;
    }
    return $foo;
}

Essa será a entrada bruta

array (
    0 => 'off',
    1 => 'on',
    2 => 'off',
    3 => 'off',
    4 => 'on',
    5 => 'off',
    6 => 'on',
),

E a função retornará

array (
    0 => 'on',
    1 => 'off',
    2 => 'on',
    3 => 'on',
)  
Cobolt
fonte
1

Eu tenho uma página (formulário) que gera dinamicamente a caixa de seleção para que essas respostas tenham sido uma grande ajuda. Minha solução é muito parecida com muitas aqui, mas não posso deixar de pensar que é mais fácil de implementar.

Primeiro, coloquei uma caixa de entrada oculta alinhada com a minha caixa de seleção, ou seja,

 <td><input class = "chkhide" type="hidden" name="delete_milestone[]" value="off"/><input type="checkbox" name="delete_milestone[]"   class="chk_milestone" ></td>

Agora, se todas as checkboxesopções não estiverem selecionadas, os valores retornados pelo campo oculto estarão desativados.

Por exemplo, aqui com cinco caixas de seleção inseridas dinamicamente, forme POSTSos seguintes valores:

  'delete_milestone' => 
array (size=7)
  0 => string 'off' (length=3)
  1 => string 'off' (length=3)
  2 => string 'off' (length=3)
  3 => string 'on' (length=2)
  4 => string 'off' (length=3)
  5 => string 'on' (length=2)
  6 => string 'off' (length=3)

Isso mostra que apenas as caixas de verificação 3 e 4 são onou checked.

Em essência, o campo de entrada fictício ou oculto indica apenas que tudo está desativado, a menos que haja um "on" abaixo do índice off, que fornece o índice necessário sem uma única linha de código do lado do cliente.

.

Alexander
fonte
0

Assim como a variante ASP.NET, exceto coloque a entrada oculta com o mesmo nome antes da caixa de seleção real (com o mesmo nome). Somente os últimos valores serão enviados. Dessa forma, se uma caixa estiver marcada, seu nome e valor "ativado" serão enviados, enquanto se estiver desmarcada, o nome da entrada oculta correspondente e o valor que você desejar atribuir será enviado. No final, você obterá a matriz $ _POST para ler, com todos os elementos marcados e desmarcados, valores "on" e "false", sem chaves duplicadas. Fácil de processar em PHP.

user3124825
fonte
0

Tendo o mesmo problema com caixas de seleção desmarcadas que não serão enviadas no envio de formulários, criei outra solução que não espelhe os itens da caixa de seleção.

Obtendo todas as caixas de seleção desmarcadas com

var checkboxQueryString;

$form.find ("input[type=\"checkbox\"]:not( \":checked\")" ).each(function( i, e ) {
  checkboxQueryString += "&" + $( e ).attr( "name" ) + "=N"
});
Maugo
fonte
-2

Eu resolvi o problema com este código:

Formulário HTML

<input type="checkbox" id="is-business" name="is-business" value="off" onclick="changeValueCheckbox(this)" >
<label for="is-business">Soy empresa</label>

e a função javascript altere o formulário do valor da caixa de seleção:

//change value of checkbox element
function changeValueCheckbox(element){
   if(element.checked){
    element.value='on';
  }else{
    element.value='off';
  }
}

e o servidor verificou se a publicação de dados está "ativada" ou "desativada". Eu usei o playframework java

        final Map<String, String[]> data = request().body().asFormUrlEncoded();

        if (data.get("is-business")[0].equals('on')) {
            login.setType(new MasterValue(Login.BUSINESS_TYPE));
        } else {
            login.setType(new MasterValue(Login.USER_TYPE));
        }
Alexis, Quintero, Yonatan
fonte