20

我已经阅读了很多将 html 复选框发布到服务器的不同方法,但我真的希望在不修改任何东西(除了 $.serialize 之外)的情况下做到这一点。理想情况下,我希望将选中的框张贴为打开,将未选中的框张贴为 0、空或空。

我对 jquery 的内部工作有点困惑,但到目前为止我已经有了这个,但是它将未选中的复选框设置为“on”......谁能告诉我如何在下面继续这个修改?

$.fn.extend({
    serializeArray: function() {
        return this.map(function(){
            return this.elements ? jQuery.makeArray( this.elements ) : this;
        })
        .filter(function(){
            return this.name && !this.disabled &&
                ( this.checked || !this.checked || rselectTextarea.test( this.nodeName ) || rinput.test( this.type ) );
        })
        .map(function( i, elem ){
            var val = jQuery( this ).val();

            return val == null ?
                null :
                jQuery.isArray( val ) ?
                    jQuery.map( val, function( val, i ){
                        return { name: elem.name, value: val.replace( /\r?\n/g, "\r\n" ) };
                    }) :
                    { name: elem.name, value: val.replace( /\r?\n/g, "\r\n" ) };
        }).get();
    }
});
4

11 回答 11

14

只需附上数据。在我的保存例程中,提交未选中为空字符串并选中为“on”就足够了:

var formData = $('form').serialize();

// include unchecked checkboxes. use filter to only include unchecked boxes.
$.each($('form input[type=checkbox]')
    .filter(function(idx){
        return $(this).prop('checked') === false
    }),
    function(idx, el){
        // attach matched element names to the formData with a chosen value.
        var emptyVal = "";
        formData += '&' + $(el).attr('name') + '=' + emptyVal;
    }
);
于 2014-09-19T12:14:21.003 回答
13

这将覆盖 jquery.serialize() 方法以发送选中/未选中的值,而不仅仅是选中的值。它使用真/假,但如果您愿意,您可以将“this.checked”更改为“this.checked?'on': 0”。

var originalSerializeArray = $.fn.serializeArray;
$.fn.extend({
    serializeArray: function () {
        var brokenSerialization = originalSerializeArray.apply(this);
        var checkboxValues = $(this).find('input[type=checkbox]').map(function () {
            return { 'name': this.name, 'value': this.checked };
        }).get();
        var checkboxKeys = $.map(checkboxValues, function (element) { return element.name; });
        var withoutCheckboxes = $.grep(brokenSerialization, function (element) {
            return $.inArray(element.name, checkboxKeys) == -1;
        });

        return $.merge(withoutCheckboxes, checkboxValues);
    }
});
于 2012-05-18T21:39:39.500 回答
12

我认为 Robin Maben 的解决方案缺少一个步骤,即将框设置为具有“已检查”属性。jQuery 的关于 serialise() 状态的用户指南说明只有选中的复选框被序列化,所以我们需要添加一点:

$('form').find(':checkbox:not(:checked)').attr('value', '0').prop('checked', true);

此方法的唯一缺点是您的表单会短暂闪现,显示所有框已选中 - 看起来有点奇怪。

于 2014-02-25T20:13:04.360 回答
3

我喜欢@Robin Maben 的方法(在调用本机 .serialize() 之前预处理复选框),但如果不进行重大修改就无法使其工作。

我想出了这个插件,我称之为“mySerialize”(可能需要一个更好的名字):

$.fn.mySerialize = function(options) {
    var settings = {
        on: 'on',
        off: 'off'
    };
    if (options) {
        settings = $.extend(settings, options);
    }
    var $container = $(this).eq(0),
        $checkboxes = $container.find("input[type='checkbox']").each(function() {
            $(this).attr('value', this.checked ? settings.on : settings.off).attr('checked', true);
        });
    var s = ($container.serialize());
    $checkboxes.each(function() {
        var $this = $(this);
        $this.attr('checked', $this.val() == settings.on ? true : false);
    });
    return s;
};

在 Opera 11.62 和 IE9 中测试

