como POST / enviar uma caixa de seleção de entrada que está desativada?

130

Eu tenho uma caixa de seleção que, em determinadas condições, precisa ser desativada. Acontece que o HTTP não publica entradas desativadas.

Como posso contornar isso? enviando a entrada mesmo que ela esteja desativada e mantendo a entrada desativada?

Um aprendiz
fonte
Eu acho que esta solução também ajuda aqui: stackoverflow.com/questions/12769664/...
Sergej Fomin
Eu acho que esta solução também ajuda aqui: stackoverflow.com/questions/12769664/...
Sergej Fomin

Respostas:

106

UPDATE : READONLYnão funciona em caixas de seleção

Você pode usar, disabled="disabled"mas neste momento o valor da caixa de seleção não aparecerá em POSTvalores. Uma das estratégias é adicionar um campo oculto contendo o valor da caixa de seleção no mesmo formulário e ler o valor novamente desse campo

Simplesmente mude disabledparareadonly

Francesco Laurita
fonte
7
Para torná-lo HTML válido, defina especificamente o valor de readonly como readonly, ou seja:<input name="foo" value="bar" readonly="readonly" />
Matt Huggins
5
Para que o campo de entrada "somente leitura" tenha a aparência do campo "desativado", defina 'style = "color: grey; background-color: # F0F0F0;"'.
Dan Nissenbaum 28/02
3
@MattHuggins Definir valor para atributos de nome apenas de atributo, como verificado, somente leitura, etc ... e barra invertida em atributos sem par não têm nada a ver com a validade HTML - eles são necessários para a validade XHTML ...
jave.web
Btw: Talvez alguém se depare com isso: NÃO O USE para o tipo de entrada = botão, eles não serão "desabilitados", use "disabled = 'desabilitado'"
Meister Schnitzel
2
readonlynão funcionará, pois você não poderá postar o valor de uma caixa de seleção com essa tag, use disabledjunto com o elemento de entrada oculto para manter o valor da caixa de seleção. Veja como: stackoverflow.com/a/8274787/448816
mikhail-t
91

Eu resolvi esse problema.

Como a readonly="readonly"tag não está funcionando (tentei navegadores diferentes), você deve usar disabled="disabled" . Mas o valor da sua caixa de seleção não será publicado ...

Aqui está a minha solução:

Para obter a aparência "somente leitura" e o valor da caixa de seleção POST ao mesmo tempo, basta adicionar uma "entrada" oculta com o mesmo nome e valor da sua caixa de seleção . Você deve mantê-lo próximo à sua caixa de seleção ou entre as mesmas <form></form>tags:

<input type="checkbox" checked="checked" disabled="disabled" name="Tests" value="4">SOME TEXT</input>

<input type="hidden" id="Tests" name="Tests" value="4" />

Além disso, apenas para que você saiba readonly="readonly", readonly="true", readonly="",ou simplesmente READONLYnão vai resolver isso! Passei algumas horas para descobrir!

Essa referência também NÃO é relevante (pode não ser ainda, ou não é mais, não tenho idéia): http://www.w3schools.com/tags/att_input_readonly.asp

mikhail-t
fonte
aqui deve haver os mesmos IDs para entradas ocultas e de caixa de seleção?
user2167382
Não, o Id pode ser o que for, mas 'name' e 'value' devem ser os mesmos.
Mikhail-t
Quão confiável é isso em vários navegadores?
Tim
isto foi testado e funcionou bem no último Chrome, Firefox e IE 11, aqui é uma implementação, experimentá-lo em seu navegador: mvccbl.com/...
Mikhail-t
74

Se você estiver satisfeito com o JQuery, remova o atributo desativado ao enviar o formulário:

