Caixas de seleção HTML desmarcadas do POST

303

Eu tenho uma carga de caixas de seleção marcadas por padrão. Meus usuários provavelmente desmarcarão algumas (se houver) das caixas de seleção e deixarão o restante marcado.

Existe alguma maneira de tornar o formulário POST as caixas de seleção que não estão marcadas, e não as que estão marcadas?

reach4thelasers
fonte

Respostas:

217

Adicione uma entrada oculta para a caixa de seleção com um ID diferente:

<input id='testName' type='checkbox' value='Yes' name='testName'>
<input id='testNameHidden' type='hidden' value='No' name='testName'>

Antes de enviar o formulário, desative a entrada oculta com base na condição verificada:

if(document.getElementById("testName").checked) {
    document.getElementById('testNameHidden').disabled = true;
}
vishnu
fonte
58
Se você optar por uma solução baseada em marcação como essa, provavelmente é melhor colocar a entrada oculta primeiro, de acordo com muitas outras respostas. Se você estiver usando PHP, poderá acabar com a dependência de javascript, porque apenas o último valor será usado.
Ben
12
gamov, você está enganado, os rótulos são anexados às entradas com base no atributo id, não no atributo do nome da entrada
Justin Emery
14
Difícil de acreditar que os autores o projetaram dessa maneira. Por que não enviar todos os campos de entrada com algum valor padrão para os que não foram verificados :( Seria uma solução muito mais clara do que ter que implementar alguns campos ocultos "hack". Deve ter ficado claro que isso será necessário e eles tiveram que ver que com antecedência.
Srneczek
34
Isso parece tão hacky.
EralpB
65
Eu sou o único que pensa que o design subjacente do checkboxelemento é terrível? Eles são um controle binário, eles devem enviar valores binários.
alexw
474

A solução que eu mais gostei até agora é colocar uma entrada oculta com o mesmo nome da caixa de seleção que pode não estar marcada. Eu acho que funciona para que, se a caixa de seleção não estiver marcada, a entrada oculta ainda for bem-sucedida e enviada ao servidor, mas se a caixa de seleção estiver marcada, ela substituirá a entrada oculta antes dela. Dessa forma, você não precisa acompanhar quais valores nos dados publicados devem vir das caixas de seleção.

<form>
  <input type='hidden' value='0' name='selfdestruct'>
  <input type='checkbox' value='1' name='selfdestruct'>
</form>
Sam
fonte
3
Agora que reli a pergunta, parece que isso não era exatamente o que você queria. No entanto, cheguei a essa pergunta quando tentava descobrir essa resposta para que talvez fosse útil para outra pessoa.
Sam
2
O .NET é diferente. Em vez disso, consulte stackoverflow.com/questions/7600817/…
KCD
121
Observe que, se você marcar a caixa, o navegador enviará os valores oculto e de caixa de seleção. Essa solução depende do tratamento da variável de postagem pelo servidor com esses 2 valores. Se ele usar apenas o último valor (por exemplo, PHP), seu código funcionará conforme o esperado. No entanto, alguns servidores lidam com isso de maneira diferente. Alguns escolhem o primeiro valor, enquanto outros colocam os dois valores em uma lista / matriz.
Michael Ekoka
1
Esta resposta baseia-se no pressuposto de que você pode retransmitir apenas uma das duas entradas com nomes iguais que serão enviadas ao servidor - não entendo por que isso recebeu tantos votos positivos?
Muleskinner
7
@ sam não sabe de onde você tirou essa idéia? Quando dois ou mais controles são nomeados iguais, ambos serão enviados para o servidor no envio (para caixas de seleção, no entanto, apenas se marcada) - a maneira como eles são tratados no servidor depende da implementação do lado do servidor. Se você não acredita em mim, pode ver por si mesmo monitorando o tráfego usando uma ferramenta como um violinista.
Muleskinner
75

Eu o resolvi usando JavaScript vanilla:

<input type="hidden" name="checkboxName" value="0"><input type="checkbox" onclick="this.previousSibling.value=1-this.previousSibling.value">

Cuidado para não haver espaços ou quebras de linha entre esses dois elementos de entrada!

Você pode usar this.previousSibling.previousSiblingpara obter elementos "superiores".

Com o PHP, você pode verificar o campo oculto nomeado para 0 (não definido) ou 1 (definido).

Marcel Ennix
fonte
Por que você não pode ter espaços ou quebras de linha entre os dois elementos?
Michael Potter
@ MichaelPotter: this.previousSibling terá um espaço em branco como irmão, portanto não funcionará.
Marcel Ennix
4
Oh, isso é PERFEITO! Ele resolve o problema de postar vários conjuntos de campos com campos nomeados duplicados lá dentro. Nenhuma das outras soluções faz isso. Usando o método de Marcel, seus campos publicados terão matrizes de comprimento igual. Portanto, este cenário: <fieldset name='fs1'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset> <fieldset name='fs2'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset>* Suponha que houvesse novas linhas lá. Eles não parecem estar trabalhando em blocos de códigos de mini-marcação
Brian Layman
1
Essa deve ser a resposta aceita. Ele funciona com matrizes (ex / name = "sopa []")
jdavid05
2
Você pode usar em previousElementSiblingvez de previousSibling. É suportado em quase todos os lugares e ignora nós de texto.
MarSoft 26/06/19
23

Meu favorito pessoal é adicionar um campo oculto com o mesmo nome que será usado se a caixa de seleção estiver desmarcada. Mas a solução não é tão fácil quanto parece.

Se você adicionar este código:

<form>
  <input type='hidden' value='0' name='selfdestruct'>
  <input type='checkbox' value='1' name='selfdestruct'>
</form>

O navegador realmente não se importa com o que você faz aqui. O navegador enviará os dois parâmetros para o servidor, e o servidor precisará decidir o que fazer com eles.

O PHP, por exemplo, usa o último valor como aquele a ser usado (consulte: Posição autorizada das chaves de consulta HTTP GET duplicadas )

Mas outros sistemas com os quais trabalhei (baseados em Java) fazem o caminho inverso - eles oferecem apenas o primeiro valor. Em vez disso, o .NET fornecerá uma matriz com os dois elementos

Vou tentar testar isso com node.js, Python e Perl em algum momento.

SimonSimCity
fonte
2
ruby e node.js terão o último valor de qualquer campo de formulário duplicado. Os métodos auxiliares do Ruby on Rails constroem caixas de seleção dessa maneira por esse motivo.
Nzifnab
7
Para completar, isso é baseado em um ataque chamado HTTP Parameter Pollution e foi analisado pela OWASP: owasp.org/images/b/ba/AppsecEU09_CarettoniDiPaola_v0.8.pdf (página 9), onde você pode encontrar uma lista de 20 sistemas e veja como eles lidam com isso.
precisa saber é o seguinte
1
Java Servlets dá-lhe tudo, desde que você chamarequest.getParameterValues
mauhiz
20

Uma técnica comum para contornar isso é carregar uma variável oculta junto com cada caixa de seleção.

<input type="checkbox" name="mycheckbox" />
<input type="hidden" name="mycheckbox.hidden"/>

No lado do servidor, primeiro detectamos a lista de variáveis ​​ocultas e, para cada variável oculta, tentamos ver se a entrada da caixa de seleção correspondente é enviada nos dados do formulário ou não.

O algoritmo do lado do servidor provavelmente se pareceria com:

for input in form data such that input.name endswith .hidden
  checkboxName = input.name.rstrip('.hidden')
  if chceckbName is not in form, user has unchecked this checkbox

O exposto acima não responde exatamente à pergunta, mas fornece um meio alternativo de obter funcionalidade semelhante.

Shailesh Kumar
fonte
20

você não precisa criar um campo oculto para todas as caixas de seleção, basta copiar meu código. ele mudará o valor da caixa de seleção, se não estiver marcado, o valueatribuirá 0e, se a caixa de seleção estiver marcada, atribuirá valueao1

$("form").submit(function () {

    var this_master = $(this);

    this_master.find('input[type="checkbox"]').each( function () {
        var checkbox_this = $(this);


        if( checkbox_this.is(":checked") == true ) {
            checkbox_this.attr('value','1');
        } else {
            checkbox_this.prop('checked',true);
            //DONT' ITS JUST CHECK THE CHECKBOX TO SUBMIT FORM DATA    
            checkbox_this.attr('value','0');
        }
    })
})
Rameez SOOMRO
fonte
1
Essa solução funciona bem e mais elegante do que poluir o Dom com campos ocultos.
Prasad Paranjape
9
Isso faz com que a caixa seja marcada temporariamente enquanto o formulário é enviado. Isso é confuso (na melhor das hipóteses) para o usuário.
Mark Fraser
12
$('input[type=checkbox]').on("change",function(){
    var target = $(this).parent().find('input[type=hidden]').val();
    if(target == 0)
    {
        target = 1;
    }
    else
    {
        target = 0;
    }
    $(this).parent().find('input[type=hidden]').val(target);
});

<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>

Se você deixar de fora o nome da caixa de seleção, ela não será aprovada. Somente a matriz test_checkbox.

Jeremy
fonte
1
Solução muito boa, mas no meu caso o live () não funciona, então usei o método (): $ ('input [type = checkbox]'). On ("change", function () {...}) ;
Massa
4
LIVE é obsoleto. Não o use mais nas respostas no fluxo de pilha. Amém.
Ismael
Esta resposta é realmente a melhor. Está funcionando como esperado. Mesmo para caixa de seleção de grupo.
Alemoh Rapheal Baja
11

Você pode fazer algum Javascript no evento de envio do formulário. É tudo o que você pode fazer, porém, não há como convencer os navegadores a fazer isso sozinhos. Isso também significa que seu formulário será quebrado para usuários sem Javascript. Melhor é saber no servidor quais caixas de seleção existem, para que você possa deduzir que aqueles ausentes dos valores do formulário postado ( $_POSTem PHP) estão desmarcados.

Bart van Heukelom
fonte
2
desde o PHP 4.1 você também pode usar $ _REQUEST php.net/manual/en/reserved.variables.request.php
Karl Adler
$_REQUESTé uma boa prática, pois permite a reutilização de algum código se o seu script suportar os dois métodos.
nullability
9

Na verdade, eu faria o seguinte.

Tenha meu campo de entrada oculto com o mesmo nome na entrada da caixa de seleção

<input type="hidden" name="checkbox_name[]" value="0" />
<input type="checkbox" name="checkbox_name[]" value="1" />

e então, quando eu postar, removo primeiro os valores duplicados capturados na matriz $ _POST, depois que exibem cada um dos valores exclusivos.

  $posted = array_unique($_POST['checkbox_name']);
  foreach($posted as $value){
    print $value;
  }

Eu recebi isso de um post remover valores duplicados da matriz

desw
fonte
Qual é o objetivo do [] no valor do campo de nome?
Michael Potter
@MichaelPotter É assim que, quando o post é enviado ao PHP, ele lê o nome `checkbox_name []
Twister1002
@ Twister1002, acho que você descreveu a finalidade do atributo name, não a finalidade de adicionar [] ao nome. Eu fiz uma pesquisa na web e parece que algumas pessoas fazem isso com os nomes: groupname [elementname] para agrupar os campos, mas não encontrei uma explicação para [] vazio.
Michael Potter
1
@ MichaelPotter Desculpe, pensei ter terminado essa declaração. Mas aparentemente não. Deixe-me refazer isso. Quando é enviado para php, o processador PHP o lê como uma matriz. Portanto, com cada nome, checkbox_name[]cada valor será inserido em uma matriz, que você poderá extrair. Ex: $_POST['checkbox_name'][0]e assim por diante com o incremento de quantos campos tinham o mesmo nome. Outro exemplo é se você tiver três campos nomeados, field_name[]poderá obter o segundo valor defield_name like $_POST['field_name'][1]. Seu objetivo pode ser incrível se você tiver vários campos com o mesmo nome.
precisa saber é o seguinte
8

"Eu segui a abordagem do servidor. Parece funcionar bem - obrigado. - reach4thelasers 01/12/2009 às 15:19" Gostaria de recomendá-lo ao proprietário. Como citado: a solução javascript depende de como o manipulador do servidor (não o verifiquei)

tal como

if(!isset($_POST["checkbox"]) or empty($_POST["checkbox"])) $_POST["checkbox"]="something";
N Zhang
fonte
8

Sei que esta pergunta tem 3 anos, mas encontrei uma solução que acho que funciona muito bem.

Você pode verificar se a variável $ _POST está atribuída e salvá-la em uma variável.

$value = isset($_POST['checkboxname'] ? 'YES' : 'NO';

a função isset () verifica se a variável $ _POST está atribuída. Por lógica, se não estiver atribuído, a caixa de seleção não estará marcada.

Riley Stadel
fonte
Isso é muito melhor, pois a resposta mais popular é uma solução terrível para os leitores de tela.
Kevin Waterson
7

A maioria das respostas aqui requer o uso de JavaScript ou controles de entrada duplicados. Às vezes, isso precisa ser tratado inteiramente no lado do servidor.

Acredito que a chave (pretendida) para resolver esse problema comum é o controle de entrada de envio do formulário.

Para interpretar e manipular valores desmarcados para caixas de seleção com êxito, você precisa ter o seguinte conhecimento:

  1. Os nomes das caixas de seleção
  2. O nome do elemento de entrada de envio do formulário

Ao verificar se o formulário foi enviado (um valor é atribuído ao elemento de entrada do envio), qualquer valor desmarcado da caixa de seleção pode ser assumido .

Por exemplo:

<form name="form" method="post">
  <input name="value1" type="checkbox" value="1">Checkbox One<br/>
  <input name="value2" type="checkbox" value="1" checked="checked">Checkbox Two<br/>
  <input name="value3" type="checkbox" value="1">Checkbox Three<br/>
  <input name="submit" type="submit" value="Submit">
</form>

Ao usar o PHP, é bastante trivial detectar quais caixas de seleção foram marcadas.

<?php

$checkboxNames = array('value1', 'value2', 'value3');

// Persisted (previous) checkbox state may be loaded 
// from storage, such as the user's session or a database.
$checkboxesThatAreChecked = array(); 

// Only process if the form was actually submitted.
// This provides an opportunity to update the user's 
// session data, or to persist the new state of the data.

if (!empty($_POST['submit'])) {
    foreach ($checkboxNames as $checkboxName) {
        if (!empty($_POST[$checkboxName])) {
            $checkboxesThatAreChecked[] = $checkboxName;
        }
    }
    // The new state of the checkboxes can be persisted 
    // in session or database by inspecting the values 
    // in $checkboxesThatAreChecked.
    print_r($checkboxesThatAreChecked);
}

?>

Os dados iniciais podem ser carregados em cada carregamento da página, mas só devem ser modificados se o formulário foi enviado. Como os nomes das caixas de seleção são conhecidos antecipadamente, eles podem ser percorridos e inspecionados individualmente, para que a ausência de seus valores individuais indique que não estão marcados.

Werner
fonte
6

Eu tentei a versão de Sam primeiro. Boa ideia, mas faz com que haja vários elementos no formulário com o mesmo nome. Se você usar qualquer javascript que encontre elementos com base no nome, ele retornará uma matriz de elementos.

Eu elaborei a idéia de Shailesh em PHP, funciona para mim. Aqui está o meu código:

/ * Exclua os campos '.hidden' se o original estiver presente, use o valor '.hidden' se não estiver. * /
foreach ($ _POST ['frmmain'] como $ field_name => $ value)
{
    // Veja apenas os elementos que terminam com '.hidden'
    if (! substr ($ field_name, -strlen ('. hidden'))) {
        pausa;
    }

    // pega o nome sem '.hidden'
    $ real_name = substr ($ chave, strlen ($ field_name) - strlen ('. hidden'));

    // Crie um campo original 'falso' com o valor em '.hidden' se um original não existir
    if (! array_key_exists ($ real_name, $ POST_copy)) {
        $ _POST [$ real_name] = $ valor;
    }

    // Exclua o elemento '.hidden'
    não definido ($ _ POST [$ field_name]);
}
Wouter
fonte
6

Também gosto da solução de que você acabou de postar um campo de entrada extra, usar JavaScript parece um pouco hacky para mim.

Dependendo do que você usa para o back-end, depende de qual entrada será a primeira.

Para um servidor back-end em que a primeira ocorrência é usada (JSP), faça o seguinte.

  <input type="checkbox" value="1" name="checkbox_1"/>
  <input type="hidden" value="0" name="checkbox_1"/>


Para um servidor backend em que a última ocorrência é usada (PHP, Rails), faça o seguinte.

  <input type="hidden" value="0" name="checkbox_1"/>
  <input type="checkbox" value="1" name="checkbox_1"/>


Para um servidor backend em que todas as ocorrências são armazenadas em um tipo de dados da lista ( [], array). (Python / Zope)

Você pode postar na ordem que quiser, basta tentar obter o valor da entrada com o checkboxatributo type Portanto, o primeiro índice da lista se a caixa de seleção estiver antes do elemento oculto e o último índice se a caixa de seleção estiver após o elemento oculto.


Para um servidor em que todas as ocorrências são concatenadas com uma vírgula (ASP.NET / IIS), você precisará (dividir / explodir) a cadeia de caracteres usando uma vírgula como delimitador para criar um tipo de dados da lista. ( [])

Agora você pode tentar pegar o primeiro índice da lista se a caixa de seleção estiver antes do elemento oculto e pegar o último índice se a caixa de seleção estiver após o elemento oculto.

Manipulação de parâmetros de back-end

fonte da imagem

TarranJones
fonte
6

Eu uso esse bloco de jQuery, que adicionará uma entrada oculta no momento do envio a todas as caixas de seleção desmarcadas. Isso garantirá que você sempre obtenha um valor enviado para cada caixa de seleção, sempre, sem sobrecarregar sua marcação e correndo o risco de esquecer de fazê-lo em uma caixa de seleção que você adicionar posteriormente. Também é independente de qualquer pilha de back-end (PHP, Ruby, etc.) que você está usando.

// Add an event listener on #form's submit action...
$("#form").submit(
    function() {

        // For each unchecked checkbox on the form...
        $(this).find($("input:checkbox:not(:checked)")).each(

            // Create a hidden field with the same name as the checkbox and a value of 0
            // You could just as easily use "off", "false", or whatever you want to get
            // when the checkbox is empty.
            function(index) {
                var input = $('<input />');
                input.attr('type', 'hidden');
                input.attr('name', $(this).attr("name")); // Same name as the checkbox
                input.attr('value', "0"); // or 'off', 'false', 'no', whatever

                // append it to the form the checkbox is in just as it's being submitted
                var form = $(this)[0].form;
                $(form).append(input);

            }   // end function inside each()
        );      // end each() argument list

        return true;    // Don't abort the form submit

    }   // end function inside submit()
);      // end submit() argument list
Matt Holden
fonte
5

Você também pode interceptar o evento form.submit e reverter a verificação antes de enviar

$('form').submit(function(event){
    $('input[type=checkbox]').prop('checked', function(index, value){
        return !value;
    });
});
Jimchao
fonte
4

Vejo que essa pergunta é antiga e tem muitas respostas, mas darei meu centavo de qualquer maneira. Meu voto é para a solução javascript no evento 'submit' do formulário, como alguns apontaram. Sem duplicar as entradas (especialmente se você tiver nomes longos e atributos com código php misturado com html), sem problemas no lado do servidor (que exigiria conhecer todos os nomes de campos e verificá-los um por um), basta buscar todos os itens não verificados , atribua a eles um valor 0 (ou o que você precisar para indicar um status 'não verificado') e altere o atributo 'verificado' para verdadeiro

    $('form').submit(function(e){
    var b = $("input:checkbox:not(:checked)");
    $(b).each(function () {
        $(this).val(0); //Set whatever value you need for 'not checked'
        $(this).attr("checked", true);
    });
    return true;
});

Dessa forma, você terá uma matriz $ _POST como esta:

Array
(
            [field1] => 1
            [field2] => 0
)
MarcoSpada
fonte
Não está trabalhando ao meu lado. Tentando fazer isso, mas ainda não publicando todas as caixas de seleção. [código] $ ("# entrada do filtro"). change (function (e) {console.log ('sublmit'); var b = $ ("input: caixa de seleção: não (: marcada)"); $ (b) .each (function () {$ (this) .val (2); $ (this) .attr ("marcado", true);}); $ ("# filter"). submit ();}); [/ code]
lio
Fiz o truque para mim. A única desvantagem no formulário enviar todas as caixas de seleção foi marcada. Isso pode ser confuso para um usuário, mas como a página é recarregada após o envio do formulário, acho que é um problema menor.
Oksana Romaniv
Como Oksana disse, marque todas as caixas de seleção, incluindo as caixas de seleção necessárias, que o usuário não selecionou para permitir que o formulário fosse enviado sem que o usuário concordasse com alguma condição.
bskool
4
$('form').submit(function () {
    $(this).find('input[type="checkbox"]').each( function () {
        var checkbox = $(this);
        if( checkbox.is(':checked')) {
            checkbox.attr('value','1');
        } else {
            checkbox.after().append(checkbox.clone().attr({type:'hidden', value:0}));
            checkbox.prop('disabled', true);
        }
    })
});
Sajjad Shirazy
fonte
1
Isso funcionou para mim. Em vez de usar .submit, você usaria .click. Em seguida, remova a parte que desativa as caixas de seleção. Depois disso, funciona perfeitamente.
cgrouge
1
Melhor resposta: não é necessário adicionar outra entrada oculta para cada uma
Sky
3

O que eu fiz foi um pouco diferente. Primeiro, alterei os valores de todas as caixas de seleção desmarcadas. Para "0", selecione todos eles, para que o valor seja enviado.

function checkboxvalues(){
  $("#checkbox-container input:checkbox").each(function({ 
    if($(this).prop("checked")!=true){
      $(this).val("0");
      $(this).prop("checked", true);
    }
  });
}

Seborreia
fonte
A resposta é boa, mas quero saber se é diferente da resposta de @Rameez SOOMRO?
Imran Qamer
Resultado final semelhante, mas dessa maneira você não altera o valor das caixas de seleção marcadas.
Seborreia
2

Eu preferiria agrupar o $ _POST

if (!$_POST['checkboxname']) !$_POST['checkboxname'] = 0;

se importa, se o POST não tiver o valor 'checkboxname', ele foi desmarcado, então, atribua um valor.

você pode criar uma matriz de seus valores de ckeckbox e criar uma função que verifique se os valores existem, caso contrário, importa que estejam desmarcados e você pode atribuir um valor

Felipe Gonzalez
fonte
1

O exemplo de ações do Ajax é (': verificado') usado jQuery em vez de .val ();

            var params = {
                books: $('input#users').is(':checked'),
                news : $('input#news').is(':checked'),
                magazine : $('input#magazine').is(':checked')
            };

os parâmetros obterão valor em VERDADEIRO OU FALSO.

Mehmet Ali Uysal
fonte
1

As caixas de seleção geralmente representam dados binários armazenados no banco de dados como valores Sim / Não, S / N ou 1/0. As caixas de seleção HTML têm natureza ruim para enviar valor ao servidor somente se a caixa de seleção estiver marcada! Isso significa que o script do servidor em outro site deve saber com antecedência quais são todas as caixas de seleção possíveis na página da Web para poder armazenar valores positivos (marcados) ou negativos (não marcados). Na verdade, apenas valores negativos são problemáticos (quando o usuário desmarca o valor previamente verificado (pré) - como o servidor pode saber disso quando nada é enviado se não souber antecipadamente que esse nome deve ser enviado). Se você possui um script do lado do servidor que cria dinamicamente o script UPDATE, há um problema porque você não sabe quais caixas de seleção devem ser recebidas para definir o valor Y para as verificadas e o valor N para as desmarcadas (não recebidas).

Como eu armazeno os valores 'Y' e 'N' no meu banco de dados e os represento por meio de caixas de seleção marcadas e desmarcadas na página, adicionei um campo oculto para cada valor (caixa de seleção) com os valores 'Y' e 'N' e utilizo as caixas de seleção apenas para visual representação e use a função JavaScript simples check () para definir o valor de se de acordo com a seleção.

<input type="hidden" id="N1" name="N1" value="Y" />
<input type="checkbox"<?php if($N1==='Y') echo ' checked="checked"'; ?> onclick="check(this);" />
<label for="N1">Checkbox #1</label>

use um ouvinte JavaScript onclick e chame a função check () para cada caixa de seleção na minha página da web:

function check(me)
{
  if(me.checked)
  {
    me.previousSibling.previousSibling.value='Y';
  }
  else
  {
    me.previousSibling.previousSibling.value='N';
  }
}

Dessa forma, os valores 'Y' ou 'N' são sempre enviados para o script do lado do servidor, ele sabe quais são os campos que devem ser atualizados e não há necessidade de converter o valor do checbox "on" em 'Y' ou a caixa de seleção não recebida em 'N '

NOTA: espaço em branco ou nova linha também é um irmão, então aqui eu preciso de .previousSibling.previousSibling.value. Se não houver espaço entre, apenas .previousSibling.value


Você não precisa adicionar explicitamente o ouvinte do onclick como antes, pode usar a biblioteca jQuery para adicionar dinamicamente o ouvinte de cliques com a função para alterar o valor de todas as caixas de seleção da sua página:

$('input[type=checkbox]').click(function()
{
  if(this.checked)
  {
    $(this).prev().val('Y');
  }
  else
  {
    $(this).prev().val('N');
  }
});
sbrbot
fonte
1

Todas as respostas são ótimas, mas se você tiver várias caixas de seleção em um formulário com o mesmo nome e desejar postar o status de cada caixa de seleção. Em seguida, resolvi esse problema colocando um campo oculto com a caixa de seleção (nome relacionado ao que eu quero).

<input type="hidden" class="checkbox_handler" name="is_admin[]" value="0" />
<input type="checkbox" name="is_admin_ck[]" value="1" />

em seguida, controle o status da alteração da caixa de seleção abaixo do código jquery:

$(documen).on("change", "input[type='checkbox']", function() {
    var checkbox_val = ( this.checked ) ? 1 : 0;
    $(this).siblings('input.checkbox_handler').val(checkbox_val);
});

agora, ao alterar qualquer caixa de seleção, ele mudará o valor do campo oculto relacionado. E no servidor você pode procurar apenas campos ocultos em vez de caixas de seleção.

Espero que isso ajude alguém a ter esse tipo de problema. torcer :)

Imran Khan
fonte
1

O problema com as caixas de seleção é que, se não estiverem marcadas, não serão postadas no seu formulário. Se você marcar uma caixa de seleção e postar um formulário, receberá o valor da caixa de seleção na variável $ _POST que pode ser usada para processar um formulário, se estiver desmarcada, nenhum valor será adicionado à variável $ _POST.

No PHP, você normalmente solucionaria esse problema realizando uma verificação isset () no elemento da caixa de seleção. Se o elemento que você espera não estiver definido na variável $ _POST, sabemos que a caixa de seleção não está marcada e o valor pode ser falso.

if(!isset($_POST['checkbox1']))
{
     $checkboxValue = false;
} else {
     $checkboxValue = $_POST['checkbox1'];
}

Mas se você criou um formulário dinâmico, nem sempre saberá o atributo name de suas caixas de seleção; se não souber o nome da caixa de seleção, não poderá usar a função isset para verificar se este foi enviado com a variável $ _POST.

Daniel Galecki
fonte
1
function SubmitCheckBox(obj) {
     obj.value   = obj.checked ? "on" : "off";
     obj.checked = true;
     return obj.form.submit();
}

<input type=checkbox name="foo" onChange="return SubmitCheckBox(this);">
ledav.net
fonte
0

Existe uma solução melhor. Primeiro, forneça o atributo name apenas às caixas de seleção marcadas. Em seguida, no clique submit, através de um JavaScript, functionvocê marca todas as caixas desmarcadas. Então, quando você submitapenas aqueles serão recuperados form collectionnaqueles que têm namepropriedades.

  //removing name attribute from all checked checkboxes
                  var a = $('input:checkbox:checked');
                   $(a).each(function () {
                       $(this).removeAttr("name");        
                   });

   // checking all unchecked checkboxes
                   var b = $("input:checkbox:not(:checked)");
                   $(b).each(function () {
                       $(this).attr("checked", true);
                   });

Vantagem: Não há necessidade de criar caixas ocultas extras e manipulá-las.

Gyanesh Gouraw
fonte
0

O @cpburnz acertou, mas com muito código, aqui está a mesma idéia usando menos código:

JS:

// jQuery OnLoad
$(function(){
    // Listen to input type checkbox on change event
    $("input[type=checkbox]").change(function(){
        $(this).parent().find('input[type=hidden]').val((this.checked)?1:0);
    });
});

HTML (observe o nome do campo usando um nome de matriz):

<div>
    <input type="checkbox" checked="checked">
    <input type="hidden" name="field_name[34]" value="1"/>
</div>
<div>
    <input type="checkbox">
    <input type="hidden" name="field_name[35]" value="0"/>
</div>
<div>

E para PHP:

<div>
    <input type="checkbox"<?=($boolean)?' checked="checked"':''?>>
    <input type="hidden" name="field_name[<?=$item_id?>]" value="<?=($boolean)?1:0?>"/>
</div>
Rodrigo Polo
fonte
0

Versão jQuery da resposta de @ vishnu.

if($('#testName').is(":checked")){
    $('#testNameHidden').prop('disabled', true);
}

Se você estiver usando o jQuery 1.5 ou abaixo, use a função .attr () em vez de .prop ()

0x1ad2
fonte
0

Esta solução é inspirada na de @ desw.

Se seus nomes de entrada estiverem no "estilo de formulário", você perderá a associação do índice de matriz com os valores da sua caixa de cheques assim que uma caixa de verificação for marcada, incrementando essa "dissociação" em uma unidade cada vez que uma caixa de cheques for marcada. Pode ser o caso de um formulário para inserir algo como funcionários compostos por alguns campos, por exemplo:

<input type="text" name="employee[]" />
<input type="hidden" name="isSingle[] value="no" />
<input type="checkbox" name="isSingle[] value="yes" />

Caso você insira três funcionários ao mesmo tempo e o primeiro e o segundo sejam únicos, você terminará com uma isSinglematriz de 5 elementos , para que não seja possível iterar de uma só vez pelas três matrizes para, por exemplo, , insira funcionários em um banco de dados.

Você pode superar isso com algum pós-processamento fácil de matriz. Estou usando PHP no lado do servidor e fiz isso:

$j = 0;
$areSingles = $_POST['isSingle'];
foreach($areSingles as $isSingle){
  if($isSingle=='yes'){
    unset($areSingles[$j-1]);
  }
  $j++;
}
$areSingles = array_values($areSingles);
Pere
fonte
0

Portanto, esta solução é um exagero para esta pergunta, mas me ajudou quando tive a mesma caixa de seleção que ocorreu várias vezes para linhas diferentes em uma tabela. Eu precisava conhecer a linha que a caixa de seleção representava e também o estado da caixa de seleção (marcada / desmarcada).

O que fiz foi retirar o atributo name das minhas entradas da caixa de seleção, dar a elas a mesma classe e criar uma entrada oculta que contivesse o equivalente JSON dos dados.

HTML

 <table id="permissions-table">
    <tr>
	<td>
	    <input type="checkbox" class="has-permission-cb" value="Jim">
	    <input type="checkbox" class="has-permission-cb" value="Bob">
	    <input type="checkbox" class="has-permission-cb" value="Suzy">
	</td>
    </tr>
 </table>
 <input type="hidden" id="has-permissions-values" name="has-permissions-values" value="">

Javascript para executar no envio do formulário

var perms = {};
$(".has-permission-checkbox").each(function(){
  var userName = this.value;
  var val = ($(this).prop("checked")) ? 1 : 0
  perms[userName] = {"hasPermission" : val};
});
$("#has-permissions-values").val(JSON.stringify(perms));

A string json será passada com o formulário como $ _POST ["has-permission-values"]. No PHP, decodifique a string em uma matriz e você terá uma matriz associativa que possui cada linha e o valor verdadeiro / falso para cada caixa de seleção correspondente. É muito fácil percorrer e comparar com os valores atuais do banco de dados.

Tmac
fonte