jQuery serialize does not register checkboxes

JquerySerialization

Jquery Problem Overview


I'm using jQuery.serialize to retrieve all data fields in a form.

My problem is that it does not retriev checkboxes that is not checked.

It includes this:

<input type="checkbox" id="event_allDay" name="event_allDay" class="checkbox" checked="checked" />

but not this

<input type="checkbox" id="event_allDay" name="event_allDay" class="checkbox" />

How can I get "values" of checkboxes that is not checked?

Jquery Solutions


Solution 1 - Jquery

To build on azatoth's genius answer, I have slightly extended it for my scenario:

    /* Get input values from form */
    values = jQuery("#myform").serializeArray();

    /* Because serializeArray() ignores unset checkboxes and radio buttons: */
    values = values.concat(
            jQuery('#myform input[type=checkbox]:not(:checked)').map(
                    function() {
                        return {"name": this.name, "value": false}
                    }).get()
    );

Solution 2 - Jquery

jQuery serialize closely mimics how a standard form would be serialized by the browser before being appended to the query string or POST body in the request. Unchecked checkboxes aren't included by the browser, which makes sense really because they have a boolean state -- they're either selected by the user (included) or not selected by the user (not included).

If you need it to be in the serialized, you should ask yourself "why? why not just check for its existence in the data?".

Bear in mind that if the way JavaScript serializes form data behaves differently to the way the browser does it then you're eliminating any chance of graceful degradation for your form. If you still absolutely need to do it, just use a <select> box with Yes/No as options. At least then, users with JS disabled aren't alienated from your site and you're not going against the defined behaviour in the HTML specification.

<select id="event_allDay" name="event_allDay">
   <option value="0" selected>No</option>
   <option value="1">Yes</option>
</select>

I've seen this employed on some sites in the past and always thought to myself, "why don't they just use a checkbox"?

Solution 3 - Jquery

You don't, as serialize is meant to be used as an query string, and in that context, unchecked means it's not in the querystring at all.

If you really want to get the values of unchecked checkboxes, use: (untested off course)

var arr_unchecked_values = $('input[type=checkbox]:not(:checked)').map(function(){return this.value}).get();

Solution 4 - Jquery

if you want to add unserialized checkboxes to your query string, add the following to your jquery submit function:

var moreinfo = '';

$('input[type=checkbox]').each(function() {		
	if (!this.checked) {
	    moreinfo += '&'+this.name+'=0';
	}
});

Solution 5 - Jquery

jQuery serialize gets the value attribute of inputs.

Now how to get checkbox and radio button to work? If you set the click event of the checkbox or radio-button 0 or 1 you will be able to see the changes.

$( "#myform input[type='checkbox']" ).on( "click", function(){
     if ($(this).prop('checked')){
          $(this).attr('value', 1);
     } else {
          $(this).attr('value', 0);
     }
 }); 

 values = $("#myform").serializeArray();

and also when ever you want to set the checkbox with checked status e.g. php

<input type='checkbox' value="<?php echo $product['check']; ?>" checked="<?php echo $product['check']; ?>" />

Solution 6 - Jquery

Here's another solution that extends the "serializeArray" method (while preserving the original behavior).

//Store the reference to the original method:

var _serializeArray = $ji.fn.serializeArray;

//Now extend it with newer "unchecked checkbox" functionality:
$ji.fn.extend({
    serializeArray: function () {
        //Important: Get the results as you normally would...
        var results = _serializeArray.call(this);

        //Now, find all the checkboxes and append their "checked" state to the results.
        this.find('input[type=checkbox]').each(function (id, item) {
            var $item = $ji(item);
            var item_value = $item.is(":checked") ? 1 : 0;
            var item_name = $item.attr('name');
            var result_index = null;
            results.each(function (data, index) {
                if (data.name == item_name) {
                    result_index = index;
                }
            });

            if (result_index != null) {
                // FOUND replace previous value
                results[result_index].value = item_value;
            }
            else {
                // NO value has been found add new one
                results.push({name: item_name, value: item_value});
            }
        });
        return results;
    }
});