正如您在此DEMO中看到的那样,您可以指定复选框的 ON 和 OFF 状态作为参数传递给的选项对象序列化的方式mySerialize()。默认情况下,ON 状态被序列化为“name=on”,OFF 被序列化为“name=off”。所有其他表单元素都按照本机 jQuery 进行序列化serialize()

于 2012-04-14T01:00:06.983 回答
2
 var x = $('#formname').serializeArray();
 var serialized = $('#formname').find(':checkbox:not(:checked)').map(function () { 
   x.push({ name: this.name, value: this.checked ? this.value : "false" }); 
 });

试试这个

于 2019-10-20T06:33:44.220 回答
1

Beetroot-Beetroot 的答案在 jQuery 1.9 及更高版本中对我不起作用。我使用.val()and .prop(),并摆脱了.eq(0)对容器的要求,这将序列化限制为选择器中的一种形式。我有一个罕见的情况,我必须同时序列化多个表单,因此删除该要求解决了这个问题。这是我修改后的解决方案:

$.fn.mySerialize = function(options) {
    // default values to send when checkbox is on or off
    var settings = {
        on: 'on',
        off: 'off'
    };

    // override settings if given
    if (options) {
        settings = $.extend(settings, options);
    }

    // set all checkboxes to checked with the on/off setting value
    // so they get picked up by serialize()
    var $container = $(this),
        $checkboxes = $container.find("input[type='checkbox']").each(function() {
            $(this).val(this.checked ? settings.on : settings.off).prop('checked', true);
        });

    var serialized = ($container.serialize());

    $checkboxes.each(function() {
        var $this = $(this);
        $this.prop('checked', $this.val() == settings.on);
    });

    return serialized;
};

你可以在这里看到相应的小提琴

于 2017-03-24T21:59:55.783 回答
0

我做了以下操作,找到未选中的复选框,在调用 serializeArray 之前检查它们,然后取消选中它们,以便表单处于与用户离开它的状态相同的状态:

var unchecked = chartCfgForm.find(':checkbox:not(:checked)');
unchecked.each(function() {$(this).prop('checked', true)});
var formValues = chartCfgForm.serializeArray();
unchecked.each(function() {$(this).prop('checked', false)});
于 2015-08-24T18:20:50.363 回答
0

下面是我如何实现一个简单的覆盖,$.serializeArray它修复了复选框的默认序列化行为,并为所有其他类型保留了默认行为。

在下面的代码中,遗漏的复选框被注入到原始序列化数组中。复选框状态返回为"true"(而不是"on")或"false"取决于是否返回checked

(function ($) {
    var _base_serializeArray = $.fn.serializeArray;
    $.fn.serializeArray = function () {
        var a = _base_serializeArray.apply(this);
        $.each(this, function (i, e) {
            if (e.type == "checkbox") {
                e.checked 
                ? a[i].value = "true" 
                : a.splice(i, 0, { name: e.name, value: "false" })
            }
        });
        return a;
    };
})(jQuery);

您可以将其自定义为 return"on"/"off"true/false.

于 2018-04-25T09:35:35.123 回答
0

如果您没有大型表格,另一种方法是。

$.fn.serializeForm = function () {
    var form = $(this).clone()
    form.find('input:checkbox:not(:checked)').attr('value', 'off').prop('checked', true);
    return form.serialize();
};

我也喜欢使用更好的值:

$.fn.serializeForm = function () {
    var form = $(this).clone()
    form.find('input:checkbox:checked').attr('value', 'Yes');
    form.find('input:checkbox:not(:checked)').attr('value', 'No').prop('checked', true);
    return form.serialize();
};

然后

$('#yourForm').serializeForm();
于 2021-12-04T13:02:30.217 回答
-1

这是一个小改动:

    .map(function( i, elem ){
        var val = jQuery( this ).val();
        if ((jQuery(this).checked != undefined) && (!jQuery(this).checked)) {
            val = "false";
        }

我没有测试过,但这似乎是最合乎逻辑的方法。祝你好运

于 2012-04-13T19:37:03.833 回答
-1

在调用之前,如果未选中复选框,则serialize()需要显式设置值false

$(form).find(':checkbox:not(:checked)').attr('value', false);

我已经在这里测试过了。

于 2012-04-13T20:03:49.233 回答