$("form").submit(function() {
    $("input").removeAttr("disabled");
});
Tristan Channing
fonte
Isso tornará o controle "ativado" na interface do usuário?
Anar khalilov
Ele remove o atributo desativado, portanto, em teoria, sim. Na prática, acho que o usuário não pode alterar o campo através da interface do usuário entre esse evento e o formulário que está sendo enviado ... Gostaria de saber com certeza.
Tristan Channing
Um pouco antigo, mas como nota explicativa: Se você usa <select>ou <textfield>ou outros elementos HTML que suportam o disabledatributo, é possível selecioná-los e ativar todos com: $( "*:disabled" ).removeAttr("disabled");
Gusstavv Gil
10

Você pode lidar com isso dessa maneira ... Para cada caixa de seleção, crie um campo oculto com o mesmo nameatributo. Mas defina o valor desse campo oculto com algum valor padrão que você possa testar. Por exemplo..

<input type="checkbox" name="myCheckbox" value="agree" />
<input type="hidden" name="myCheckbox" value="false" />

Se a caixa de seleção estiver "marcada" quando o formulário for enviado, o valor desse parâmetro será

"agree,false"

Se a caixa de seleção não estiver marcada, o valor será

"false"

Você pode usar qualquer valor em vez de "false", mas entende a ideia.

jessegavin
fonte
5
Você não odeia quando escreve uma solução complicada para um problema e, quando atualiza, alguém (como Francesco) escreve e escreve uma única linha? ;)
jessegavin
Isso é perfeito para o que estou tentando realizar. Quero que a caixa de seleção desmarcada envie um valor em vez de nada, obrigado: D.
Geoffrey
@ jessegavin Dado que o seu 'liner simples' não funciona mais e ele atualizou sua resposta para incluir o seu, não, não posso dizer que sim.
RyanfaeScotland
8
<input type="checkbox" checked="checked" onclick="this.checked=true" />

Comecei com o problema: "como POST / enviar uma caixa de seleção de entrada que está desativada?" e na minha resposta pulei o comentário: "Se queremos desativar uma caixa de seleção, certamente precisamos manter um valor prefixado (marcado ou desmarcado) e também queremos que o usuário esteja ciente disso (caso contrário, devemos usar um tipo oculto e não é uma caixa de seleção) ". Na minha resposta, supus que queremos manter sempre uma caixa de seleção marcada e esse código funciona dessa maneira. Se clicarmos nessa caixa de verificação, ela será verificada para sempre e seu valor será POSTADO / Enviado! Da mesma forma, se eu escrever onclick = "this.checked = false" sem marcado = "marcado" (nota: o padrão é desmarcado), ele será desmarcado para sempre e seu valor não será POSTADO / Enviado !.

PaoloMarass
fonte
isso simplesmente duplicará o que a caixa de seleção já faz, mas se ela tiver sido desativada por javascript ou algo assim, ainda estará desativada, você poderia explicar um pouco mais o que estava procurando, talvez eu entenda mal, pois é apenas uma linha de código
ScottC
8

crie uma classe css, por exemplo:

.disable{
        pointer-events: none;
        opacity: 0.5;
}

aplique esta classe em vez do atributo desativado

Austin Rodrigues
fonte
7

A maneira mais simples de fazer isso é:

<input type="checkbox" class="special" onclick="event.preventDefault();" checked />

Isso impedirá que o usuário desmarque essa caixa de seleção e ainda enviará seu valor quando o formulário for enviado. Desmarque a opção se desejar que o usuário não consiga marcar esta caixa de seleção.

Além disso, você pode usar o javascript para limpar o onclick depois que uma determinada condição for atendida (se é isso que você procura). Aqui está um rabisco baixo e sujo mostrando o que quero dizer. Não é perfeito, mas você entende.

http://jsfiddle.net/vwUUc/

thatFunkymunkey
fonte
4

Isso funciona como um encanto:

  1. Remova os atributos "desativados"
  2. Envie o formulário
  3. Adicione os atributos novamente. A melhor maneira de fazer isso é usar uma função setTimeOut , por exemplo, com um atraso de 1 milissegundo.

