简体   繁体   English

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

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

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然后在表单上运行 jQuery.serializeArray()

the value set for the foo element is "no"为 foo 元素设置的值为“no”

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

Shouldn't serializeArray() emulate browser behaviour?不应该 serializeArray() 模拟浏览器行为吗? If so, shouldn't it return "yes" if checkbox is checked?如果是这样,如果选中复选框,它不应该返回“是”吗?

I am using jQuery v1.10.2我正在使用 jQuery v1.10.2

In a short word: No. The serializeArray method only returns the checkbox in the case it is checked.在一个短字:否serializeArray方法只返回在检查的情况下的复选框。 Thus, it will ignore it as long as it remains unchecked.因此,只要它保持未选中状态,它就会忽略它。 In case you checked it, though, it wiill return the value of your input directly.但是,如果您检查它,它将直接返回您输入的值。

Check out the demo at http://api.jquery.com/serializearray/ .http://api.jquery.com/serializearray/查看演示。

Using serializeArray on a form with multiple inputs of the same name returns more than one object for each element (if checked).在具有多个同名输入的表单上使用serializeArray为每个元素返回多个对象(如果选中)。 This means that the following HTML will return the following object.这意味着以下 HTML 将返回以下对象。 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.因此,我假设您尝试将数据操作到 1 个对象中,或者将其发布到服务器,该服务器仅考虑具有该键的第一个值中的数据。 You just need to make sure that any checkbox element takes precedence.您只需要确保任何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 serializeArray with the same name.另一种方法是去掉隐藏字段,然后在提交表单之前检查每个未选中的复选框,并检查serializeArray是否有任何同名的数据。 If not just add it in there as a off .如果不只是将它添加到那里作为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演示

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 serialize method, 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.如果您的后端系统感到困惑并且选择了错误的值,请颠倒您的复选标记和隐藏元素的顺序。

FACT : jQuery serializeArray() does not include unchecked checkboxes that probably we DO need them sent to server (no problem for radios though).事实:jQuery的serializeArray()不包括可能我们确实需要它们发送到服务器(没问题无线电虽然)选中复选框。

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.因此,空值表示未选中的复选框。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>

<form url="http://application.localdev/api/v1/register" method="post" id="formReg" accept-charset="utf-8">
    <input type="email" placeholder="email" name="email"><br>
    <input type="text" placeholder="firstname" name="firstname"><br>
    <input type="text" placeholder="lastname" name="lastname"><br>
    <input type="number" placeholder="zip_code" name="zip_code"><br>
    <input type="checkbox" name="general" value="true"> general<br>
    <input type="checkbox" name="marketing" value="true"> marketing<br>
    <input type="checkbox" name="survey" value="true"> survey<br>
    <button type="submit">save</button>
</form>

<script>
    $(document).ready(function() {
        $('#formReg').on('submit', function(e){
            // validation code here
                        
            e.preventDefault();


                            
            var values = {};
            $.each($('#formReg').serializeArray(), function(i, field) {
                values[field.name] = field.value;
            });

            $('input[type="checkbox"]:not(:checked)').each(function(){
                if($.inArray(this.name, values) === -1){
                    values[this.name] = $(this).prop('checked')
                }
            });

            console.log(values)
        });
    });
</script>

serializeArray doesn't return unchecked checkbox. serializeArray不会返回未选中的复选框。 I try this instead of serializeArray :我尝试这个而不是serializeArray

$('input, select, textarea').each(
   function(index){  
       var input = $(this);
       alert('Type: ' + input.attr('type') + 'Name: ' + input.attr('name') + 
       'Value: ' + input.val());
   }
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM