Como faço para que $ .serialize () leve em consideração aqueles elementos de entrada disabled:?

135

Parece que, por padrão, os elementos de entrada desativados são ignorados por $.serialize(). Existe uma solução alternativa?

fms
fonte
É ainda mais estranho, porque você pode serializar um desativado textarea, mas não a pessoas com deficiência input..
Dave

Respostas:

233

Ative-os temporariamente.

var myform = $('#myform');

 // Find disabled inputs, and remove the "disabled" attribute
var disabled = myform.find(':input:disabled').removeAttr('disabled');

 // serialize the form
var serialized = myform.serialize();

 // re-disabled the set of inputs that you previously enabled
disabled.attr('disabled','disabled');
user113716
fonte
26
vale a pena considerar em readonlyvez de disabledcomo mencionado por Andrew abaixo.
andilabs
93

Use entradas somente leitura em vez de entradas desativadas:

<input name='hello_world' type='text' value='hello world' readonly />

Isso deve ser captado por serialize ().

Andrew
fonte
Ótimo, apenas uma observação: o botão Enviar ainda pode ser clicado quando somente leitura.
André Chalella 7/11
3
desativada impede a serialização, mas a validação impede somente leitura
Jeff Lowery
11

Você pode usar uma função proxy (isso afeta tanto $.serializeArray()e $.serialize()):

(function($){
    var proxy = $.fn.serializeArray;
    $.fn.serializeArray = function(){
        var inputs = this.find(':disabled');
        inputs.prop('disabled', false);
        var serialized = proxy.apply( this, arguments );
        inputs.prop('disabled', true);
        return serialized;
    };
})(jQuery);
Krzysiek
fonte
Melhor solução, obras para select, checkbox, rádio, entradas escondidas e deficientes
Plasebo
9

@ user113716 forneceu a resposta principal. Minha contribuição aqui é apenas um detalhe do jQuery, adicionando uma função a ele:

/**
 * Alternative method to serialize a form with disabled inputs
 */
$.fn.serializeIncludeDisabled = function () {
    let disabled = this.find(":input:disabled").removeAttr("disabled");
    let serialized = this.serialize();
    disabled.attr("disabled", "disabled");
    return serialized;
};

Exemplo de uso:

$("form").serializeIncludeDisabled();
Aaron Hudon
fonte
4

Tente o seguinte:

<input type="checkbox" name="_key" value="value"  disabled="" />
<input type="hidden" name="key" value="value"/>
KennyKam
fonte
Você poderia elaborar um pouco mais e explicar ao OP por que isso funciona?
Willem Mulder
Eu posso explicar isso para você. Se você ainda deseja ter um campo de entrada desativado (por qualquer motivo), mas também deseja enviar o nome da entrada com o método serialize (). Em vez disso, você pode usar um campo de entrada oculto (com o mesmo valor do seu campo de entrada desativado), que serialize () não ignora. E você também pode manter seu campo de entrada desativado para a visibilidade.
Superkytoz
3

Eu posso ver algumas soluções alternativas, mas ainda assim ninguém sugeriu escrever sua própria função de serialização? Aqui está: https://jsfiddle.net/Lnag9kbc/

var data = [];

// here, we will find all inputs (including textareas, selects etc)
// to find just disabled, add ":disabled" to find()
$("#myform").find(':input').each(function(){
    var name = $(this).attr('name');
    var val = $(this).val();
    //is name defined?
    if(typeof name !== typeof undefined && name !== false && typeof val !== typeof undefined)
    {
        //checkboxes needs to be checked:
        if( !$(this).is("input[type=checkbox]") || $(this).prop('checked'))
            data += (data==""?"":"&")+encodeURIComponent(name)+"="+encodeURIComponent(val);
    }
});
David162795
fonte
2

Os elementos de entrada desativados não são serializados porque 'desativado' significa que eles não devem ser usados, de acordo com o padrão W3C. O jQuery está apenas cumprindo o padrão, embora alguns navegadores não. Você pode contornar isso adicionando um campo oculto com um valor idêntico ao campo desabilitado ou fazendo isso via jQuery, algo como isto:

$('#myform').submit(function() {
  $(this).children('input[hiddeninputname]').val($(this).children('input:disabled').val());
  $.post($(this).attr('url'), $(this).serialize, null, 'html');
});

Obviamente, se você tivesse mais de uma entrada desativada, teria que repetir os seletores correspondentes etc.

Jason Lewis
fonte
1

Caso alguém não queira ativá-los e desativá-los novamente, você também pode tentar fazer isso (modifiquei-o dos campos Disabled não selecionados pelo serializeArray , do plug-in ao uso da função normal):

function getcomment(item)
{
  var data = $(item).serializeArray();
  $(':disabled[name]',item).each(function(){
    data.push({name: item.name,value: $(item).val()});
  });
  return data;
}

Então você pode chamá-los assim:

getcomment("#formsp .disabledfield");
maximran
fonte
1
Eu tentei sua função e ela não produz o nome ou valor dos elementos. Veja o exemplo abaixo; code 3: {name: undefined, value: ""} 4: {name: undefined, value: ""}
blackmambo
0

Pouco sobre Aaron Hudon:

Talvez você tenha algo além de Input (como select), então mudei

this.find(":input:disabled")

para

this.find(":disabled")
Carl Verret
fonte