In: , ,
On: 2008 / 09 / 07 Viewed: 77984 times
Shorter URL for this post: http://ozh.in/j7

I ran into an interesting problem, facing what is certainly an HTML limitation that had somehow never really occurred to me. The thing is: when you submit a form with empty fields, empty values are POSTed, except for checkboxes and radio buttons which are not posted at all, just as if they were no such field in the form.

For instance, this form:

  1. <form method="post" action="">
  2. <input type="text" name="input" value="">
  3. <input type="hidden" name="hidden" value="">
  4. <input type="checkbox" name="checkbox">
  5. </form>

Submitting it, leaving empty values and not checking the checkbox, you would get the following $_POST array (notice the missing "checkbox")

  1. array (
  2.   "input" => "",
  3.   "hidden" => ""
  4. )

In short: <input type="checkbox" name="field" value="something"> either gets submitted as field = "something" if checked, or doesn't exist if unchecked.

My problem was that I needed to process an arbitrary number of checkboxes while being able to know wether a checkbox was left unchecked, that is I needed to have a value for each checkbox in the $_POST array, either blank/off/empty or checked/on/whatever.

The solution I found was simple: before each checkbox, add a hidden field with the same name:

  1. <form method="post" action="">
  2. <input type="hidden" name="checkbox" value="">
  3. <input type="checkbox" name="checkbox">
  4. </form>

This way, there is always a value for field checkbox in the $_POST array: either "" if the checkbox was unchecked, or "on" if it was checked. I've uploaded a simple HTML form if you're curious to try: regular way, without the "special hidden" fields, or without the duplicate hidden fields. Submit the form with all fields left to empty and see the resulting $_POST array.

This simple yet effective and smart workaround was found by Cameron and I really love it. (And the image above is by Joey Rozier from a restaurant where you apparently can build your perfect burger, seems fun:)

This trick might or might now suit your need: for instance, client-side javascript serialization of the form could lead to something unexpected because of the duplicated fields. Also, this won't work with arrays of checkboxes (something like having multiple <input type="checkbox" name="field[]"/>). But for the particular case I had to deal with, it was very perfect. Love it.

Shorter URL

Want to share or tweet this post? Please use this short URL: http://ozh.in/j7

Metastuff

This entry "Posting Unchecked Checkboxes in HTML Forms" was posted on 07/09/2008 at 9:47 pm and is tagged with , ,
Watch this discussion : Comments RSS 2.0.

