¿Cómo hago que $ .serialize () tenga en cuenta los elementos de entrada deshabilitados?

135

Parece que, por defecto, los elementos de entrada deshabilitados son ignorados por $.serialize(). ¿Hay alguna solución?

fms
fuente
Es aún más extraño, porque puedes serializar un deshabilitado textareapero no un deshabilitado input...
DATE el

Respuestas:

233

Habilítelos temporalmente.

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');
usuario113716
fuente
26
vale la pena considerar en readonlylugar de disabledlo mencionado por Andrew a continuación.
andilabs
93

Use entradas de solo lectura en lugar de entradas deshabilitadas:

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

Esto debería ser recogido por serialize ().

Andrés
fuente
Genial, solo una nota: aún se puede hacer clic en el botón Enviar cuando es de solo lectura.
André Chalella
3
deshabilitado impide la serialización, pero solo impide la validación
Jeff Lowery
12

Puede usar una función proxy (afecta a ambos $.serializeArray()y $.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
fuente
La mejor solución, funciona para entradas de selección, casilla de verificación, radio, ocultas y deshabilitadas
Plasebo
9

@ user113716 proporcionó la respuesta central. Mi contribución aquí es solo una gentileza de jQuery al agregarle una función:

/**
 * 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;
};

Ejemplo de uso:

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

Prueba esto:

<input type="checkbox" name="_key" value="value"  disabled="" />
<input type="hidden" name="key" value="value"/>
KennyKam
fuente
¿Podría por favor elaborar un poco más y explicarle al OP por qué esto funciona?
Willem Mulder
Te lo puedo explicar. Si aún desea tener un campo de entrada deshabilitado (por cualquier razón), pero también desea enviar el nombre de entrada con el método serialize (). Luego, en su lugar, puede usar un campo de entrada oculto (con el mismo valor que su campo de entrada deshabilitado), que serializar () no ignora. Y luego también puede mantener su campo de entrada deshabilitado para la visibilidad.
superkytoz
3

Puedo ver algunas soluciones, pero ¿nadie sugirió escribir su propia función de serialización? Aquí tienes: 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
fuente
2

Los elementos de entrada deshabilitados no se serializan porque 'deshabilitado' significa que no deben usarse, según el estándar W3C. jQuery solo cumple con el estándar, aunque algunos navegadores no lo hacen. Puede solucionar este problema agregando un campo oculto con un valor idéntico al campo deshabilitado, o haciendo esto a través de jQuery, algo como esto:

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

Obviamente, si tuviera más de una entrada deshabilitada, tendría que iterar sobre los selectores coincidentes, etc.

Jason Lewis
fuente
1

En caso de que alguien no quiera activarlos, luego deshabilítelos nuevamente, también puede intentar hacer esto (lo modifiqué desde los campos Deshabilitados que no fueron recogidos por serializeArray , desde usar un complemento hasta usar una función normal):

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

Entonces puedes llamarlos así:

getcomment("#formsp .disabledfield");
maximran
fuente
1
Probé su función y no produce el nombre o valor de los elementos. Ver ejemplo a continuación; code 3: {nombre: indefinido, valor: ""} 4: {nombre: indefinido, valor: ""}
blackmambo
0

Justo sobre Aaron Hudon:

Tal vez tenga algo más que Entrada (como select), así que cambié

this.find(":input:disabled")

a

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