42

I have an HTML form - with PHP, I am sending the data of the form into a MySQL database. Some of the answers to the questions on the form have checkboxes. Obviously, the user does not have to tick all checkboxes for one question. I also want to make the other questions (including radio groups) optional.

However, if I submit the form with empty boxes, radio-groups etc, I received a long list of 'Undefined index' error messages for each of them.

How can I get around this? Thanks.

DaveS
  • 3,156
  • 1
  • 21
  • 31
Tray
  • 3,105
  • 8
  • 26
  • 25

8 Answers8

100

I've used this technique from time to time:

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

note: This gets interpreted differently in different server-side languages, so test and adjust if necessary. Thanks to SimonSimCity for the tip.

Community
  • 1
  • 1
ceejayoz
  • 176,543
  • 40
  • 303
  • 368
  • 8
    Relying on the web browser honouring the ordering of the successful form elements on a page, and your server side scripting honouring it too is asking for trouble. – KayEss Jul 20 '09 at 10:07
  • It works in all browsers I've encountered. Doesn't seem likely that that'll change, either. – ceejayoz Jul 20 '09 at 13:42
  • 10
    You deserve a better rating. Let's do some research! From the HTML 4.01 specification see "17.13.3 Processing form data" Step two: Build a form data set. "A form data set is a sequence of control-name/current-value pairs...". A sequence implies a logical order (you can look that up anywhere) consequently what you purpose might even be purposed by the standard. Even though it's not without flaws I'm intrigued to start using this right away. – John Leidegren Aug 10 '09 at 16:14
  • My problem is a bit more complicated than the one suggested here, but your solution fits my needs perfectly fine. – John Leidegren Aug 10 '09 at 16:16
  • If you're searching for a solution in another system than PHP, you may have to switch it around to get it work :) – SimonSimCity Jan 23 '12 at 14:30
  • @SimonSimCity Interesting, and counter-intuitive. Which system did you encounter that in? – ceejayoz Jan 23 '12 at 14:43
  • @ceejayoz Here's a link to a question where I wrote a bit more about how this is handled in other languages than PHP: http://stackoverflow.com/questions/1809494/post-the-checkboxes-that-are-unchecked/8972025#8972025 – SimonSimCity Apr 02 '12 at 14:23
  • +1 Great trick! BTW I used similiar trick for auto – Tom Lime Sep 06 '12 at 00:40
  • -1: When you consider you have to be conscious of how the server-side language interprets this, you may as well just make your logic handle it by the value either being sent or not. Then you eliminate excess HTML data, too. – deed02392 Apr 07 '14 at 11:15
43

Unchecked radio or checkbox elements are not submitted as they are not considered as successful. So you have to check if they are sent using the isset or empty function.

if (isset($_POST['checkbox'])) {
    // checkbox has been checked
}
Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • 1
    And in the form you need to make sure that the checkbox elements have a value set as otherwise some user agents won't consider the checkbox successful either. – KayEss Jul 20 '09 at 10:08
7

An unchecked checkbox doesn't get sent in the POST data. You should just check if it's empty:

if (empty($_POST['myCheckbox']))
     ....
else
     ....

In PHP empty() and isset() don't generate notices.

Greg
  • 316,276
  • 54
  • 369
  • 333
6

Here is a simple workaround using javascript:

before the form containing checkboxes is submitted, set the "off" ones to 0 and check them to make sure they submit. this works for checkbox arrays for example.

///// example //////

given a form with id="formId"

<form id="formId" onSubmit="return formSubmit('formId');" method="POST" action="yourAction.php">

<!--  your checkboxes here . for example: -->

<input type="checkbox" name="cb[]" value="1" >R
<input type="checkbox" name="cb[]" value="1" >G
<input type="checkbox" name="cb[]" value="1" >B

</form>
<?php


if($_POST['cb'][$i] == 0) {
    // empty
} elseif ($_POST['cb'][$i] == 1) {
    // checked
} else {
    // ????
}

?>


<script>

function formSubmit(formId){

var theForm = document.getElementById(formId); // get the form

var cb = theForm.getElementsByTagName('input'); // get the inputs

for(var i=0;i<cb.length;i++){ 
    if(cb[i].type=='checkbox' && !cb[i].checked)  // if this is an unchecked checkbox
    {
       cb[i].value = 0; // set the value to "off"
       cb[i].checked = true; // make sure it submits
    }
}

return true;

}

</script>
idf
  • 61
  • 1
  • 1
3

Use this

$myvalue = (isset($_POST['checkbox']) ? $_POST['checkbox'] : 0;

Or substituting whatever your no value is for the 0

Yuck
  • 49,664
  • 13
  • 105
  • 135
Cruachan
  • 15,733
  • 5
  • 59
  • 112
3

To add to fmsf's code, when adding checkboxes I make them an array by having [] in the name

<FORM METHOD=POST ACTION="statistics.jsp?q=1&g=1">
    <input type="radio" name="gerais_radio" value="primeiras">Primeiras Consultas por medico<br/>
    <input type="radio" name="gerais_radio" value="salas">Consultas por Sala <br/>
    <input type="radio" name="gerais_radio" value="assistencia">Pacientes por assistencia<br/>
    <input type="checkbox" name="option[]" value="Option1">Option1<br/>
    <input type="checkbox" name="option[]" value="Option2">Option2<br/>
    <input type="checkbox" name="option[]" value="Option3">Option3<br/>
    <input type="submit" value="Ver">

user58670
  • 1,438
  • 17
  • 17
2

We are trouble on detecting which one checked or not.

If you are populating form in a for loop, please use value property as a data holder:

    <?php for($i=1;$i<6;$i++):?>
    <input type="checkbox" name="active[]" value="<?php echo $i ?>"
    <?endfor;?>

If submit form you'll get order numbers of checkboxes that checked (in this case I checked 3rd and 4th checkboxes):

   array(1) {       
       ["active"]=>
          array(2) {
            [0]=>       
             string(1) "3"
            [1]=>
             string(1) "4"
          }
   }

When you are processing form data in loop, let's say in post.php, use following code to detect if related row is selected:

    if(in_array($_POST['active'] ,$i)) 
            $answer_result = true;
        else 
            $answer_result = false;

Final code for testing:

    <?php if (isset($_POST) && !empty($_POST)):
        echo '<pre>';
        var_dump($_POST);
        echo '</pre>';
    endif;
    ?>
    <form action="test.php" method="post">
    <?php for($i=1;$i<6;$i++):?>
    <input type="checkbox" name="active[]" value="<?php echo $i; ?>" />
    <?php endfor;?>
    <button type="submit">Submit</button>
    </form>
tolginho
  • 583
  • 9
  • 12
1

Although many answers were submitted, I had to improvise for my own solution because I used the customized check-boxes. In other words, none of the answers worked for me.

What I wanted to get is an array of check-boxes, with on and off values. The trick was to submit for each check-box on/off value a separator. Lets say that the separator is ";" so the string you get is

;, on, ;, ;, ;

Then, once you get your post, simply split the data into array using the "," as a character for splitting, and then if the array element contains "on", the check-box is on, otherwise, it is off.

For each check-box, change the ID, everything else is the same... and syntax that repeats is:

    <div>
    <input type="hidden" name="onoffswitch" class="onoffswitch-checkbox" value=";" />
    ...some other custom code here...
    <input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch1" checked>
    </div>

EDIT: instead of the ";", you can use some KEY string value, and that way you will know that you did not mess up the order, once the POST is obtained on the server-side... that way you can easily create a Map, Hash, or whatever. PS: keep them both within the same div tag.

3xCh1_23
  • 1,491
  • 1
  • 20
  • 39