JQuery 序列化不注册复选框

我使用 jQuery.Series 检索表单中的所有数据字段。

我的问题是,它不检索未选中的复选框。

其中包括:

<input type="checkbox" id="event_allDay" name="event_allDay" class="checkbox" checked="checked" />

但不是这个

<input type="checkbox" id="event_allDay" name="event_allDay" class="checkbox" />

如何得到未选中的复选框的“值”?

110993 次浏览

没有,因为序列化意味着要用作查询字符串,在这种情况下,未检查意味着它根本不在查询字符串中。

如果您确实希望获得未选中复选框的值,请使用: (未经测试的偏离路线)

var arr_unchecked_values = $('input[type=checkbox]:not(:checked)').map(function(){return this.value}).get();

JQuery serialize非常类似于标准表单在被追加到请求中的查询字符串或 POST 主体之前由浏览器序列化的方式。未选中的复选框不包含在浏览器中,这很有意义,因为它们具有布尔状态——它们要么被用户选中(包含) ,要么不被用户选中(不包含)。

If you need it to be in the serialized, you should ask yourself "why? why not just check for its existence in the data?".

请记住,如果 JavaScript 序列化表单数据的方式与浏览器不同,那么您就消除了表单优雅降级的任何可能性。如果您仍然绝对需要这样做,只需使用带有 Yes/No 选项的 <select>框。至少这样,禁用 JS 的用户不会疏远您的站点,您也不会违背 HTML 规范中定义的行为。

<select id="event_allDay" name="event_allDay">
<option value="0" selected>No</option>
<option value="1">Yes</option>
</select>

我过去在一些网站上看到过这种做法,总是对自己说,“他们为什么不用复选框”

如果您想将未序列化的复选框添加到查询字符串中,请将以下内容添加到 jquery 提交函数中:

var moreinfo = '';


$('input[type=checkbox]').each(function() {
if (!this.checked) {
moreinfo += '&'+this.name+'=0';
}
});

sometimes unchecked means other values, for instance checked could mean yes unchecked no or 0,1 etc it depends on the meaning you want to give.. so could be another state besides "unchecked means it's not in the querystring at all"

“这将使在 DB 中存储信息变得更加容易。因为这样 Serialize 中的字段数就等于表中的字段数。现在我必须控制哪些是丢失的”,你是对的,这也是我的问题... 所以看起来我必须检查这个不存在的价值... 。

但也许这是个解决办法? Http://tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/

为了建立在阿扎托斯的天才答案的基础上,我对我的场景稍微扩展了一下:

    /* Get input values from form */
values = jQuery("#myform").serializeArray();


/* Because serializeArray() ignores unset checkboxes and radio buttons: */
values = values.concat(
jQuery('#myform input[type=checkbox]:not(:checked)').map(
function() {
return {"name": this.name, "value": false}
}).get()
);

我在自己的系统中使用过一种技术,我相信 Struts 也采用了这种技术,它包括..。

<input type="hidden" name="_fieldname" value="fieldvalue"/>

... 作为我的表单创建逻辑的一部分,紧挨着复选框。

这允许我重新构建表单中提供了但没有选中的复选框,通过一点点额外的逻辑来区分提供了什么和选中了什么,你可以看到那些没有选中的复选框。无论您使用 HTML 还是 AJAX 样式提交,提交的内容也是相同的。

根据您使用的服务器端技术,您可能希望使用这种语法..。

<input type="hidden" name="_fieldname[]" value="fieldvalue"/>

以便于将这些值作为一个列表来抓取。

使用非标准复选框序列化的一个原因是 只对序列化数据中显式指定的字段进行反序列化(更改)——例如,当你使用 jquery 序列化和反序列化来保存和加载首选项时。

Thomas Danemar 实现了对标准 serialize()方法的一个修改,以便可选地采用 checkboxesAsBools选项: http://tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/——这与上面@mydoghasworms 列出的实现类似,但也集成到标准序列化中。

我已经把它复制到 Github,以防有人在任何时候需要改进: https://gist.github.com/1572512

此外,“ jquery.desialize”插件现在可以正确地反序列化用 checkboxesAsBools序列化的复选框值,并忽略序列化数据中没有提到的复选框: https://github.com/itsadok/jquery.deserialize

试试这个:

$(’: input [ type = “ checkbox”] : check’) . map (function (){ return this. value }) . get () ;

只要简单地添加一个隐藏的输入

<input type="hidden" name="your_specific_name">

不需要价值,我测试这个工程为我

var checkboxes = $('#myform').find('input[type="checkbox"]');
$.each( checkboxes, function( key, value ) {
if (value.checked === false) {
value.value = 0;
} else {
value.value = 1;
}
$(value).attr('type', 'hidden');
});
$('#myform').serialize();

