最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin5浏览0评论

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

the value set for the foo element is "no"

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

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

I am using jQuery v1.10.2

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

the value set for the foo element is "no"

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

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

I am using jQuery v1.10.2

Share Improve this question asked Jun 21, 2014 at 4:07 developarvindeveloparvin 5,08712 gold badges57 silver badges101 bronze badges 2
  • 2 Try with different name for hidden and checkbox type input. – dotnetstep Commented Jun 21, 2014 at 4:10
  • @dotnetstep The same names are intentional since this is just one value that I want to pass. – developarvin Commented Jun 21, 2014 at 4:16
Add a comment  | 

6 Answers 6

Reset to default 5

In a short word: No. The serializeArray method only returns the checkbox in the case it is checked. 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/ .

Using serializeArray on 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 checkbox element takes precedence.

Returned Object:

[
    {
        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

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. If not just add it in there as a 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

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

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!!!

So, an empty value denotes a unchecked checkbox.

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.

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.

<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. I try this instead of serializeArray:

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

评论列表(0)

  1. 暂无评论