This will actually append "true" or "false" boolean results, but if you prefer you can use "1" and "0" respectively, by changing the value to value: $item.is(":checked") ? 1 : 0.

Usage

Just as usual, call the method on your form: $form.serialize() or $form.serializeArray(). What happens is that serialize makes use of serializeArray anyways, so you get the proper results (although different format) with whichever method you call.

Solution 7 - Jquery

You can call handleInputs() add in your submit function before ajax

function handleInputs(){
    $('input[type=checkbox]').each(function() {     
        if (!this.checked) {
            $(this).attr("value","0");
        }else{
            $(this).attr("value","1");
        }
    });
}

It is perfectly working

Solution 8 - Jquery

A technique I've used in my own systems, and which I believe is employed by Struts, is to include...

<input type="hidden" name="_fieldname" value="fieldvalue"/> 

...immediately next to the checkbox as part of my form creation logic.

This allows me to reconstruct which checkboxes were served in the form but not selected, with a tiny bit of extra logic to do the diff what was served and what was checked, you have the ones which were unchecked. The submission is also the same in content regardless whether you're using HTML or AJAX style submission.

Depending on the technology you're using server-side then you may wish to use this syntax...

<input type="hidden" name="_fieldname[]" value="fieldvalue"/>

...to make it easy to grab these values as a list.

Solution 9 - Jquery

The trick is to intercept the form post and change the check boxes to hidden input fields.

Example: Plain Submit

$('form').on("submit", function (e) {
    //find the checkboxes
    var $checkboxes = $(this).find('input[type=checkbox]');

    //loop through the checkboxes and change to hidden fields
    $checkboxes.each(function() {
        if ($(this)[0].checked) {
            $(this).attr('type', 'hidden');
            $(this).val(1);
        } else {
            $(this).attr('type', 'hidden');
            $(this).val(0);
        }
    });
});

Example: AJAX

You need to jump through a few more hoops if you are posting the form via ajax to not update the UI.