JQuery 序列化获取输入的 value 属性。

现在如何让复选框和单选按钮工作?如果您设置复选框或单选按钮0或1的单击事件,您将能够看到更改。

$( "#myform input[type='checkbox']" ).on( "click", function(){
if ($(this).prop('checked')){
$(this).attr('value', 1);
} else {
$(this).attr('value', 0);
}
});


values = $("#myform").serializeArray();

也可以在任何时候将复选框设置为选中状态,例如 php

<input type='checkbox' value="<?php echo $product['check']; ?>" checked="<?php echo $product['check']; ?>" />

使用 Andy 建议的选择字段不一定是用户体验的最佳选择,因为它需要两次鼠标点击而不是一次。

此外,“选择”比复选框在 UI 中使用更多的空间。

Ash 的答案是一个简单的解决方案,但在 数组字段的情况下不起作用。

在我的上下文中,我有一个可变长度的表单,其中包含显示文本和复选框字段组合的行:

<input type="checkbox" value="1" name="thisIsAChkArray[]"/>
<input type="text" value="" name="thisIsATxtArray[]"/>

对于解码发布的数据,阵列元素的 秩序非常重要。仅仅将未检查的项追加到常规 Jquery 序列化中并不能保持行元素的顺序。

以下是根据 Ash 的回答提出的解决方案:

(function($) {
$.fn.serializeWithChkBox = function() {
// perform a serialize form the non-checkbox fields
var values = $(this).find('select')
.add(  $(this).find('input[type!=checkbox]') )
.serialize();
// add values for checked and unchecked checkboxes fields
$(this).find('input[type=checkbox]').each(function() {
var chkVal = $(this).is(':checked') ? $(this).val() : "0";
values += "&" + $(this).attr('name') + "=" + chkVal;
});
return values;
}
})(jQuery);

诀窍是拦截表单发送并将复选框更改为隐藏输入字段。

示例: 简单提交

$('form').on("submit", function (e) {
//find the checkboxes
var $checkboxes = $(this).find('input[type=checkbox]');


//loop through the checkboxes and change to hidden fields
$checkboxes.each(function() {
if ($(this)[0].checked) {
$(this).attr('type', 'hidden');
$(this).val(1);
} else {
$(this).attr('type', 'hidden');
$(this).val(0);
}
});
});

例如: AJAX

如果您通过 ajax 发布表单以避免更新 UI,那么您需要跳过更多的障碍。

