【问题标题】:How can I serializeArray for unchecked checkboxes?如何为未选中的复选框序列化数组?
【发布时间】:2011-11-12 05:05:41
【问题描述】:

我如何modify this example 才能从未选中的复选框中获取值?

我希望所有复选框都有一个值,如果尚未选中,我希望将其值设为false

<input type="checkbox" name="Check01" value="true" />
<input type="checkbox" name="Check02" value="true" checked="checked" />

默认行为

$("form").serializeArray();
// [Check02 = true]

预期行为

$("form").serializeArray();
// [Check01 = false, Check02 = true]

【问题讨论】:

  • 这是一个糟糕的方法。您应该在服务器端收集所有可用值(并最终使用它来自动生成复选框)并在表单提交时将其与提交的选中值相交以获得未选中值。
  • @BalusC 如果复选框用作开关而不是集合怎么办?然后需要一个真/假值,除非您想在服务器端对提交的值进行大量检查。
  • @mwieczorek: 默认使用false
  • 是的,但在严格类型的语言中(或 PHP 中的严格模式,应该 always 开启),POST 数组/对象不会包含未选中的复选框,如果引用会抛出异常。这只是另一个if 或三元语句来检查键是否存在于数组或对象中。

标签: javascript jquery forms


【解决方案1】:

自己动手可能是最简单的:

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

如果还有其他输入,那么您可以序列化表单,然后找到类似上述内容的未选中复选框并将该结果附加到第一个数组。

【讨论】:

  • 你如何将其他输入的值附加到这个serializedObj
  • @Smith 你会做类似serialized.push({name: "something", value: "whatever"});
【解决方案2】:

serializeArray 忽略未选中的复选框。您可以尝试这样的操作。

工作demo

    var serializedObj = {};
    $("form input:checkbox").each(function(){
        serializedObj[this.name] = this.checked;
    });

【讨论】:

  • 你如何将其他输入的值附加到这个serializedObj
  • serializeArray 忽略未选中的复选框 这确实需要突出显示
  • 虽然认识到你有两个选择,使用真/假,或者在选中时使用复选框的值,在未选中时使用另一个值,例如空字符串或未定义。
【解决方案3】:

你可以使用这个获取未检查的值

$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
    if (o[this.name] !== undefined) {
        if (!o[this.name].push) {
            o[this.name] = [o[this.name]];
        }
        o[this.name].push(this.value || '');
    } else {
        o[this.name] = this.value || '';
    }
});
var $radio = $('input[type=radio],input[type=checkbox]',this);
$.each($radio,function(){
    if(!o.hasOwnProperty(this.name)){
        o[this.name] = '';
    }
});
return o;
};

code samples

