2014-06-21 323 views
1

我有一个复选框作为一个标志的形式。jQuery的 - serializearray()没有得到选中的复选框的值

为了做到这一点,我添加了一个隐藏的输入元素,因此如果未选中该复选框,东西仍然被保存

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

我遇到的问题是,当我

  1. 选中复选框
  2. 然后形式上运行jQuery.serializeArray()

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

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

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

我使用jQuery v1.10.2的

+1

尝试用隐藏和checkbox类型的输入不同的名称。 – dotnetstep

+0

@dotnetstep相同的名字是故意的,因为这只是我想传递的一个值。 – arvinsim

回答

1

在很短的一句话:否。serializeArray方法只返回它检查的情况下的复选框。因此,只要未被选中,它就会忽略。 但是,如果您检查了它,它将直接返回您输入的值。

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

2

在具有多个同名输入的表单上使用serializeArray会为每个元素返回多个对象(如果选中)。这意味着以下HTML将返回以下对象。所以有问题的数据在那里并且可用。正因为如此,我假设你试图将数据操作为1个对象,或者将它发布到服务器,该服务器仅考虑来自具有该密钥的第一个值的数据。你只需要确保任何checkbox元素都优先。

返回的对象:

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

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:

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

DEMO

另一种方法可以做到这一点的就是摆脱隐藏的字段,并且在您提交表单之前,请检查每个未选中的复选框,并检查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

+1

所以你说serializeArray()不能决定提交哪个值,不像没有JS的普通表单发布那样呢? – arvinsim

+0

不,当数据通过$ .post('url',$('form')。serializeArray())发送时;'它发送两个数据。我只是显示两个数据都被记录下来,两个数据都通过ajax发布。这意味着你的服务器没有正确读取数据,很可能是因为2个元素相同。我建议你从复选框中删除名称,并在更改时更新隐藏字段以消除混淆。我会在我的回答中暂时添加此代码。 –

+0

@arvinsim我已经更新了我的答案的底部,以包含另一种方式,而不使用任何隐藏字段。这将真正帮助摆脱任何混淆,为自己和服务器接收这些数据。 –

0

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

使用相同名称的唯一原因是,如果你想通过某种默认值,就像你在下面的情况下,你在哪里做一个简单的是/否。

你想要什么,模仿浏览器,是serialize方法,而不是serializeArray

我加入了形式到页面 - 从我的控制台:

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

NO对号

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

对号

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

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

+0

奇怪的是我尝试了serialize(),它获得了与serializeArray()相同的行为。也就是说,即使复选框被选中,它仍然只传递“foo = no”。 – arvinsim

+0

当你说*它只通过*,你从哪里得到这些信息?如果您的后台只显示一个值,这是正常和正确的。 –

+0

我使用了这个'console.info(JSON.stringify(formElement.serialize()));'在执行AJAX提交的代码之前。 – arvinsim