如何覆盖jquery的.serialize以包含未选中的复选框

我已经阅读了很多不同的方法让html复选框被发布到服务器,但我真的希望这样做而不需要修改任何东西,除了$ .serialize。 理想情况下,我希望将复选框发布为on,并取消选中以发布为0,空或null。

我对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(); } }); 

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

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

这种方法的唯一缺点是表单的简短闪烁显示所有选中的框 – 看起来有点奇怪。

只需附加数据。 在我的保存例程中,提交未选中的空字符串并检查为“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; } ); 

这将覆盖jquery.serialize()方法以发送已检查/未检查的值,而不是仅检查已检查的值。 它使用true / false,但如果您愿意,可以将“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); } }); 

我喜欢@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中测试过

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

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

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

我在这里测试过它。

我做了以下操作,找到未选中的复选框,在调用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)}); 

Beetroot-Beetroot的回答在jQuery 1.9及更高版本中对我没有用。 我使用.val().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; }; 

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

这是我如何实现$.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); 

您可以自定义此选项以返回"on"/"off"true/false

这是一个小小的改变:

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

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