A única desvantagem é o piscar rápido dos campos de entrada desativados ao enviar. Pelo menos no meu cenário, isso não é um problema!

$('form').bind('submit', function () {
  var $inputs = $(this).find(':input'),
      disabledInputs = [],
      $curInput;

  // remove attributes
  for (var i = 0; i < $inputs.length; i++) {
    $curInput = $($inputs[i]);

    if ($curInput.attr('disabled') !== undefined) {
      $curInput.removeAttr('disabled');
      disabledInputs.push(true);
    } else 
      disabledInputs.push(false);
  }

  // add attributes
  setTimeout(function() {
    for (var i = 0; i < $inputs.length; i++) {

      if (disabledInputs[i] === true)
        $($inputs[i]).attr('disabled', true);

    }
  }, 1);

});
Andi R
fonte
3

Não desative; em vez disso, defina-o como somente leitura, embora isso não tenha efeito, pois não permite que o usuário altere o estado. Mas você pode usar o jQuery para aplicar isso (impeça o usuário de alterar o estado da caixa de seleção:

$('input[type="checkbox"][readonly="readonly"]').click(function(e){
    e.preventDefault();
});

Isso pressupõe que todas as caixas de seleção que você não deseja modificar tenham o atributo "somente leitura". por exemplo.

<input type="checkbox" readonly="readonly">
Peter
fonte
Obrigado por isso! Por alguma razão, a entrada "oculta" não estava funcionando para mim. Isso me salvou. Corte muito bom mesmo!
NewbieProgrammer
3

Desde a:

  • definir o atributo readonly como checkbox não é válido de acordo com a especificação HTML,
  • usar elemento oculto para enviar valor não é uma maneira muito bonita e
  • definir JavaScript onclick que impede a alteração de valor também não é muito bom

Vou lhe oferecer outra possibilidade:

Defina sua caixa de seleção como desativada normalmente. E antes que o formulário seja enviado pelo usuário, ative esta caixa de seleção por JavaScript.

<script>
    function beforeSumbit() {
        var checkbox = document.getElementById('disabledCheckbox');
        checkbox.disabled = false;
    }
</script>
...
<form action="myAction.do" method="post" onSubmit="javascript: beforeSubmit();">
    <checkbox name="checkboxName" value="checkboxValue" disabled="disabled" id="disabledCheckbox" />
    <input type="submit />
</form>

Como a caixa de seleção está ativada antes do envio do formulário, seu valor é lançado de maneira comum. A única coisa que não é muito agradável com esta solução é que essa caixa de seleção fica ativada por um tempo e pode ser vista pelos usuários. Mas é apenas um detalhe com o qual posso viver.

sporak
fonte
1

Infelizmente, não existe uma solução "simples". O atributo somente leitura não pode ser aplicado às caixas de seleção. Eu li as especificações do W3 sobre a caixa de seleção e encontrei o culpado:

Se um controle não tiver um valor atual quando o formulário for enviado, os agentes do usuário não precisarão tratá-lo como um controle bem-sucedido. ( http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2 )

Isso faz com que o estado desmarcado e o estado desabilitado resultem no mesmo valor analisado.

  • readonly = "readonly" não é um atributo válido para caixas de seleção.
  • onclick = "event.preventDefault ();" nem sempre é uma boa solução, pois é acionada na própria caixa de seleção. Mas pode funcionar em alguns casos.
  • Ativar a caixa de seleção onSubmit não é uma solução, porque o controle ainda não é tratado como um controle bem-sucedido, para que o valor não seja analisado.
  • Adicionar outra entrada oculta com o mesmo nome em seu HTML não funciona porque o primeiro valor de controle é substituído pelo segundo valor de controle, pois tem o mesmo nome.

A única maneira completa de fazer isso é adicionar uma entrada oculta com o mesmo nome com javascript ao enviar o formulário .

Você pode usar o pequeno trecho que fiz para isso:

function disabled_checkbox() {
  var theform = document.forms[0];
  var theinputs = theform.getElementsByTagName('input');
  var nrofinputs = theinputs.length;
  for(var inputnr=0;inputnr<nrofinputs;inputnr++) {
    if(theinputs[inputnr].disabled==true) {
      var thevalueis = theinputs[inputnr].checked==true?"on":"";
      var thehiddeninput = document.createElement("input");
      thehiddeninput.setAttribute("type","hidden");
      thehiddeninput.setAttribute("name",theinputs[inputnr].name);
      thehiddeninput.setAttribute("value",thevalueis);
      theinputs[inputnr].parentNode.appendChild(thehiddeninput);
    }
  }
}

Ele procura o primeiro formulário no documento, reúne todas as entradas e pesquisa entradas desativadas. Quando uma entrada desativada é encontrada, uma entrada oculta é criada no parentNode com o mesmo nome e o valor 'on' (se o estado estiver 'marcado') e '' (se o estado for '' - não marcado).

Esta função deve ser acionada pelo evento 'onsubmit' no elemento FORM como:

<form id='ID' action='ACTION' onsubmit='disabled_checkbox();'>
JPA
fonte
1

Adicione onsubmit="this['*nameofyourcheckbox*'].disabled=false"ao formulário.

GuiltyScarl3t
fonte
1

Não há outra opção além de um hiddencampo, portanto, tente usar um hiddencampo como demonstrado no código abaixo:

<input type="hidden" type="text" name="chk1[]" id="tasks" value="xyz" >
<input class="display_checkbox" type="checkbox" name="chk1[]" id="tasks" value="xyz" checked="check"  disabled="disabled" >Tasks
Om R Kattimani
fonte
0
<html>
    <head>
    <script type="text/javascript">
    function some_name() {if (document.getElementById('first').checked)      document.getElementById('second').checked=false; else document.getElementById('second').checked=true;} 
    </script>
    </head>
    <body onload="some_name();">
    <form>
    <input type="checkbox" id="first" value="first" onclick="some_name();"/>first<br/>
    <input type="checkbox" id="second" value="second" onclick="some_name();" />second
    </form>
    </body>
</html>

A função some_name é um exemplo de uma cláusula anterior para gerenciar a segunda caixa de seleção marcada (lança seu valor) ou desmarcada (não lança seu valor) de acordo com a cláusula e o usuário não pode modificar seu status; não há necessidade de gerenciar qualquer desativação da segunda caixa de seleção

paolomarass
fonte
0

Você pode mantê-lo desativado conforme desejado e remover o atributo desativado antes do envio do formulário.

$('#myForm').submit(function() {
    $('checkbox').removeAttr('disabled');
});
Sergej Fomin
fonte
0

Adicionando onclick="this.checked=true"Resolva meu problema:
Exemplo:

<input type="checkbox" id="scales" name="feature[]" value="scales" checked="checked" onclick="this.checked=true" />
berramou
fonte
0

Aqui está outra solução alternativa que pode ser controlada pelo back-end.

ASPX

<asp:CheckBox ID="Parts_Return_Yes" runat="server" AutoPostBack="false" />

No ASPX.CS

Parts_Return_Yes.InputAttributes["disabled"] = "disabled";
Parts_Return_Yes.InputAttributes["class"] = "disabled-checkbox";

A classe é adicionada apenas para fins de estilo.

Mahib
fonte
0

Acabei de combinar as sugestões de HTML, JS e CSS nas respostas aqui

HTML:

<input type="checkbox" readonly>

jQuery:

(function(){
    // Raj: https://stackoverflow.com/a/14753503/260665
    $(document).on('click', 'input[type="checkbox"][readonly]', function(e){
        e.preventDefault();
    });
})();

CSS:

input[type="checkbox"][readonly] {
  cursor: not-allowed;
  opacity: 0.5;
}

Como o elemento não está 'desativado', ele ainda passa pelo POST.

Raj Pawan Gumdal
fonte