Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POST unchecked HTML checkboxes

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?

like image 313
reach4thelasers Avatar asked Nov 27 '09 15:11

reach4thelasers


People also ask

How do you make a checkbox unchecked in HTML?

attr("checked","checked"); To uncheck the checkbox: $("#checkboxid").

How do you make a checkable box in HTML?

The <input type="checkbox"> defines a checkbox. The checkbox is shown as a square box that is ticked (checked) when activated. Checkboxes are used to let a user select one or more options of a limited number of choices. Tip: Always add the <label> tag for best accessibility practices!

How do I uncheck all checkboxes?

Click event on Checkbox with class='checkbox'Check total checkbox is equal to total checked checkboxes. If it is equal then set check all checkbox checked otherwise unchecked.


25 Answers

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>
like image 110
Sam Avatar answered Oct 07 '22 16:10

Sam


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;
    }
}
like image 20
vishnu Avatar answered Oct 07 '22 16:10

vishnu


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).

like image 30
Marcel Ennix Avatar answered Oct 07 '22 17:10

Marcel Ennix


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.

like image 22
SimonSimCity Avatar answered Oct 07 '22 18:10

SimonSimCity


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');
        }
    })
})
like image 27
Rameez SOOMRO Avatar answered Oct 07 '22 18:10

Rameez SOOMRO


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.

like image 21
Shailesh Kumar Avatar answered Oct 07 '22 17:10

Shailesh Kumar


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.

like image 23
Riley Stadel Avatar answered Oct 07 '22 18:10

Riley Stadel


$('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.

like image 24
Jeremy Avatar answered Oct 07 '22 16:10

Jeremy


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.

like image 44
Bart van Heukelom Avatar answered Oct 07 '22 16:10

Bart van Heukelom


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

like image 36
desw Avatar answered Oct 07 '22 17:10

desw


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

like image 45
TarranJones Avatar answered Oct 07 '22 16:10

TarranJones


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]);
}
like image 32
Wouter Avatar answered Oct 07 '22 16:10

Wouter


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
like image 21
Matt Holden Avatar answered Oct 07 '22 18:10

Matt Holden


"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";
like image 34
N Zhang Avatar answered Oct 07 '22 16:10

N Zhang


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.

like image 30
Werner Avatar answered Oct 07 '22 16:10

Werner


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;
    });
});
like image 43
Jimchao Avatar answered Oct 07 '22 16:10

Jimchao


$('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);
        }
    })
});
like image 24
Sajjad Shirazy Avatar answered Oct 07 '22 17:10

Sajjad Shirazy


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
)
like image 40
MarcoSpada Avatar answered Oct 07 '22 17:10

MarcoSpada


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);
    }
  });
}
like image 27
IgorAgatti Avatar answered Oct 07 '22 16:10

IgorAgatti


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

like image 40
Felipe Gonzalez Avatar answered Oct 07 '22 17:10

Felipe Gonzalez


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

like image 35
frag Avatar answered Oct 07 '22 16:10

frag


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.

like image 36
Ian Avatar answered Oct 07 '22 17:10

Ian


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

like image 38
Mehmet Ali Uysal Avatar answered Oct 07 '22 18:10

Mehmet Ali Uysal


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');
  }
});
like image 40
sbrbot Avatar answered Oct 07 '22 17:10

sbrbot


@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>
like image 37
Rodrigo Polo Avatar answered Oct 07 '22 18:10

Rodrigo Polo