javascript jQuery - serializeArray() 未获取选中复选框的值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24338177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 02:35:44  来源:igfitidea点击:

jQuery - serializeArray() is not getting the value of the checked checkbox

javascriptjqueryhtmlcheckbox

提问by developarvin

I have a checkbox in a form that acts as a flag.

我有一个复选框,它作为一个标志。

In order to do it, I added a hidden input element so that if the checkbox is not checked, something will still be saved

为了做到这一点,我添加了一个隐藏的输入元素,以便如果未选中复选框,仍会保存某些内容

<form action="">
    ...
        <input type="hidden" name="foo" value="no" />
        <input type="checkbox" name="foo" value="yes">
    ...
</form>

The problem I am having is that when I

我遇到的问题是,当我

  1. check the checkbox
  2. then run jQuery.serializeArray() on the form
  1. 选中复选框
  2. 然后在表单上运行 jQuery.serializeArray()

the value set for the foo element is "no"

为 foo 元素设置的值为“no”

Object { name="foo", value="no"}

Shouldn't serializeArray() emulate browser behaviour? If so, shouldn't it return "yes" if checkbox is checked?

不应该 serializeArray() 模拟浏览器行为吗?如果是这样,如果选中复选框,它不应该返回“是”吗?

I am using jQuery v1.10.2

我正在使用 jQuery v1.10.2

回答by Eric Wu

In a short word: No. The serializeArray method only returns the checkbox in the case it ischecked. Thus, it will ignoreit as long as it remains unchecked. In case you checked it, though, it wiill return the value of your input directly.

在一个短字:否serializeArray方法只返回在它的情况下的复选框选中。因此,只要它保持未选中状态,它就会忽略它。但是,如果您检查它,它将直接返回您输入的值。

Check out the demo at http://api.jquery.com/serializearray/.

http://api.jquery.com/serializearray/查看演示。

回答by Adam Merrifield

Using serializeArrayon a form with multiple inputs of the same name returns more than one object for each element (if checked). This means that the following HTML will return the following object. So the data in question is there and is available. Because of this I'm assuming that you're attempting to either manipulate the data to be in 1 object or you're posting it to a server which is only taking into account the data from the first value with that key. You just need to make sure that any checkboxelement takes precedence.

使用serializeArray具有相同名称返回多于一个对象的每个元素(如果选中)的多个输入的形式。这意味着以下 HTML 将返回以下对象。所以有问题的数据就在那里并且是可用的。因此,我假设您尝试将数据操作为 1 个对象,或者将其发布到服务器,该服务器仅考虑来自具有该键的第一个值的数据。您只需要确保任何checkbox元素优先。

Returned Object:

返回对象:

[
    {
        name:"foo",
        value:"no"
    },
    {
        name:"foo2",
        value:"no"
    },
    {
        name:"foo2",
        value:"yes"
    }
] 

HTML:

HTML:

<form>
    <input type="hidden" name="foo" value="no" />
    <input type="checkbox" name="foo" value="yes" />

    <input type="hidden" name="foo2" value="no" />
    <input type="checkbox" name="foo2" value="yes" checked />
</form>

JS:

JS:

console.log($('form').serializeArray());

DEMO

演示

Another way you can do this is get rid of the hidden fields and before you submit the form go through each unchecked checkbox and check if there is any data in the serializeArraywith the same name. If not just add it in there as a off.

另一种方法是去掉隐藏的字段,在提交表单之前,检查每个未选中的复选框,并检查是否有任何serializeArray同名的数据。如果不只是将它作为off.

$('#submit').on('click', function(){
    var arr = $('form').serializeArray(),
        names = (function(){
            var n = [],
                l = arr.length - 1;
            for(; l>=0; l--){
                n.push(arr[l].name);
            }

            return n;
        })();

    $('input[type="checkbox"]:not(:checked)').each(function(){
        if($.inArray(this.name, names) === -1){
            arr.push({name: this.name, value: 'off'});
        }
    });

    console.log(arr);
});

DEMO

演示

回答by Jeremy J Starcher

Using the same name for multiple fields is problematic at best and there is no standardized way that front end systems, or back end systems, will handle it.

对多个字段使用相同的名称充其量是有问题的,并且前端系统或后端系统没有标准化的方法来处理它。

The only reason to use the same name is if you are trying to pass some kind of a default value, like you are in the case below, where you are doing a simple yes/no.

使用相同名称的唯一原因是,如果您尝试传递某种默认值,就像下面的情况一样,您正在执行简单的是/否。

What you want, to emulate the browser, is serializemethod, not the serializeArray.

要模拟浏览器,您想要的是serialize方法,而不是serializeArray.

I added the form to a page -- from my console:

我将表单添加到页面 - 从我的控制台:

JSON.stringify(f.serializeArray());
"[{"name":"foo","value":"no"}]"

NO checkmark

没有复选标记

JSON.stringify(f.serialize());
""foo=no""

Checkmark

复选标记

JSON.stringify(f.serialize());
""foo=yes&foo=no""

If your back end system gets confused and is picking up the wrong value, reverse the order of your checkmark and hidden element.

如果您的后端系统感到困惑并且选择了错误的值,请颠倒您的复选标记和隐藏元素的顺序。

回答by centurian

FACT: jQuery serializeArray()does not include unchecked checkboxes that probably we DOneed them sent to server (no problem for radios though).

事实:jQuery的serializeArray()不包括可能是我们选中的复选框DO需要它们发送到服务器(没问题无线电虽然)。

SOLUTION: create a new serialize:

解决方案:创建一个新的序列化

//1. `sel` any collection of `form` and/or `input`, `select`, `textarea` 
//2. we assign value `1` if not exists to radios and checkboxes
// so that the server will receive `1` instead of `on` when checked
//3. we assign empty value to unchecked checkboxes 
function serialize(sel) {
   var arr,
       tmp,
       i,
       $nodes = $(sel);

   // 1. collect form controls
   $nodes = $nodes.map(function(ndx){
      var $n = $(this);

      if($n.is('form'))
         return $n.find('input, select, textarea').get();
      return this;
    });

   // 2. replace empty values of <input>s of type=["checkbox"|"radio"] with 1 
   // or, we end up with "on" when checked
   $nodes.each(function(ndx, el){
      if ((el.nodeName.toUpperCase() == 'INPUT') && ((el.type.toUpperCase() == 'CHECKBOX') || (el.type.toUpperCase() == 'RADIO'))){
         if((el.value === undefined) || (el.value == ''))
            el.value = 1;
      }
   });

   // 3. produce array of objects: {name: "field attribute name", value: "actual field value"}
   arr = $nodes.serializeArray();
   tmp = [];
   for(i = 0; i < arr.length; i++)
      tmp.push(arr[i].name);

   // 4. include unchecked checkboxes
    $nodes.filter('input[type="checkbox"]:not(:checked)').each(function(){
      if(tmp.indexOf(this.name) < 0){
         arr.push({name: this.name, value: ''});
      }
    });

   return arr;
}

The reason we assigned empty string to unchecked checkboxes is because a checked one will submit it's value to server which is set in html and can be a zero!!!

我们将空字符串分配给未选中的复选框的原因是因为选中的复选框会将其值提交给在 html 中设置的服务器,并且可以为零!!!

So, an empty value denotes a unchecked checkbox.

因此,空值表示未选中的复选框。