16 Blablas

  1. 1
    stratosg Greece »
    thought, on 08/Sep/08 at 12:32 am # :

    stumbled on the same problem several times and the solution defers each time because of my needs. what i usually do is have a hidden field called checkboxes or smth like that and store there a string like "checkbx1=0;checkbx2=1…". i have a small javascript that runs everytime a checkbox is changed and loops through all the checkboxes of the form and creates the string. serverside i just use a split and voila everything falls to place. the problem is when js is disabled but give or take it's ok… yours is a much simpler way but as you said is the solution for a limited variation of problems. also i must admit that i hadn't thought this simple before :) :) :)

  2. 2
    Carbonize United Kingdom »
    replied, on 19/Sep/08 at 4:22 pm # :

    What's wrong with the method most of us use which is

    1. $_POST['checkbox'] = (isset($_POST['checkbox'])) ? 1 : 0;
  3. 3
    stratosg Greece »
    said, on 19/Sep/08 at 11:24 pm # :

    nothing is wrong :) it's just another way to do it ;)

  4. 4
    Ozh France »
    wrote, on 20/Sep/08 at 9:46 am # :

    Carbonize ยป This works fine as long as you know how many checkboxes you have in the submitted form. The trick is when you *don't* know.

  5. 5
    Justin United States »
    thought, on 15/Oct/08 at 2:33 am # :

    This is a lifesaver, scratching my head on this for about an hour wondering if I could ever figure out how to account for something that doesn't exist. I knew there had to a simple, non-bloated code solution where you account for every checkbox, and this is it! Thanks

  6. 6
    Garrett United States »
    said, on 09/Aug/09 at 7:43 pm # :

    Freakin' awesome. THANK YOU. Was wracking my brain trying to figure out what to do when I have a dynamic amount of checkboxes and how to 'track' how many were there. Great idea, worked perfectly.

  7. 7
    Dazbert United Kingdom »
    commented, on 25/Aug/09 at 4:48 pm # :

    Great answer to a tricky problem. By far the most elegant workaround I could find, and seems like less of an overhead than querying the database and cross-referencing to the text file I'm storing the data in.

    Thanks!

  8. 8
    Phil Canada »
    replied, on 24/Apr/10 at 4:03 pm # :

    I've been doing this for years, except if you add

    at the END of the document instead of the front then it also works for arrays of checkboxes, you can also use it for arrays of radio buttons.

  9. 9
    InsanP Indonesia »
    said, on 30/Jun/10 at 5:28 am # :

    Works like charm! Thank you so much!
    Ordinary checking by using isset() is not enough in my case since I'm dealing with sessions and need to refresh the value of all checkboxes!

    Thanks again!

  10. 10
    Phil Canada »
    wrote, on 20/Jan/11 at 6:00 am # :

    Although I agree it is annoying that checkboxes and radio buttons do not get posted with "empty" values, many people don't seem to get it that if the box is not checked it doesn't have ANY value. A significant number of developers use these boxes relying only on the name, but if there is no value then there is nothing to post, and if the box is not checked there is no value. I have been coding these for years and one approach has been to include a hidden dummy (at the END of the form) with the same name and checked. This guarantees that the name will always be posted and always as an array, but also assumes the application is looking for specific values or ignoring empty values (a checkbox/radio button with no value= still has no real value).

    A second alternative is to send a hidden field containing a list of checkbox names, then at the host pre-process the input to interrogate this hidden list of checkbox names and add any with an appropriate "missing" indicator to the session environment, this assumes that variables can be added transparently at the host to the POSTed stream.

    A third alternative is to use javascript on the client to use the hidden field mentioned in alternative #2 above when the form is submitted to interrogate the form fields and if none of the boxes are checked then create a dummy entry and attach it to the DOM to be sent (still assumes that the application wants a real value=).

    The menu form shown earlier is a classic example of what should be a checkbox array where each value= is the name e.g.
    type="checkbox" name="sauces" value="Apricot Sauce"
    type="checkbox" name="sauces" value="Marinara Sauce"
    etc.
    so the application should be iterating through the array and checking the presence of the array before starting the iteration.

    There are many pros and cons to the W3C "successful" behaviour of an individual HTML element in a POST or GET, but the fact remains we should be writing defensive code, after all we never know when a 'bot may be trying to infiltrate our site.

    Phil

  11. 11
    Bejoy Netherlands »
    said, on 16/Mar/11 at 3:55 pm # :

    I did like this.

    …………
    ans in java script before submit..

    var elem = document.getElementById("i_chkbox")
    if (elem.checked == false){
    elem.checked = true;
    elem.value = "off"
    }
    ……………

    at the server side i get "off" or "on"

  12. 12
    Ross United States »
    thought, on 11/Jan/12 at 7:38 am # :

    Thanks for this! I can confirm that your method (hidden fields) works for simple jquery ajax requests where I use:
    dataString = $("#form").serialize();
    and
    $.ajax({
    type: "POST",
    url: "save_settings.php",
    data: dataString,
    dataType: "json",

  13. 13
    Nikenya United States »
    wrote, on 03/Aug/12 at 12:09 pm # :

    This is brilliant the only bad thing id that it limits on the number of tasks it can perform otherwise this has made work easy.

  14. 14
    gox Poland »
    said, on 31/Aug/12 at 5:14 pm # :

    This does not work on opera browser :(
    I'am trying with name="array[key]" and always get default, hardcoded checked or unchecked state. Very sad indeed…

  15. 15
    gox Poland »
    commented, on 31/Aug/12 at 5:16 pm # :

    Update, there is no different on input name, it never works under Opera :(

  16. 16
    JG Australia »
    replied, on 21/Apr/14 at 3:08 am # :

    This trick does not work if you wish to display the checkbox already checked. Every example of this trick that I found on the web assume that the form displays the checkbox unchecked.

    The best way to handle checkboxes is by having a framework that allows you to check if a form has been submitted. Then the logic is simple: if form has been submitted and the post value for the checkbox isn't set, the value to 0.

Leave a Reply

Comment Guidelines or Die

  • HTML: You can use these tags: <a href=""> <em> <i> <b> <strong> <blockquote>
  • Posting code: Post raw code (no <> &lt; etc) within appropriate tags : [php][/php], [css][/css], [html][/html], [js][/js], [sql][/sql], [xml][/xml], or generic [code][code]
  • Gravatars: Curious about the little images next to each commenter's name ? Go to Gravatar.
  • Spam: Various spam plugins on patrol. I'll put pins in a Voodoo doll if you spam me.
  • I will mark as Spam test comments, all comments with SEO names (ie "My Cool Online Shop" instead of "Joe") or containing forum-like signatures.

Read more ?