$('form').on("submit", function (e) {
e.preventDefault();


//clone the form, we don't want this to impact the ui
var $form = $('form').clone();


//find the checkboxes
var $checkboxes = $form.find('input[type=checkbox]');


//loop through the checkboxes and change to hidden fields
$checkboxes.each(function() {
if ($(this)[0].checked) {
$(this).attr('type', 'hidden');
$(this).val(1);
} else {
$(this).attr('type', 'hidden');
$(this).val(0);
}
});


$.post("/your/path", $form.serialize());

下面是另一个扩展“ seralizeArray”方法(同时保留原始行为)的解决方案。

//Store the reference to the original method:
var _serializeArray = $ji.fn.serializeArray;


//Now extend it with newer "unchecked checkbox" functionality:
$ji.fn.extend({
serializeArray: function () {
//Important: Get the results as you normally would...
var results = _serializeArray.call(this);


//Now, find all the checkboxes and append their "checked" state to the results.
this.find('input[type=checkbox]').each(function (id, item) {
var $item = $ji(item);
var item_value = $item.is(":checked") ? 1 : 0;
var item_name = $item.attr('name');
var result_index = null;
results.each(function (data, index) {
if (data.name == item_name) {
result_index = index;
}
});


if (result_index != null) {
// FOUND replace previous value
results[result_index].value = item_value;
}
else {
// NO value has been found add new one
results.push({name: item_name, value: item_value});
}
});
return results;
}
});

这实际上将附加“ true”或“ false”布尔结果,但是如果您愿意,可以分别使用“1”和“0”,方法是将值更改为 value: $item.is(":checked") ? 1 : 0

用法

像往常一样,调用表单上的方法: $form.serialize()$form.serializeArray()。无论如何,serialize都会使用 serializeArray,因此无论调用哪种方法,都会得到正确的结果(尽管格式不同)。

我也遇到过类似的问题,下面的代码允许我收集所有表单输入值和选中/未选中的复选框。

var serialized = this.$('#myform input').map(function() {
return { name: this.name, id: this.id, value: this.checked ? "checked" : "false" };
});

您可以通过 jquery 序列化获得输入值

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" id="event_allDay" name="event_allDay" checked="checked" onchange="isChecked(this)" value="" />
<script>
function isChecked(element) {
$(element).val($(element).is(':checked').toString());
}
isChecked('#event_allDay');
</script>

这个例子假设您希望通过 serialize而不是 serializeArray回发表单,并且一个未选中的复选框意味着 false:

var form = $(formSelector);
var postData = form.serialize();


var checkBoxData = form.find('input[type=checkbox]:not(:checked)').map(function () {
return encodeURIComponent(this.name) + '=' + false;
}).get().join('&');


if (checkBoxData) {
postData += "&" + checkBoxData;
}


$.post(action, postData);

这将使用布尔值的选中状态将表单复选框值设置为布尔值。

var form = $('#myForm');
var data = form.serializeObject();


$('#myForm input[type=checkbox]').each(function() { data[this.name] = this.checked; });

我们使用的框架创建两个具有相同名称的输入,这将导致在序列化表单时出现意外行为。我将把每个复选框值解析为包含字符串值的两个元素数组。根据映射数据服务器端的方式,可能会得到意想不到的结果。

为了扩展上面的答案,在我的例子中,我需要针对序列化到后端捕获的单个 ID 发送一个 yes/no。

我将复选框元素设置为包含特定数据库列(即 (默认选中))的 ID:

(Laravel Blade)

<div class="checkbox">
<label>
<input type="checkbox" value="\{\{ $heading->id }}" checked> \{\{ $heading->name }}
</label>
</div>

当我提交材料的时候,我抓取了以下数据:

(jQuery)

let form = $('#formID input[type="checkbox"]').map(function() {
return { id: this.value, value: this.checked ? 1 : 0 };
}).get();


var data = JSON.stringify(form);
$.post( "/your/endpoint", data );

对于 ASP.NET MVC,我们通过一个 AJAX POST 成功地保存了一个 复选框表格,这是本文中参考的几种方法的组合,包括 @ Jecoms 建议:

var form = $('#myForm');
// Serialize the form into a JavaScript object using the jQuery.serializeObject plugin
// https://plugins.jquery.com/serializeObject/
var data = form.serializeObject();
// Change the submitted value of checkboxes to the value of the checked property
$('#myForm input[type=checkbox]').each( function () { data[this.name] = this.checked; } );
// For a MVC controller, convert the JS object back into a query string using jQuery.param function
data = $.param(data);
// Perform AJAX POST with the form data
$.ajax({
async: true,
url: 'mvcActionMethodURL',
type: 'POST',
data: data,
success: function (data, textStatus, xhr) {


},
error: function (xhr, status, error) {


}
});

你可以在 ajax 之前调用 handleInputs()添加你的提交函数

function handleInputs(){
$('input[type=checkbox]').each(function() {
if (!this.checked) {
$(this).attr("value","0");
}else{
$(this).attr("value","1");
}
});
}

效果非常好

对于使用 serialize()函数的用户:

(function ($) {
var serialize = $.fn.serialize;


$.fn.serialize = function () {
let values = serialize.call(this);
let checkboxes = [];


checkboxes = checkboxes.concat(
$('input[type=checkbox]:not(:checked)', this).map(
function () {
return this.name + '=false';
}).get()
);


if(checkboxes.length > 0)
values = checkboxes.join('&') + '&' + values;


return values;
};
})(jQuery);

我已经用这种方法得到了值“0”或者如果选中“1”。这说明,如果 复选框输入名称不存在于序列化的 form_data中,那么这意味着它没有被选中,然后添加值为零(form_data += '&' + name + '=0') ,但如果被选中的 serialize()函数会自动添加它。

   /*get all other form inputs*/
var form_data = form.serialize();


/*get checkboxes*/
$.each($("#form_id input[type='checkbox']"), function(){
var name = $(this).attr('name');
if(form_data.indexOf(name)===-1)form_data += '&' + name + '=0';
});

我用了另一种方式,对我有效:

序列化表单数据(如上所述,将排除未选中的复选框值) :

const formData = $("form[name='config']").serialize();
const data = {
config: formData
}

然后,在 PHP 中,我将构建一个 JSON 对象:

parse_str($_REQUEST['config'], $configJSON);
$configJSON = json_encode($configJSON);

在 MSSQL,在我的存储过程中,当一个列从 jSON 中消失时(因为它已经被 jquery 序列化过滤掉了) ,它将是 NULL,因此将被替换为0(多亏了 ISNULL函数) :

ALTER PROCEDURE [dbo].[eth_userprofil_updateconfig]
(
@userId int,
@configJSON nvarchar(max)
)
AS
BEGIN
SET NOCOUNT ON;
    

UPDATE dbo.MyTable
SET MyField = ISNULL(JSON_VALUE(@configJSON, '$.MyField '), 0),
....
WHERE userId = @userId
END