jQuery序列化不注册复选框


76

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

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

它包括:

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

但不是这个

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

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


2
我们在ASP Net中所做的是有一个隐藏的输入: <input type="checkbox" id="event_allDay" name="event_allDay" class="checkbox" checked="checked" Value="On" /> <input type="hidden" name="event_allDay" Value="Off" /> 这样,如果不选中它,它将采用隐藏的值
Carlos Martinez T

Answers:


72

jQueryserialize紧密模拟了标准格式在添加到请求中的查询字符串或POST正文之前如何被浏览器序列化。未选中的复选框未包含在浏览器中,这确实是有道理的,因为它们具有布尔状态-由用户选择(包含)或未被用户选择(未包含)。

如果需要将其序列化,则应问自己“为什么?为什么不只检查其在数据中是否存在?”。

请记住,如果JavaScript序列化表格数据的方式与浏览器的方式不同,那么您就消除了表格降级的任何可能性。如果仍然绝对需要这样做,只需使用<select>带有“是/否”的选项即可。至少到那时,禁用JS的用户不会与您的网站疏远,并且您不会违反HTML规范中定义的行为。

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

我曾经在某些网站上看到过这种做法,并且总是对自己说:“为什么他们不只是使用复选框”


20
这将使在数据库中存储信息变得容易得多。因为那样,Serialize中的字段数将等于表中的字段数。现在,我必须控制缺少的那些。
史蒂文2010年

19
想要未选中的复选框和未设置的单选按钮是一个很好的案例。这些字段的值可能已经在服务器上存在,并且您只想更新。通过在提交字符串中没有这些值,可以假定您每次都在对记录进行完全覆盖。
mydoghasworms

4
@mydog:为什么会这样呢?如果您问我,这似乎是一个糟糕的设计选择。如果浏览器正在提交表单数据,则这些字段将永远不在查询字符串中,那么为什么您将其设计为与JavaScript不同?首先,您将完全消除任何正常降级的机会。
安迪E

1
@AndyE有时您的服务器要求所有选项都明确。为什么这是罕见的情况?
Glenn

1
HTML应该表现为视图,而不是决定将哪些数据发送到“控制器”。数据的解释方式应由“控制器”(负责处理表单发布者)负责。
麦格里奥

79

