POST unchecked HTML checkboxes
Asked Answered
S

45

377

I've got a load of checkboxes that are checked by default. My users will probably uncheck a few (if any) of the checkboxes and leave the rest checked.

Is there any way to make the form POST the checkboxes that are not checked, rather than the ones that are checked?

Singlebreasted answered 27/11, 2009 at 15:56 Comment(1)
What about using two radio inputs?Curlpaper
S
248

Add a hidden input for the checkbox with a different ID:

<input id='testName' type='checkbox' value='Yes' name='testName'>
<input id='testNameHidden' type='hidden' value='No' name='testName'>

Before submitting the form, disable the hidden input based on the checked condition:

form.addEventListener('submit', () => {
    if(document.getElementById("testName").checked) {
        document.getElementById('testNameHidden').disabled = true;
    }
}
Slowmoving answered 5/7, 2013 at 15:7 Comment(16)
If you're going with a markup-based solution like this, it's probably better to put the hidden input first, per many the other answers. If you're using PHP, you can then do away with the javascript dependency, because only the last value gets used.Pelisse
The problem with this is that clicking on the label doesn't tick/untick the checkbox anymore because two inputs have same name...Ize
gamov, you are mistaken, labels are attached to inputs based on the id attribute, not the input name attributeResile
I'm a little confused by this answer. The OP asked how to get all of the checkboxes that were unchecked, not the ones that are checked. I think what they are trying to do is only send the hidden fields for the checkboxes that are not checked, but aren't the checked non-hidden fields also POSTed? In the javascript provided, shouldn't the visible checkbox that is checked, 'testName', also be disabled or unchecked to prevent it from being included in the form POST. Or is the server only looking for hidden-named fields in the form POST to determine what is unchecked?Buntline
@PhilDD Old comment, but just for clarification for people who visit here, unchecked checkboxes are not included in submitted form values. This solution (and the answer to the OP's question) allows for the hidden to be submitted in place of an unchecked checkbox. If the checkbox is checked, it will disable the hidden to ensure an array of values (bot the CB and the hidden) aren't sent. It saves people from having to do backend validation on the checkbox to see if it exists (like with isset() in php), and they can just handle the value, though they probably should be doing it anyway.Marie
@GarySchreiner Yeah, it "self clarified" after a while :-). The hidden fields are surrogates for visible but unchecked checkboxes. Only one field with the name is ever submitted - either the hidden unchecked surrogate or the visible checked checkbox, but each has its own unique ID.Buntline
Hard to believe authors designed it this way. Why not to send all input fields with some default value for those not checked :( It would be much clearer solution then having to implement some hidden fields "hack". It must have been clear that it is going to be needed and they had to see that in advance.Brader
How do you actually do this when you have a name like: name[]? Whenever I check a checkbox, it will take both of the values. How do I fix this?Tresa
@Tresa I added a class to the hidden input on my dynamic form and then disable it by finding closest. <input type="hidden" name="task[]" value="0" class="task_hidden" /> $("input[name='task[]']").click(function() { var parent = $(this).closest('.section') if($(this).prop('checked')== true && $(this).val()== "Clip" ){ $(".task_hidden",parent).prop("disabled",true); });Rattlehead
Am I the only one who thinks that the underlying design of the checkbox element is terrible? They're a binary control, they should send binary values.Legislation
Great ans sir. i have another solution make it sense ? <input type='checkbox' name='testName' class='chk_check'> <input type='text' value='No' name='testName' id="checkbox_value"> <!-- after testing you change type="hidden" --> $(document).on('click', '.chk_check', function () { var is_checked = $(this).is(":checked") ? 1 : 0; $('#checkbox_value').val(is_checked); });Kenna
One issue with adding the hidden input with same name as the checkbox is that code like frm.testName.checked = true no longer works, because frm.testName is now a collection of two elements.Solley
Another issue is that the hidden input is only being disabled, never re-enabled. That can be an issue if the form uses AJAX to submit data and the user can use the form again without page load.Solley
The easiest solution is <input type=checkbox onclick="$(this).val(this.checked?1:0)" ..>Maddening
This is too messy to be accepted as the answer to this question! Why not just handle this on the server side?Tasset
@Srneczek, in the 90s the transfer speeds were a lot smaller than today, so this was probably designed to send just the exact amount of data needed and not one bit more.Amr
C
582

The solution I liked the most so far is to put a hidden input with the same name as the checkbox that might not be checked. I think it works so that if the checkbox isn't checked, the hidden input is still successful and sent to the server but if the checkbox is checked it will override the hidden input before it. This way you don't have to keep track of which values in the posted data were expected to come from checkboxes.

<form>
  <input type='hidden' value='0' name='selfdestruct'>
  <input type='checkbox' value='1' name='selfdestruct'>
</form>
Catholic answered 2/1, 2010 at 20:35 Comment(17)
Now that I re-read the question it seems this wasn't really what you wanted. However I got to this question when I was trying to figure out this answer so maybe it could be useful to someone else.Catholic
.NET is different, instead see #7601317Sometime
It should be noted that if you check the box, the browser will send both the hidden and checkbox values. This solution then relies on the server's handling of the post variable with these 2 values. If it only takes the last value (e.g. PHP), your code will work as expected. However, some servers handle this differently, Some pick the first value, while others place both values in a list/array.Mathew
I use this approach in Ruby on Rails. If a user un-checks a checkbox, false (0) is submitted. If checked, the last input of the same name overrides the hidden field per the HTML specification. If the original value needs to be referenced in a stateless environment, just add a hidden field with a different name and populate its value e.g. <input type='hidden' value='1' name='selfdestruct_original'> It will be transmitted with the posting of the form. Then just test on the server-side params[:selfdestruct] == params[:selfdestruct_original]Thanks
This answer is build on the assumption that you can relay on only one of two equal named inputs will be send to the server - I don't understand why this has received so many up-votes?Dariodariole
And what's the problem with that assumption? This is how HTML form fields work.Catholic
@sam dont know where you got that idea from? When two or more controls are named the same then both will be send to the server on submit (for checkboxes however, only if checked) - how they are handled on the server depends on the server side implementation. If you dont believe me you can see for yourself by monitoring the traffic using a tool like fiddler.Dariodariole
this is the Rails solutionBenge
BOTH VALUES GET SENT when the box is checked. There is no overriding. Servers handle the resulting duplicate values differently. In .NET, I see a comma separated list like "off,off" and "on,on".Mooneyham
This works for me, just add a hidden input before all the checkbox with the same name, value="" or value="somthing" will add nothing into de database, if at lease one checkbox is checked, they are going into the database but still nothing from the hidden inputBisulcate
owasp.org/images/b/ba/AppsecEU09_CarettoniDiPaola_v0.8.pdf - this is a platform-specific hack. As noted already, it's not portable across different web servers, and may result in easy to miss bugs.Impersonality
Thank you. I know bout this but never though to arrange it like this. I almost end up using JSExcavator
It should also be noted that NO VALUE GETS SENT IF ITS NOT CHECKED, but I know this isn't where people would normally look for this piece of information.Vorlage
Using a php://input stream you can spot and handle this kind of cheating. Or deal with duplicate names in general.Pig
This may not be what OP wanted, but this is EXACTLY what I was looking for. It's good to note though, that this seems to only work if the hidden field comes BEFORE the checkbox. Otherwise the hidden field will always overwrite the checkbox.Tellurian
this is the PHP solution. Works with PHP 7.* and tested with PHP 8.1 too.Gittle
This is sending both the normal and hidden values instead of overwriting the hidden oneWellknown
S
248

Add a hidden input for the checkbox with a different ID:

<input id='testName' type='checkbox' value='Yes' name='testName'>
<input id='testNameHidden' type='hidden' value='No' name='testName'>

Before submitting the form, disable the hidden input based on the checked condition:

form.addEventListener('submit', () => {
    if(document.getElementById("testName").checked) {
        document.getElementById('testNameHidden').disabled = true;
    }
}
Slowmoving answered 5/7, 2013 at 15:7 Comment(16)
If you're going with a markup-based solution like this, it's probably better to put the hidden input first, per many the other answers. If you're using PHP, you can then do away with the javascript dependency, because only the last value gets used.Pelisse
The problem with this is that clicking on the label doesn't tick/untick the checkbox anymore because two inputs have same name...Ize
gamov, you are mistaken, labels are attached to inputs based on the id attribute, not the input name attributeResile
I'm a little confused by this answer. The OP asked how to get all of the checkboxes that were unchecked, not the ones that are checked. I think what they are trying to do is only send the hidden fields for the checkboxes that are not checked, but aren't the checked non-hidden fields also POSTed? In the javascript provided, shouldn't the visible checkbox that is checked, 'testName', also be disabled or unchecked to prevent it from being included in the form POST. Or is the server only looking for hidden-named fields in the form POST to determine what is unchecked?Buntline
@PhilDD Old comment, but just for clarification for people who visit here, unchecked checkboxes are not included in submitted form values. This solution (and the answer to the OP's question) allows for the hidden to be submitted in place of an unchecked checkbox. If the checkbox is checked, it will disable the hidden to ensure an array of values (bot the CB and the hidden) aren't sent. It saves people from having to do backend validation on the checkbox to see if it exists (like with isset() in php), and they can just handle the value, though they probably should be doing it anyway.Marie
@GarySchreiner Yeah, it "self clarified" after a while :-). The hidden fields are surrogates for visible but unchecked checkboxes. Only one field with the name is ever submitted - either the hidden unchecked surrogate or the visible checked checkbox, but each has its own unique ID.Buntline
Hard to believe authors designed it this way. Why not to send all input fields with some default value for those not checked :( It would be much clearer solution then having to implement some hidden fields "hack". It must have been clear that it is going to be needed and they had to see that in advance.Brader
How do you actually do this when you have a name like: name[]? Whenever I check a checkbox, it will take both of the values. How do I fix this?Tresa
@Tresa I added a class to the hidden input on my dynamic form and then disable it by finding closest. <input type="hidden" name="task[]" value="0" class="task_hidden" /> $("input[name='task[]']").click(function() { var parent = $(this).closest('.section') if($(this).prop('checked')== true && $(this).val()== "Clip" ){ $(".task_hidden",parent).prop("disabled",true); });Rattlehead
Am I the only one who thinks that the underlying design of the checkbox element is terrible? They're a binary control, they should send binary values.Legislation
Great ans sir. i have another solution make it sense ? <input type='checkbox' name='testName' class='chk_check'> <input type='text' value='No' name='testName' id="checkbox_value"> <!-- after testing you change type="hidden" --> $(document).on('click', '.chk_check', function () { var is_checked = $(this).is(":checked") ? 1 : 0; $('#checkbox_value').val(is_checked); });Kenna
One issue with adding the hidden input with same name as the checkbox is that code like frm.testName.checked = true no longer works, because frm.testName is now a collection of two elements.Solley
Another issue is that the hidden input is only being disabled, never re-enabled. That can be an issue if the form uses AJAX to submit data and the user can use the form again without page load.Solley
The easiest solution is <input type=checkbox onclick="$(this).val(this.checked?1:0)" ..>Maddening
This is too messy to be accepted as the answer to this question! Why not just handle this on the server side?Tasset
@Srneczek, in the 90s the transfer speeds were a lot smaller than today, so this was probably designed to send just the exact amount of data needed and not one bit more.Amr
A
108

I solved it by using vanilla JavaScript:

<input type="hidden" name="checkboxName" value="0"><input type="checkbox" onclick="this.previousSibling.value=1-this.previousSibling.value">

Be careful not to have any spaces or linebreaks between this two input elements!

You can use this.previousSibling.previousSibling to get "upper" elements.

With PHP you can check the named hidden field for 0 (not set) or 1 (set).

Ascidian answered 10/9, 2014 at 12:1 Comment(6)
Why can't you have spaces or line breaks between the two elements?Lyon
@MichaelPotter: this.previousSibling will get whitespace as sibling, so it dont work.Ascidian
Oh this is PERFECT! It solves the problem of posting multiple fieldsets with duplicate named fields there in. None of the other solutions do. Using Marcel's method, your posted fields will have equal length arrays. So this scenario: <fieldset name='fs1'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset> <fieldset name='fs2'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset> * Assume there were new lines there. They don't seem to be working in mini-markup code blocksTeniers
This should be the accepted answer. It works with arrays (ex/ name="soup[]")Ridiculous
You can use previousElementSibling instead of previousSibling. It is supported nearly everywhere, and it ignores text nodes.Whin
It won't work if the checkbox is set using JS or default as checked. To fix the latter you can `onclick="this.previousElementSibling.name=this.checked?'':this.name"Heywood
B
28

My personal favorite is to add a hidden field with the same name that will be used if the check-box is unchecked. But the solution is not as easy as it may seems.

If you add this code:

<form>
  <input type='hidden' value='0' name='selfdestruct'>
  <input type='checkbox' value='1' name='selfdestruct'>
</form>

The browser will not really care about what you do here. The browser will send both parameters to the server, and the server has to decide what to do with them.

PHP for example takes the last value as the one to use (see: Authoritative position of duplicate HTTP GET query keys)

But other systems I worked with (based on Java) do it the way around - they offer you only the first value. .NET instead will give you an array with both elements instead

I'll try to test this with node.js, Python and Perl at sometime.

Boesch answered 23/1, 2012 at 13:1 Comment(4)
ruby and node.js will both take the last value of any duplicated form fields. Ruby on Rails' helper methods construct checkboxes in this fashion for this reason.Alkalinize
Just to round that up - this is based on an attack called HTTP Parameter Pollution and has been analyzed by OWASP: owasp.org/images/b/ba/AppsecEU09_CarettoniDiPaola_v0.8.pdf (page 9) where you can find a list of 20 systems systems and see how they handle that.Boesch
Java Servlets gives you all, as long as you call request.getParameterValuesSwithbart
I've tested this with Python and it looks like it's trying to handle both valuesCanadian
H
25

you don't need to create a hidden field for all checkboxes just copy my code. it will change the value of checkbox if not checked the value will assign 0 and if checkbox checked then assign value into 1

$("form").submit(function () {

    var this_master = $(this);

    this_master.find('input[type="checkbox"]').each( function () {
        var checkbox_this = $(this);


        if( checkbox_this.is(":checked") == true ) {
            checkbox_this.attr('value','1');
        } else {
            checkbox_this.prop('checked',true);
            //DONT' ITS JUST CHECK THE CHECKBOX TO SUBMIT FORM DATA    
            checkbox_this.attr('value','0');
        }
    })
})
Hebetate answered 13/12, 2013 at 15:26 Comment(2)
This solution works fine and more elegant than polluting Dom with hidden fields.Bastardy
This causes the box to get checked temporarily while the form is submitted. This is confusing (at best) to the user.Lightish
D
23

A common technique around this is to carry a hidden variable along with each checkbox.

<input type="checkbox" name="mycheckbox" />
<input type="hidden" name="mycheckbox.hidden"/>

On the server side, we first detect list of hidden variables and for each of the hidden variable, we try to see if the corresponding checkbox entry is submitted in the form data or not.

The server side algorithm would probably look like:

for input in form data such that input.name endswith .hidden
  checkboxName = input.name.rstrip('.hidden')
  if chceckbName is not in form, user has unchecked this checkbox

The above doesn't exactly answer the question, but provides an alternate means of achieving similar functionality.

Dav answered 27/11, 2009 at 16:31 Comment(1)
doesn't work with Perl CGI::Simple - it will still create a too-short array of mycheckbox elements so you don't know which ones are missing.Svetlanasvoboda
A
13

I know this question is 3 years old but I found a solution that I think works pretty well.

You can do a check if the $_POST variable is assigned and save it in a variable.

$value = isset($_POST['checkboxname'] ? 'YES' : 'NO';

the isset() function checks if the $_POST variable is assigned. By logic if it is not assigned then the checkbox is not checked.

Artless answered 9/8, 2018 at 11:39 Comment(4)
This is much better, as the most popular response is a terrible solution for screen readers.Pappas
This answer should have more upvotes. It is simple and has no overheads.Tasset
It is because you only have 1 checkbox, if you have multiple checkbox to submit, and you care about the checkbox sorting this solution won't workFrugivorous
This works only for single input field, when it comes to multiple, you will not find unchecked post dataRas
S
12
$('input[type=checkbox]').on("change",function(){
    var target = $(this).parent().find('input[type=hidden]').val();
    if(target == 0)
    {
        target = 1;
    }
    else
    {
        target = 0;
    }
    $(this).parent().find('input[type=hidden]').val(target);
});

<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>

If you leave out the name of the checkbox it doesn't get passed. Only the test_checkbox array.

Site answered 14/1, 2013 at 19:44 Comment(3)
Very great solution, but in my case the live() doesnt work, so I used on() method: $('input[type=checkbox]').on("change",function(){...});Foot
LIVE is obsolete. Do not use it on answers in the stackoverflow anymore. Amem.Litchfield
This answer is really the best.. It's working as expected. Even for group checkbox.Mukul
L
11

You can do some Javascript in the form's submit event. That's all you can do though, there's no way to get browsers to do this by themselves. It also means your form will break for users without Javascript. Better is to know on the server which checkboxes there are, so you can deduce that those absent from the posted form values ($_POST in PHP) are unchecked.

Lychnis answered 27/11, 2009 at 15:59 Comment(2)
since php 4.1 you also may use $_REQUEST php.net/manual/en/reserved.variables.request.phpAmid
$_REQUEST is a good practice since it allows some code reuse if your script supports both methods.Unfit
A
11

I also like the solution that you just post an extra input field, using JavaScript seems a little hacky to me.

Depending on what you use for you backend will depend on which input goes first.

For a server backend where the first occurrence is used (JSP) you should do the following.

  <input type="checkbox" value="1" name="checkbox_1"/>
  <input type="hidden" value="0" name="checkbox_1"/>


For a server backend where the last occurrence is used (PHP,Rails) you should do the following.

  <input type="hidden" value="0" name="checkbox_1"/>
  <input type="checkbox" value="1" name="checkbox_1"/>


For a server backend where all occurrences are stored in a list data type ([],array). (Python / Zope)

You can post in which ever order you like, you just need to try to get the value from the input with the checkbox type attribute. So the first index of the list if the checkbox was before the hidden element and the last index if the checkbox was after the hidden element.


For a server backend where all occurrences are concatenated with a comma (ASP.NET / IIS) You will need to (split/explode) the string by using a comma as a delimiter to create a list data type. ([])

Now you can attempt to grab the first index of the list if the checkbox was before the hidden element and grab the last index if the checkbox was after the hidden element.

Backend parameter handling

image source

Alcaide answered 4/1, 2016 at 16:54 Comment(0)
S
9

I would actually do the following.

Have my hidden input field with the same name with the checkbox input

<input type="hidden" name="checkbox_name[]" value="0" />
<input type="checkbox" name="checkbox_name[]" value="1" />

and then when i post I first of all remove the duplicate values picked up in the $_POST array, atfer that display each of the unique values.

  $posted = array_unique($_POST['checkbox_name']);
  foreach($posted as $value){
    print $value;
  }

I got this from a post remove duplicate values from array

Somerset answered 22/4, 2013 at 8:55 Comment(4)
What is the purpose of the [] on the name field value?Lyon
@MichaelPotter It is so when post is sent to PHP, it will read the name `checkbox_name[]Sherl
@Twister1002, I think you described the purpose of the name attribute, not the purpose of adding [] on the name. I did a web search and it seems some people do this with the names: groupname[elementname] to group fields together, but I did not find an explanation for empty [].Lyon
@MichaelPotter Sorry, I thought I had finished that statement. But apparently not. Let me redo that. When it is sent to php the PHP processor will read it as an array. So with each name checkbox_name[] each value will be entered into an array, which you can then pull. Ex: $_POST['checkbox_name'][0] and so on with the increment of how many fields had that same name. Another example is if you had three fields named field_name[] you can get the second value of field_name like $_POST['field_name'][1]. Its purpose can be amazing if you have several fields that are of the same name.Sherl
U
8

"I've gone with the server approach. Seems to work fine - thanks. – reach4thelasers Dec 1 '09 at 15:19" I would like to recommend it from the owner. As quoted: javascript solution depends on how the server handler (I didn't check it)

such as

if(!isset($_POST["checkbox"]) or empty($_POST["checkbox"])) $_POST["checkbox"]="something";
Unbonnet answered 27/2, 2013 at 13:1 Comment(0)
S
7

Most of the answers here require the use of JavaScript or duplicate input controls. Sometimes this needs to be handled entirely on the server-side.

I believe the (intended) key to solving this common problem is the form's submission input control.

To interpret and handle unchecked values for checkboxes successfully you need to have knowledge of the following:

  1. The names of the checkboxes
  2. The name of the form's submission input element

By checking whether the form was submitted (a value is assigned to the submission input element), any unchecked checkbox values can be assumed.

For example:

<form name="form" method="post">
  <input name="value1" type="checkbox" value="1">Checkbox One<br/>
  <input name="value2" type="checkbox" value="1" checked="checked">Checkbox Two<br/>
  <input name="value3" type="checkbox" value="1">Checkbox Three<br/>
  <input name="submit" type="submit" value="Submit">
</form>

When using PHP, it's fairly trivial to detect which checkboxes were ticked.

<?php

$checkboxNames = array('value1', 'value2', 'value3');

// Persisted (previous) checkbox state may be loaded 
// from storage, such as the user's session or a database.
$checkboxesThatAreChecked = array(); 

// Only process if the form was actually submitted.
// This provides an opportunity to update the user's 
// session data, or to persist the new state of the data.

if (!empty($_POST['submit'])) {
    foreach ($checkboxNames as $checkboxName) {
        if (!empty($_POST[$checkboxName])) {
            $checkboxesThatAreChecked[] = $checkboxName;
        }
    }
    // The new state of the checkboxes can be persisted 
    // in session or database by inspecting the values 
    // in $checkboxesThatAreChecked.
    print_r($checkboxesThatAreChecked);
}

?>

Initial data could be loaded on each page load, but should be only modified if the form was submitted. Since the names of the checkboxes are known beforehand, they can be traversed and inspected individually, so that the the absence of their individual values indicates that they are not checked.

Synopsis answered 14/4, 2015 at 7:56 Comment(0)
S
6

I've tried Sam's version first. Good idea, but it causes there to be multiple elements in the form with the same name. If you use any javascript that finds elements based on name, it will now return an array of elements.

I've worked out Shailesh's idea in PHP, it works for me. Here's my code:

/* Delete '.hidden' fields if the original is present, use '.hidden' value if not. */
foreach ($_POST['frmmain'] as $field_name => $value)
{
    // Only look at elements ending with '.hidden'
    if ( !substr($field_name, -strlen('.hidden')) ) {
        break;
    }

    // get the name without '.hidden'
    $real_name = substr($key, strlen($field_name) - strlen('.hidden'));

    // Create a 'fake' original field with the value in '.hidden' if an original does not exist
    if ( !array_key_exists( $real_name, $POST_copy ) ) {
        $_POST[$real_name] = $value;
    }

    // Delete the '.hidden' element
    unset($_POST[$field_name]);
}
Sarena answered 8/3, 2011 at 14:41 Comment(0)
L
6

You can also intercept the form.submit event and reverse check before submit

$('form').submit(function(event){
    $('input[type=checkbox]').prop('checked', function(index, value){
        return !value;
    });
});
Ladybird answered 4/12, 2012 at 17:8 Comment(0)
C
6

I use this block of jQuery, which will add a hidden input at submit-time to every unchecked checkbox. It will guarantee you always get a value submitted for every checkbox, every time, without cluttering up your markup and risking forgetting to do it on a checkbox you add later. It's also agnostic to whatever backend stack (PHP, Ruby, etc.) you're using.

// Add an event listener on #form's submit action...
$("#form").submit(
    function() {

        // For each unchecked checkbox on the form...
        $(this).find($("input:checkbox:not(:checked)")).each(

            // Create a hidden field with the same name as the checkbox and a value of 0
            // You could just as easily use "off", "false", or whatever you want to get
            // when the checkbox is empty.
            function(index) {
                var input = $('<input />');
                input.attr('type', 'hidden');
                input.attr('name', $(this).attr("name")); // Same name as the checkbox
                input.attr('value', "0"); // or 'off', 'false', 'no', whatever

                // append it to the form the checkbox is in just as it's being submitted
                var form = $(this)[0].form;
                $(form).append(input);

            }   // end function inside each()
        );      // end each() argument list

        return true;    // Don't abort the form submit

    }   // end function inside submit()
);      // end submit() argument list
Cardoon answered 17/4, 2016 at 15:10 Comment(0)
G
5
$('form').submit(function () {
    $(this).find('input[type="checkbox"]').each( function () {
        var checkbox = $(this);
        if( checkbox.is(':checked')) {
            checkbox.attr('value','1');
        } else {
            checkbox.after().append(checkbox.clone().attr({type:'hidden', value:0}));
            checkbox.prop('disabled', true);
        }
    })
});
Golter answered 25/8, 2016 at 5:53 Comment(2)
This worked for me. Instead of using .submit you would use .click. Then remove the bit that disables checkboxes. After that it works perfectly.Warwick
Best answer no need to add another hidden input for each oneIndiscreet
K
4

I see this question is old and has so many answers, but I'll give my penny anyway. My vote is for the javascript solution on the form's 'submit' event, as some has pointed out. No doubling the inputs (especially if you have long names and attributes with php code mixed with html), no server side bother (that would require to know all field names and to check them down one by one), just fetch all the unchecked items, assign them a 0 value (or whatever you need to indicate a 'not checked' status) and then change their attribute 'checked' to true

    $('form').submit(function(e){
    var b = $("input:checkbox:not(:checked)");
    $(b).each(function () {
        $(this).val(0); //Set whatever value you need for 'not checked'
        $(this).attr("checked", true);
    });
    return true;
});

this way you will have a $_POST array like this:

Array
(
            [field1] => 1
            [field2] => 0
)
Kiangsi answered 28/2, 2016 at 23:38 Comment(3)
Not working at my side. Trying to do this but still not posting all the checkboxes. [code] $("#filter input").change(function(e) { console.log('sublmit'); var b = $("input:checkbox:not(:checked)"); $(b).each(function () { $(this).val(2); $(this).attr("checked", true); }); $("#filter").submit(); }); [/code]Swaraj
Did the trick for me. The only drawback - on form submit every checkbox became checked. This can be confusing to a user, but because the page is reloading after form submits, I think it's a minor issue.Sparry
As Oksana said, it check all of the checkboxes, including any required checkboxes the user did not select themselves allowing the form to be submitted without the user agreeing to some condition.Nonchalant
T
3

What I did was a bit different. First I changed the values of all the unchecked checkboxes. To "0", then selected them all, so the value would be submitted.

function checkboxvalues(){
  $("#checkbox-container input:checkbox").each(function({ 
    if($(this).prop("checked")!=true){
      $(this).val("0");
      $(this).prop("checked", true);
    }
  });
}
Tempo answered 21/4, 2015 at 2:14 Comment(2)
Answer is good, but i want to know is it different from @Rameez SOOMRO's answer?Slither
Similar end result, only this way you don't change the value of the checked checkboxes.Tempo
M
3

The easiest solution is a "dummy" checkbox plus hidden input if you are using jquery:

 <input id="id" type="hidden" name="name" value="1/0">
 <input onchange="$('#id').val(this.checked?1:0)" type="checkbox" id="dummy-id" 
 name="dummy-name" value="1/0" checked="checked/blank">

Set the value to the current 1/0 value to start with for BOTH inputs, and checked=checked if 1. The input field (active) will now always be posted as 1 or 0. Also the checkbox can be clicked more than once before submission and still work correctly.

Maddening answered 7/2, 2020 at 13:36 Comment(0)
S
2

I would prefer collate the $_POST

if (!$_POST['checkboxname']) !$_POST['checkboxname'] = 0;

it minds, if the POST doesn't have have the 'checkboxname'value, it was unckecked so, asign a value.

you can create an array of your ckeckbox values and create a function that check if values exist, if doesn`t, it minds that are unchecked and you can asign a value

Signor answered 23/8, 2015 at 19:51 Comment(0)
M
2

Might look silly, but it works for me. The main drawback is that visually is a radio button, not a checkbox, but it work without any javascript.

HTML

Initialy checked
<span><!-- set the check attribute for the one that represents the initial value-->
<input type="radio" name="a" value="1" checked>
<input type="radio" name="a" value="0">
</span>

<br/>
Initialy unchecked
<span><!-- set the check attribute for the one that represents the initial value-->
<input type="radio" name="b" value="1">
<input type="radio" name="b" value="0" checked>
</span>

and CSS

span input
{position: absolute; opacity: 0.99}

span input:checked
{z-index: -10;}

span input[value="0"]
{opacity: 0;}

fiddle here

I'd like to hear any problems you find with this code, cause I use it in production

Marlo answered 21/2, 2018 at 19:9 Comment(2)
Thinking along these lines, you could use a type='range' input with min=0 and max=1Pyrogenous
@Pyrogenous that's what I do nowadays whenever the problem occurs.Marlo
B
1

Example on Ajax actions is(':checked') used jQuery instead of .val();

            var params = {
                books: $('input#users').is(':checked'),
                news : $('input#news').is(':checked'),
                magazine : $('input#magazine').is(':checked')
            };

params will get value in TRUE OR FALSE..

Broadax answered 25/2, 2014 at 8:2 Comment(0)
T
1

Checkboxes usually represent binary data that are stored in database as Yes/No, Y/N or 1/0 values. HTML checkboxes do have bad nature to send value to server only if checkbox is checked! That means that server script on other site must know in advance what are all possible checkboxes on web page in order to be able to store positive (checked) or negative (unchecked) values. Actually only negative values are problem (when user unchecks previously (pre)checked value - how can server know this when nothing is sent if it does not know in advance that this name should be sent). If you have a server side script which dynamically creates UPDATE script there's a problem because you don't know what all checkboxes should be received in order to set Y value for checked and N value for unchecked (not received) ones.

Since I store values 'Y' and 'N' in my database and represent them via checked and unchecked checkboxes on page, I added hidden field for each value (checkbox) with 'Y' and 'N' values then use checkboxes just for visual representation, and use simple JavaScript function check() to set value of if according to selection.

<input type="hidden" id="N1" name="N1" value="Y" />
<input type="checkbox"<?php if($N1==='Y') echo ' checked="checked"'; ?> onclick="check(this);" />
<label for="N1">Checkbox #1</label>

use one JavaScript onclick listener and call function check() for each checkboxe on my web page:

function check(me)
{
  if(me.checked)
  {
    me.previousSibling.previousSibling.value='Y';
  }
  else
  {
    me.previousSibling.previousSibling.value='N';
  }
}

This way 'Y' or 'N' values are always sent to server side script, it knows what are fields that should be updated and there's no need for conversion of checbox "on" value into 'Y' or not received checkbox into 'N'.

NOTE: white space or new line is also a sibling so here I need .previousSibling.previousSibling.value. If there's no space between then only .previousSibling.value


You don't need to explicitly add onclick listener like before, you can use jQuery library to dynamically add click listener with function to change value to all checkboxes in your page:

$('input[type=checkbox]').click(function()
{
  if(this.checked)
  {
    $(this).prev().val('Y');
  }
  else
  {
    $(this).prev().val('N');
  }
});
Tertias answered 15/9, 2014 at 14:5 Comment(0)
G
1

@cpburnz got it right but to much code, here is the same idea using less code:

JS:

// jQuery OnLoad
$(function(){
    // Listen to input type checkbox on change event
    $("input[type=checkbox]").change(function(){
        $(this).parent().find('input[type=hidden]').val((this.checked)?1:0);
    });
});

HTML (note the field name using an array name):

<div>
    <input type="checkbox" checked="checked">
    <input type="hidden" name="field_name[34]" value="1"/>
</div>
<div>
    <input type="checkbox">
    <input type="hidden" name="field_name[35]" value="0"/>
</div>
<div>

And for PHP:

<div>
    <input type="checkbox"<?=($boolean)?' checked="checked"':''?>>
    <input type="hidden" name="field_name[<?=$item_id?>]" value="<?=($boolean)?1:0?>"/>
</div>
Goosestep answered 22/10, 2014 at 10:58 Comment(0)
S
1

All answers are great, but if you have multiple checkboxes in a form with the same name and you want to post the status of each checkbox. Then i have solved this problem by placing a hidden field with the checkbox (name related to what i want).

<input type="hidden" class="checkbox_handler" name="is_admin[]" value="0" />
<input type="checkbox" name="is_admin_ck[]" value="1" />

then control the change status of checkbox by below jquery code:

$(documen).on("change", "input[type='checkbox']", function() {
    var checkbox_val = ( this.checked ) ? 1 : 0;
    $(this).siblings('input.checkbox_handler').val(checkbox_val);
});

now on change of any checkbox, it will change the value of related hidden field. And on server you can look only to hidden fields instead of checkboxes.

Hope this will help someone have this type of problem. cheer :)

Seraphina answered 21/5, 2015 at 5:2 Comment(0)
G
1

You can add hidden elements before submitting form.

$('form').submit(function() {
  $(this).find('input[type=checkbox]').each(function (i, el) {
    if(!el.checked) {
      var hidden_el = $(el).clone();
      hidden_el[0].checked = true;
      hidden_el[0].value = '0';
      hidden_el[0].type = 'hidden'
      hidden_el.insertAfter($(el));
    }
  })
});
Gamin answered 23/7, 2015 at 13:57 Comment(0)
S
1

The problem with checkboxes is that if they are not checked then they are not posted with your form. If you check a checkbox and post a form you will get the value of the checkbox in the $_POST variable which you can use to process a form, if it's unchecked no value will be added to the $_POST variable.

In PHP you would normally get around this problem by doing an isset() check on your checkbox element. If the element you are expecting isn't set in the $_POST variable then we know that the checkbox is not checked and the value can be false.

if(!isset($_POST['checkbox1']))
{
     $checkboxValue = false;
} else {
     $checkboxValue = $_POST['checkbox1'];
}

But if you have created a dynamic form then you won't always know the name attribute of your checkboxes, if you don't know the name of the checkbox then you can't use the isset function to check if this has been sent with the $_POST variable.

Subclimax answered 26/1, 2016 at 15:59 Comment(0)
J
1
function SubmitCheckBox(obj) {
     obj.value   = obj.checked ? "on" : "off";
     obj.checked = true;
     return obj.form.submit();
}

<input type=checkbox name="foo" onChange="return SubmitCheckBox(this);">
Johst answered 26/4, 2016 at 7:36 Comment(0)
C
1

If you want to submit an array of checkbox values (including un-checked items) then you could try something like this:

<form>
<input type="hidden" value="0" name="your_checkbox_array[]"><input type="checkbox">Dog
<input type="hidden" value="0" name="your_checkbox_array[]"><input type="checkbox">Cat
</form>

$('form').submit(function(){
    $('input[type="checkbox"]:checked').prev().val(1);
});
Casuist answered 18/8, 2017 at 2:40 Comment(1)
This is the exact answer I was looking for. Thank you @CasuistActing
D
1

When the checkbox is unchecked on submit, update the checkbox value to 'NO' and set checked = 'TRUE'

https://jsfiddle.net/pommyk/8d9jLrvo/26/

$(document).ready(function() 
{
  function save() 
  {
    if (document.getElementById('AgeVerification').checked == false) 
    {
      document.getElementById('AgeVerification').value = 'no';
      document.getElementById('AgeVerification').checked = true;     
    }
  }
  document.getElementById("submit").onclick = save;
})
Dichogamy answered 18/4, 2018 at 15:16 Comment(0)
I
1

We can check if the $_POST/Request elements have it or not. Then assign it to a vairable.

$value = (null !== $_POST['checkboxname']) ? 'YES' : 'NO';

This is quite similar to isset() function. But the isset() function can't be used on the result of an expression. We can check its result with null and achieve the same.

The final value is just imaginary. We can change 'YES' to 1 and 'NO'to 0 if the required field is of boolean type.

Insurgency answered 30/6, 2022 at 21:2 Comment(0)
P
0

There is a better workaround. First of all provide name attribute to only those checkboxes that are checked. Then on click submit, through a JavaScript function you check all unchecked boxes . So when you submit only those will be retrieved in form collection those who have name property.

  //removing name attribute from all checked checkboxes
                  var a = $('input:checkbox:checked');
                   $(a).each(function () {
                       $(this).removeAttr("name");        
                   });

   // checking all unchecked checkboxes
                   var b = $("input:checkbox:not(:checked)");
                   $(b).each(function () {
                       $(this).attr("checked", true);
                   });

Advantage: No need to create extra hidden boxes,and manipulate them.

Protozoon answered 30/9, 2014 at 9:33 Comment(0)
P
0

jQuery version of @vishnu's answer.

if($('#testName').is(":checked")){
    $('#testNameHidden').prop('disabled', true);
}

If you are using jQuery 1.5 or below please use the .attr() function instead of .prop()

Predial answered 23/10, 2014 at 19:10 Comment(0)
A
0

This solution is inspired by @desw's one.

If your input names are in "form style", you will lose array index association with your chekbox values as soon as one chekbox is checked, incrementing this "dissociation" by one unit each time a chekbox is checked. This can be the case of a form for inserting something like employees composed by some fields, for instance:

<input type="text" name="employee[]" />
<input type="hidden" name="isSingle[] value="no" />
<input type="checkbox" name="isSingle[] value="yes" />

In case you insert three employees at once and the first and the second ones are single, you will end up with a 5-element isSingle array, so you won't be able to iterate at once through the three arrays in order to, for instance, insert employees in a database.

You can overcome this with some easy array postprocessing. I'm using PHP at the server side and I did this:

$j = 0;
$areSingles = $_POST['isSingle'];
foreach($areSingles as $isSingle){
  if($isSingle=='yes'){
    unset($areSingles[$j-1]);
  }
  $j++;
}
$areSingles = array_values($areSingles);
Adherent answered 20/1, 2015 at 17:25 Comment(0)
L
0

So this solution is overkill for this question, but it helped me when I had the same checkbox that occurred many times for different rows in a table. I needed to know the row the checkbox represented and also know the state of the checkbox (checked/unchecked).

What I did was to take the name attribute off of my checkbox inputs, give them all the same class, and create a hidden input that would hold the JSON equivalent of the data.

HTML

 <table id="permissions-table">
    <tr>
	<td>
	    <input type="checkbox" class="has-permission-cb" value="Jim">
	    <input type="checkbox" class="has-permission-cb" value="Bob">
	    <input type="checkbox" class="has-permission-cb" value="Suzy">
	</td>
    </tr>
 </table>
 <input type="hidden" id="has-permissions-values" name="has-permissions-values" value="">

Javascript to run on form submit

var perms = {};
$(".has-permission-checkbox").each(function(){
  var userName = this.value;
  var val = ($(this).prop("checked")) ? 1 : 0
  perms[userName] = {"hasPermission" : val};
});
$("#has-permissions-values").val(JSON.stringify(perms));

The json string will get passed with the form as $_POST["has-permissions-values"]. In PHP, decode the string into an array and you will have an associative array that has each row and the true/false value for each corresponding checkbox. It is then very easy to walk through and compare to current database values.

Lophobranch answered 18/2, 2015 at 21:58 Comment(0)
A
0

I prefer to stay with solutions that do not require javascript (and yes, I know there will be some that now categorize me as a luddite) but if you are like me, and you want to be able to display a default / initial setting for a checkbox and then have it hold or update based on the form being submitted, try this (built on a couple of ideas above):

Set the variables determining the initial checkbox state and then use server checks to determine the display after each submit of the form.

The example below creates an array of arrays (for use in WordPress ; works equally well elsewhere) and then determines the checkbox state using server script without using either hidden fields or javascript.

<?php

$options_array = array (
    array('list_companies_shortcode' , 'shortcode_list_companies' , 'List Companies Shortcode'),
    array('list_contacts_shortcode' , 'shortcode_list_contacts' , 'List Contacts Shortcode'),
    array('test_checkbox_1' , 'checked' , 'Label for Checkbox 1' , 'checkbox' , 'Some text to instruct the user on this checkbox use' ),
    array('test_checkbox_2' , '' , 'Label for Checkbox 2' , 'checkbox' , 'Some other text to instruct the user on this checkbox use' )
 ) ;


$name_value_array = array() ;
$name_label_array = array() ;
$field_type_array = array() ;
$field_descriptor_array = array() ;
foreach ( $options_array as $option_entry ) {
    $name_value_array[ $option_entry[0] ] = $option_entry[1] ;
    $name_label_array[ $option_entry[0] ] = $option_entry[2] ;
    if ( isset( $option_entry[3] ) ) {
        $field_type_array[ $option_entry[0] ] = $option_entry[3] ;
        $field_descriptor_array[ $option_entry[0] ] = $option_entry[4] ;
    } else {
        $field_type_array[ option_entry[0] ] = 'text' ;
        $field_descriptor_array[ $option_entry[0] ] = NULL ;
    } 
}

echo "<form action='' method='POST'>" ;
    foreach ( $name_value_array as $setting_name => $setting_value ) {
        if ( isset( $_POST[ 'submit' ] ) ) {
            if ( isset( $_POST[ $setting_name ] ) ) {
                $setting_value = $_POST[ $setting_name ] ;
            } else {
                $setting_value = '' ;
            }
        }   
        $setting_label = $option_name_label_array[ $setting_name ] ;
        $setting_field_type = $field_type_array[ $setting_name ] ;
        $setting_field_descriptor = $field_descriptor_array [ $setting_name ] ;
        echo "<label for=$setting_name >$setting_label</label>" ;
        switch ( $setting_field_type ) {
            case 'checkbox':
                echo "<input type='checkbox' id=" . $setting_name . " name=" . $setting_name . " value='checked' " . $setting_value . " >(" . $setting_field_descriptor . ")</input><br />" ;
                break ;
            default:
                echo "<input type='text' id=" . $setting_name . " name=" . $setting_name . " value=" . $setting_value . " ></input><br />" ;
        }
    }
    echo "<input type='submit' value='Submit' name='submit' >" ;
echo "</form>" ;
Agni answered 4/10, 2015 at 19:35 Comment(0)
B
0
<input type="checkbox" id="checkbox" name="field_name" value="1">

You can do the trick at server side, without using hidden fields,
Using the ternary operator:

isset($_POST['field_name']) ? $entity->attribute = $_POST['field_name'] : $entity->attribute = 0;

Using normal IF operator:

if (isset($_POST['field_name'])) {
    $entity->attribute = $_POST['field_name'];
} else {
    $entity->attribute = 0;
}
Bruges answered 6/8, 2017 at 21:10 Comment(1)
What if you have multiple checkboxes with same name and you get an array? You can't know which index it is if some are unchecked ...Schoolmate
S
0

One line solution:

$option1ChkBox = array_key_exists('chkBoxName', $_POST) ? true : false;
Slier answered 22/11, 2017 at 8:28 Comment(1)
This does not change the way the data is submitted in any way, because it is server-side only. OP wants the submission process done by the client to be modified.Waterside
D
0

Copy this directly

  


$(document).on('change', "input[type=checkbox]", function () {
       
        var checkboxVal = (this.checked) ? 1 : 0;

      
        if (checkboxVal== 1) {
           
            $(this).prop("checked", true);
            $(this).val("true");
        }
        else {
         
            $(this).prop("checked", false);
            $(this).val("false");
        }
    });
Dockyard answered 12/12, 2019 at 5:22 Comment(0)
D
0

For checkbox, a simple way to do this without using hidden type value is:

<form>
    <input type='checkbox' name='selfdestruct' value='1'>
</form>

In PHP, for the form data posted do:

// Sanitize form POST data
$post = filter_var_array($_POST, FILTER_SANITIZE_STRING);

// set the default checkbox value
$selfDestruct = '0';
if(isset($post["selfdestruct"]))
    $selfDestruct = $post["selfdestruct"];
Dorpat answered 18/4, 2021 at 22:12 Comment(0)
H
0

A play on a previous answer, to automatically persist unchecked checkboxes with a specific value (in this case, 0) without the side effect of checking all of the checkboxes on submit.

$("form").submit(function () {
    let this_master = $(this);

    // Remove any of the hidden values that may already be there (if the user previously canceled the submit)
    this_master.find("*[id^='hiddenchkinput_']").remove();

    // Get all unchecked checkboxes
    this_master.find('input:checkbox:not(:checked)').each(function () {
      let thisChk = $(this);

      // Create a hidden input with the same name as the checkbox
      let newInput = document.createElement('input');
      $(newInput).attr('name', thisChk.attr('id'))
        .attr('id', 'hiddenchkinput_' + thisChk.attr('id'))
        .attr('type', 'hidden')
        .val('0');
      // Append the new input to the end of the form
      this_master.append(newInput);
    });
})
Harlem answered 23/5, 2022 at 17:3 Comment(0)
P
0

Sometimes you have to deal with auto generated forms and you don't know what field will be a checkbox and what not.

Because of these situations, what i like most as a solution for this, is to collect all checkbox field names at the time the form is generated, then default those fields to 0 if they don't have an other value.

No js or lucky value overlapping involved.

when generating the form use this:

<input type='hidden' name='checkboxes_index[]' value='field_name1' />
<input type='checkbox' value='1' name='field_name1'>

<input type='hidden' name='checkboxes_index[]' value='field_name2' />
<input type='checkbox' value='1' name='field_name2'>

and server-side (php example):

$data = $_POST;
unset($data['checkboxes_index']);
foreach($_POST['checkboxes_index'] as $fieldname){
    if(!isset($data[$fieldname])){
        $data[$fieldname] = 0;
    }
}

this will populate $data with $_POST values but with the unsent checkboxes defaulting to zero

If you know what fields will be checkboxes, you can just default these to zero, it will have same effect.

Pulley answered 21/8, 2023 at 23:0 Comment(0)
L
-5

"I've got a load of checkboxes that are by default checked" - this is how I solved my problem:

  1. if(($C1)OR($C2)OR... ($C18)){echo "some are checked!";} else{$C1='set';$C2='set';$C3='set';$C4='set';$C5='set';$C6='set';$C7='set';$C8='set';$C9='set';$C10='set';$C11='set';$C12='set';$C13='set';$C14='set';$C15='set';$C16='set';$C17='set';$C18='set';} //(if all are unchecked - set them to 'check' since its your default)
  2. the above line will execute the echo if some are unchecked
  3. but the checked ones will still have the value parameter set
  4. therefore, to keep them set, when writing them in the form, use if($C1){echo "checked";}
  5. use the values in the further logic...

!!! limitation of this method: you can not uncheck everything - they will all get back checked

Lingo answered 21/6, 2013 at 12:25 Comment(0)
T
-16

Simple answer. If your code has checked="checked" in it change this to unchecked="unchecked"

so your text should look something like this:

input type="checkbox" name="yourchosenname" unchecked="unchecked"

if it doesn't contain this, you could always add it

Thiosinamine answered 31/5, 2012 at 18:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.