$('form').on("submit", function (e) {
    e.preventDefault();

    //clone the form, we don't want this to impact the ui
    var $form = $('form').clone();

    //find the checkboxes
    var $checkboxes = $form.find('input[type=checkbox]');

    //loop through the checkboxes and change to hidden fields
    $checkboxes.each(function() {
        if ($(this)[0].checked) {
            $(this).attr('type', 'hidden');
            $(this).val(1);
        } else {
            $(this).attr('type', 'hidden');
            $(this).val(0);
        }
    });

    $.post("/your/path", $form.serialize());

Solution 10 - Jquery

For ASP.NET MVC, we successfully save a form with checkboxes via an AJAX POST with the following, which is a combination of several methods referenced in this post, including @Jecoms suggestion:

var form = $('#myForm');
// Serialize the form into a JavaScript object using the jQuery.serializeObject plugin
// https://plugins.jquery.com/serializeObject/
var data = form.serializeObject();
// Change the submitted value of checkboxes to the value of the checked property
$('#myForm input[type=checkbox]').each( function () { data[this.name] = this.checked; } );
// For a MVC controller, convert the JS object back into a query string using jQuery.param function
data = $.param(data);
// Perform AJAX POST with the form data
$.ajax({
	async: true,
	url: 'mvcActionMethodURL',
	type: 'POST',
	data: data,
	success: function (data, textStatus, xhr) {
		
	},
	error: function (xhr, status, error) {
		
	}
});

Solution 11 - Jquery

One reason for using non-standard checkbox serialization that isn't addressed in the question or in of the current answers is to only deserialize (change) fields that were explicitly specified in the serialized data - e.g. when you are using jquery serialization and deserialization to/from a cookie to save and load prefererences.

Thomas Danemar implemented a modification to the standard serialize() method to optionally take a checkboxesAsBools option: http://tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/ - this is similar to the implementation listed above by @mydoghasworms, but also integrated into the standard serialize.

I've copied it to Github in case anyone has improvements to make at any point: https://gist.github.com/1572512

Additionally, the "jquery.deserialize" plugin will now correctly deserialize checkbox values serialized with checkboxesAsBools, and ignore checkboxes that are not mentioned in the serialized data: https://github.com/itsadok/jquery.deserialize

Solution 12 - Jquery

var checkboxes = $('#myform').find('input[type="checkbox"]');
$.each( checkboxes, function( key, value ) {
	if (value.checked === false) {
		value.value = 0;
	} else {
		value.value = 1;
	}
	$(value).attr('type', 'hidden');
});
$('#myform').serialize();

Solution 13 - Jquery

This will set your form checkbox values to booleans using their checked state.

var form = $('#myForm');
var data = form.serializeObject();

$('#myForm input[type=checkbox]').each(function() { data[this.name] = this.checked; });

The framework we use creates two inputs with the same name, which leads to unexpected behavior when serializing the form. I would get each checkbox value parsed as a two-element array with string values. Depending on how you map data server-side, you may get unintended results.

Solution 14 - Jquery

Using select fields as suggested by Andy is not necessarily the best option for the user experience since it needs two mouse clicks instead of one.

Moreover, a "Select" uses much more space in the UI than a checkbox.

Ash's answer is a simple solution but does not work in the case of array fields.

In my context, I have a variable length form, that holds rows displaying a mix of text and checkbox fields :

<input type="checkbox" value="1" name="thisIsAChkArray[]"/> 
<input type="text" value="" name="thisIsATxtArray[]"/>

For decoding the posted data, the order of the array elements is important. Just appending the non-checked items to a regular Jquery serialize does not keep the order of the row elements.

Here is a proposed solution based on Ash's answer :

(function($) {
  $.fn.serializeWithChkBox = function() {
    // perform a serialize form the non-checkbox fields
    var values = $(this).find('select')
                        .add(  $(this).find('input[type!=checkbox]') )
                        .serialize();
    // add values for checked and unchecked checkboxes fields
    $(this).find('input[type=checkbox]').each(function() {
      var chkVal = $(this).is(':checked') ? $(this).val() : "0";
      values += "&" + $(this).attr('name') + "=" + chkVal;
    });
    return values;
  }
})(jQuery);

Solution 15 - Jquery

I had a similar problem and the following allowed me to collect all form input values and checked/unchecked checkboxes.

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

Solution 16 - Jquery

This example assumes you want to post a form back via serialize and not serializeArray, and that an unchecked checkbox means false:

var form = $(formSelector);
var postData = form.serialize();

var checkBoxData = form.find('input[type=checkbox]:not(:checked)').map(function () {
    return encodeURIComponent(this.name) + '=' + false;
}).get().join('&');

if (checkBoxData) {
    postData += "&" + checkBoxData;
}

$.post(action, postData);

Solution 17 - Jquery

For those using the serialize() function:

(function ($) {
    var serialize = $.fn.serialize;

    $.fn.serialize = function () {
        let values = serialize.call(this);
        let checkboxes = [];

        checkboxes = checkboxes.concat(
            $('input[type=checkbox]:not(:checked)', this).map(
            function () {
                return this.name + '=false';
            }).get()
        );

        if(checkboxes.length > 0)
            values = checkboxes.join('&') + '&' + values;

        return values;
    };
})(jQuery);

Solution 18 - Jquery

sometimes unchecked means other values, for instance checked could mean yes unchecked no or 0,1 etc it depends on the meaning you want to give.. so could be another state besides "unchecked means it's not in the querystring at all"

"It would make it a lot easier to store information in DB. Because then the number of fields from Serialize would equal the number of fields in table. Now I have to contrll which ones are missing", youre right this is my problem too... so it appears i have to check for this nonexisting value....

but maybe this could be a solution? http://tdanemar.wordpress.com/2010/08/24/jquery-serialize-method-and-checkboxes/

Solution 19 - Jquery

just simply add a hidden input

<input type="hidden" name="your_specific_name">

doesn't need value,i tested this works for me

Solution 20 - Jquery

You Can Get inputs value with jquery serialize

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" id="event_allDay" name="event_allDay" checked="checked" onchange="isChecked(this)" value="" />
<script>
    function isChecked(element) {
        $(element).val($(element).is(':checked').toString());
    }
    isChecked('#event_allDay');
</script>

Solution 21 - Jquery

Just to expand on the answer(s) above, in my case, I required sending a yes/no against a single ID serialized to my backend catch.

I set the checkbox elements to contain the ID of a particular database column, aka (default checked):

(Laravel Blade)

<div class="checkbox">
    <label>
        <input type="checkbox" value="{{ $heading->id }}" checked> {{ $heading->name }}
    </label>
</div>

When I did my submission, I grabbed the data with:

(jQuery)

let form = $('#formID input[type="checkbox"]').map(function() {
                return { id: this.value, value: this.checked ? 1 : 0 };
           }).get();

var data = JSON.stringify(form);
$.post( "/your/endpoint", data );

Solution 22 - Jquery

I have used this way and getting values "0" or if checked "1". This telling that if checkbox input name is not exist in serialized form_data then it means it is not checked then add value as zero (form_data += '&' + name + '=0'), but if checked serialize() function automatically adds it.

   /*get all other form inputs*/ 
   var form_data = form.serialize();

    /*get checkboxes*/
    $.each($("#form_id input[type='checkbox']"), function(){
        var name = $(this).attr('name');
        if(form_data.indexOf(name)===-1)form_data += '&' + name + '=0';
    });

Solution 23 - Jquery

I'm using another way that works for me :

Serialize form data (as specified above, will exclude checkboxes' values that are unchecked) :

const formData = $("form[name='config']").serialize();
const data = {
                config: formData
            }

Then, in PHP, I'm building a JSON object :

parse_str($_REQUEST['config'], $configJSON);
$configJSON = json_encode($configJSON);

And in MSSQL, in my stored procedure when a column is missing from the JSON (because it's been filtered out by the jquery serialization) it will be NULL and so will be replaced by 0 (thanks to ISNULL function) :

ALTER PROCEDURE [dbo].[eth_userprofil_updateconfig]
(
	@userId int, 
	@configJSON nvarchar(max)
)	
AS
BEGIN
	SET NOCOUNT ON;
	
	UPDATE dbo.MyTable
	SET MyField = ISNULL(JSON_VALUE(@configJSON, '$.MyField '), 0),
		....
	WHERE userId = @userId
END

Solution 24 - Jquery

Try this:

$(':input[type="checkbox"]:checked').map(function(){return this.value}).get();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStevenView Question on Stackoverflow
Solution 1 - JquerymydoghaswormsView Answer on Stackoverflow
Solution 2 - JqueryAndy EView Answer on Stackoverflow
Solution 3 - JqueryazatothView Answer on Stackoverflow
Solution 4 - JqueryMazatecView Answer on Stackoverflow
Solution 5 - JqueryFuryView Answer on Stackoverflow
Solution 6 - JquerychamberlainpiView Answer on Stackoverflow
Solution 7 - JqueryFerhat KOÇERView Answer on Stackoverflow
Solution 8 - JqueryCefn HoileView Answer on Stackoverflow
Solution 9 - JquerymuglioView Answer on Stackoverflow
Solution 10 - JqueryiCodeView Answer on Stackoverflow
Solution 11 - JqueryTaoView Answer on Stackoverflow
Solution 12 - JqueryuserView Answer on Stackoverflow
Solution 13 - JqueryJecomsView Answer on Stackoverflow
Solution 14 - JqueryeosphereView Answer on Stackoverflow
Solution 15 - Jquerywooz16View Answer on Stackoverflow
Solution 16 - JqueryDominik HollandView Answer on Stackoverflow
Solution 17 - JqueryIsaac AdamsView Answer on Stackoverflow
Solution 18 - JquerygeomorilloView Answer on Stackoverflow
Solution 19 - Jqueryjk jkView Answer on Stackoverflow
Solution 20 - JqueryMustafa Cevat BozView Answer on Stackoverflow
Solution 21 - JqueryGrantView Answer on Stackoverflow
Solution 22 - JqueryWebManView Answer on Stackoverflow
Solution 23 - Jquerypti_julView Answer on Stackoverflow
Solution 24 - JquerySam DeeringView Answer on Stackoverflow