为了基于azatoth的天才答案,针对我的情况我略微扩展了它:

    /* 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()
    );

7
不适用于我,所以我做了一个小调整:return {“ name”:this.name,“ value”:'off'}
xeo 2014年

1
我爱你。我一直在努力寻找解决方案来解决我的问题,而这正是google带来的。谢谢
Justin

谢谢!这正是我所需要的!
jared_flack 2015年

只有当您使用的作品serializeArray()不只是serialize()
乔杜里Waqas

1
这对我来说比接受的答案更好,但是“ this.checked”为我提供了复选框状态,而不是使用“ this.value”。我还将jquery选择器修改为“:checkbox”,因为我需要所有复选框。
保罗

27

您不需要,因为序列化是要用作查询字符串,在这种情况下,未选中表示根本不在查询字符串中。

如果您确实想要获取未选中复选框的值,请使用:(当然,未经测试)

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

下面答案很好地扩展了这一点。
2012年

17

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

var moreinfo = '';

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

这将消除您的表单正常降级的任何可能性-禁用JS的用户提交的数据将有所不同。
Andy E

我不得不说,如果您使用.serialize()函数,这是最好的解决方案。var data = $(“#userinput_form”)。serialize(); $('#userinput_form input [type = checkbox]:not(:checked)')。each(function(){data + ='&'+ this.name +'= 0';});
windmaomao

5

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']; ?>" />

2
此代码可以正常工作。通过为复选框提供一个属性-与检查状态保持同步,它基本上使复选框控件看起来像是该函数的普通输入(typetext或a select)。而且比选择的答案更优雅。serialize()value
Annabel '18

对于.Net MVC,使用True和False的值将允许mvc模型映射魔术设置您的布尔模型属性。并将这些属性添加到您的<input>以获得正确的视图呈现:value =“ @(Model.Item2.IsCurrent?” True“:” False“)” @(Model.Item2.IsCurrent?“ checked ='checked'” :“”)
DavidCC

4

这是扩展“ serializeArray”方法(同时保留原始行为)的另一种解决方案。

//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,因此无论使用哪种方法,您都可以获得正确的结果(尽管格式不同)。


错误:不好,当复选框为“ true”时,它仍会附加一个具有通常“ on”值的参数。要纠正这个问题……
bigp

如果选中了此复选框,则结果中将获得2个具有相同名称的值...一个带'on'的值,最后一个带'1'的值...
WonderLand

我已解决问题:)
WonderLand

4

您可以handleInputs()在ajax之前在提交功能中调用添加

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

这是完美的工作


3

我在自己的系统中使用过的一种技术(相信是Struts使用的一种技术)包括...

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

...紧邻复选框,这是我的表单创建逻辑的一部分。

这使我能够重构以表格形式提供但未选中的复选框,并使用一点点额外的逻辑来区分所提供的内容和已检查的内容,而那些未选中的内容。无论您使用的是HTML还是AJAX样式的提交,提交的内容都相同。

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

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

...以便轻松获取这些值作为列表。


3

对于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) {

    }
});

2

使用问题或当前答案中未解决的非标准复选框序列化的原因之一是仅对序列化数据中显式指定的字段进行反序列化(更改),例如,当您使用jquery序列化和反序列化来/从cookie中保存和加载偏好。

Thomas Danemar对标准serialize()方法进行了修改,可以选择采用以下checkboxesAsBools选项:http : //tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/-与上面列出的实现类似通过@mydoghasworms,还集成到标准序列化中。

我已将其复制到Github,以防任何人在任何时候都需要改进:https : //gist.github.com/1572512

此外,“ jquery.deserialize”插件现在将正确反序列化用序列化的复选框值checkboxesAsBools,并忽略序列化数据中未提及的复选框:https : //github.com/itsadok/jquery.deserialize


2
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();

3
你能解释一下你的答案吗?
2013年

此答案将复选框修改为隐藏字段,因此可以序列化。但是,由于对DOM进行了修改,因此该答案使表单可以一次性使用。
格兰特(Grant)

2

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

示例:普通提交

$('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());

2

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

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

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

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


1
serializeObject()似乎是一个jQuery插件:plugins.jquery.com/serializeObject
iCode


1

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

此外,“选择”在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);

1

我遇到了类似的问题,以下内容使我可以收集所有表单输入值和已选中/未选中的复选框。

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

“ this。$”特定于我为此解决方案使用的Zendesk应用程序框架。
wooz16 '16

1

本示例假定您要通过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);

我喜欢not(:checked)选择器
BernhardDöbler,

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

有时未选中意味着其他值,例如,选中可能意味着是未选中的否或0,1等,这取决于您要赋予的含义..因此可能是除“未选中意味着它根本不在查询字符串中”的另一种状态

“这将使在DB中存储信息变得容易得多。因为然后Serialize中的字段数将等于表中的字段数。现在我必须控制缺少的字段”,您也是对的。 ..所以看来我必须检查这个不存在的值....

但这可能是一个解决方案? http://tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/


1
如果不存在导致问题,则应使用<select>带有yes / no选项的a,而不是创建与HTML规范定义要提交的表单的方式不符的内容。
安迪E

0

只需添加一个隐藏的输入

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

不需要价值,我测试了对我有用


1
请详细说明。尝试添加代码示例,并可能链接到文档。
Yotam Omer

0

您可以使用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>


0

为了扩展上面的答案,就我而言,我需要针对序列化到后端捕获的单个ID发送是/否。

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

(Laravel刀片)

<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 );

0

我已经使用这种方式,并获得值“ 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';
    });

-1

试试这个:

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


-1

我发布了对我有用的解决方案!

var form = $('#checkboxList input[type="checkbox"]').map(function() {
               return { name: this.name, value: this.checked ? this.value : "false" };
            }).get();

var data = JSON.stringify(form);

data value is : "[{"name":"cb1","value":"false"},{"name":"cb2","value":"true"},{"name":"cb3","value":"false"},{"name":"cb4","value":"true"}]"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.