【讨论】:

    【解决方案4】:

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

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

    (function ($) {
        var _base_serializeArray = $.fn.serializeArray;
        $.fn.serializeArray = function () {
            var a = _base_serializeArray.apply(this);
            $.each(this.find("input"), 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

    更新:修复了基于 @shyammakwana.me 发现的错误的代码。

    【讨论】:

    • 呃哦,这段代码错误的很危险!它假定基本 serializeArray 结果具有与 find("input") 的顺序完全相同的顺序和内容。但是,如果您的表单有 textarea 或 select,您最终会通过将 true/false 分配给错误的字段来破坏表单值!
    【解决方案5】:

    另一种选择是只查看 serializeArray 的源代码并删除(或修改)对过滤器的调用。我刚刚使用了该函数并创建了一个名为 serializeArrayAll 的新函数,如下所示:

    $.fn.serializeArrayAll = function() {
      var rCRLF = /\r?\n/g;
      return this.map(function(){
          return this.elements ? jQuery.makeArray( this.elements ) : this;
      })
      /* this is what is excluding the unchecked checkboxes (and also other disabled options) 
          .filter(function(){
            return this.name && !this.disabled &&
                ( 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( rCRLF, "\r\n" ) };
                  }) :
              { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
      }).get();
    };
    

    【讨论】:

      【解决方案6】:

      您可以为每个复选框添加一个隐藏的 false 值:

      <input type="checkbox" name="Check01" value="true" /><input name="Check01" type="hidden" value="false" />
      <input type="checkbox" name="Check02" value="true" checked="checked" /><input name="Check02" type="hidden" value="false" />
      

      对于未选中的复选框,您只会获得“false”值,而对于选中的复选框,您只会获得“true”和“false”,因此您可以像这样删除重复项:

      var params = {};
      $.each($('form').serializeArray(), function (index, value) {
          params[value.name] = params[value.name] ? params[value.name] || value.value : value.value;
      });
      console.log(params); // outputs: {"Check01":"false","Check02":"true"}
      

      【讨论】:

        【解决方案7】:

        我根据@Pointy、@Ben 和原始 jQuery 代码的答案制作了自己的新解决方案。 @Pointy 的答案有奇怪的行为,它返回了复选框的上下文,这解决了这个问题。 @Ben 的回答也没有正常工作,因为它总是返回 checkbox = on,即使它没有被选中。

        $.fn.serializeArrayWithCheckboxes = function() {
        var rCRLF = /\r?\n/g;
        return this.map(function(){
            return this.elements ? jQuery.makeArray( this.elements ) : this;
        })
        
            .map(function( i, elem ){
                var val = jQuery( this ).val();
        
        
                if (val == null) {
                  return val == null
                //next 2 lines of code look if it is a checkbox and set the value to blank 
                //if it is unchecked
                } else if (this.type == "checkbox" && this.checked == false) {
                  return { name: this.name, value: this.checked ? this.value : ""}
                //next lines are kept from default jQuery implementation and 
                //default to all checkboxes = on
                } else {
                  return jQuery.isArray( val ) ?
                        jQuery.map( val, function( val, i ){
                            return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                        }) :
                    { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                }
            }).get();
        };
        

        【讨论】:

        • return val == null 将返回 true 如果值为空。此外,this.checked 在 else if 中进行检查,仅当 this.checked 为 == false 时才输入。
        【解决方案8】:

        使用jQuery插件serializeJSON,可以使用data-unchecked-value属性来指定不勾选时的值:

        <input type="checkbox" name="Check01" value="true" data-unchecked-value="false" />
        <input type="checkbox" name="Check02" value="true" data-unchecked-value="false" checked="checked" />
        

        JavaScript:

        $('input').serializeJSON({ parseBooleans: true });
        // returns => { 'Check01' : false, 'Check02' : true }
        

        【讨论】:

          【解决方案9】:

          @SNag's answer 工人几乎 99% 只是稍作修正。 更改以下行

          来自:

          $.each(this, function (i, e) {
          

          到:

          $.each(this.find('input'), function (i, e) {
          

          解释:因为this 返回了表单元素,所以这不起作用。所以在表单.each 上不会给我们表单内的所有输入元素。所以我做了这个更正,它就像魅力一样。

          【讨论】:

          • 感谢您的修复!
          【解决方案10】:

          又一个 SerializeArray()

          这个实现再次基于 jQuery 的原始代码,但我需要它用于一些具有两个不同值的 Bootstrap's "switch" checkboxes

          $.fn.serializeArrayWC = function() {
              var rCRLF = /\r?\n/g;
              return this.map(function(){
                  return this.elements ? jQuery.makeArray( this.elements ) : this;
              })
              .map(function(i, elem){
                  if (this.type == "checkbox") {
                      // Bootstrap checkboxes with two different values.
                      if (jQuery(this).hasClass("switched")) {
                          // Always return value (either on-value or off-value).
                          return { name: this.name, value: this.value };
                      }
                      // Normal checkboxes. Unchecked checkboxed are not returned.
                      if (!this.checked) {
                          // This will be removed by the !!f filter, below.
                          return false;
                      }
                      // Return the value, or "on".
                      return { name: this.name, value: this.value||"on" };
                  }
                  var val = jQuery(this).val();
                  if (val == null) {
                      return { name: elem.name, value: null };
                  } else {
                      return jQuery.isArray(val) ?
                          jQuery.map( val, function( val, i ){
                              return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                          }) :
                      { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                  }
              })
              .filter(function(i, f){ return !!f; })
              .get();
          };
          

          【讨论】:

            【解决方案11】:

            您可以将未选中的复选框数据附加到.serializeArray 结果:

            var formData = $("#mybaseelement").serializeArray();
            $('#mybaseelement input[type="checkbox"]:not(:checked)').each(function(i, e) {
                formData.push({name: e.getAttribute("name"), value: false});
            });
            

            这是我能想到的侵入性最小的解决方案。

            【讨论】:

              【解决方案12】:
              var fields = $("form").serializeArray();
              $('form input[type=checkbox]').map(function() {
                 if( !this.checked )
                      {
                              fields.push({ name: this.name, value: "off" });
                      }
                 });
              

              【讨论】:

              • 不鼓励仅使用代码的答案。请单击edit 并添加一些词来总结您的代码如何解决问题,或者解释您的答案与之前的答案/答案有何不同。 From Review
              猜你喜欢
              • 2010-11-14
              • 1970-01-01
              • 2021-05-20
              • 1970-01-01
              • 2020-02-10
              • 2011-07-04
              • 2011-07-27
              • 1970-01-01
              • 2012-08-19
              相关资源
              最近更新 更多