Working with form check boxes can be a bit of a pain on sites with dynamic content. Saving the checked data is easy, but how do you easily save the unchecked value without manually adding it to an array from inside your code? Keep reading.

revealCMS is working great – I’m really starting to see a lot of its strengths (and, admittedly, some weaknesses) as I use it more and begin extending it. Due to how data is saved to the database, the HTML checkboxes were a bit of a problem when trying to save their unchecked state. Typically I save the post data to the object, where it is filtered and scrubbed, as necessary.Only the posted values get updated in their respective rows (makes sense, right?).

The problem is that unless a box is checked, it’s not going to be sent with the form – a problem if you have a checked box, but want to save the unchecked state.The first option is easy and probably the first solution you’d think of – write a couple lines of code for every single checkbox and set it to some default value if it’s left unchecked when the form is posted. Fine, but that takes more thinking than I want to do for something so simple, and it’s somewhat prone to error. Instead…

…the solution: Insert a hidden form field with the same name as the checkbox and the default value right before the place where the checkbox is located:
<input type="hidden" name="box1" value="0" /> <input type="checkbox" name="box1" value="1" />
What happens here is that when the checkbox is left unchecked, the hidden field’s value gets submitted, as-is. When the check box is checked, the hidden field’s POST value gets overwritten by the activated checkbox’s.
Unactivated: Hidden field’s value.
Activated: Check box’s value.

Told you it was easy!



38 Responses to “Unchecked checkbox values”  

  1. 1 Jan Haegeman

    Thank you! Another mystery of my HTML forms solved.

  2. 2 bc547c

    Thx.
    Great and that simple solution!

  3. 3 gligeti

    > hidden field’s POST value gets overwritten by the activated checkbox’s

    This is not correct. Both values will get submitted, HTML allows mutliple values with the same name. That is you’ll get something like:
    process.html?box1=0&box1=1 — checked
    process.html?box1=0 — unchecked

    now it may work for you, but your server side code must be prepared to handle multiple values for the same variable, but saying that it “gets overwritten” is incorrect.

  4. 4 bcr

    Hi!
    I actually have exactly that problem! Is it possible to have the form giving out just “0″ if it remains unchecked? And not “0, 1″ !
    Thank you very much for your help.

  5. gligeti,

    you’re right, technically both do get posted, however by the time it gets to your server-side script you’re likely only going to see the latter valeu = the 1. In PHP $_POST['box1'] would output a 1.

    Let’s keep the discussion going – if there’s a better solution, please, please, please post it! It can only help us all out!

  6. 6 Daniel

    Thank you very much. This is the solution I was looking for

  7. 7 Ed Hourigan

    If you’re using an array– it posts both values to the array.
    Example:

    both 0 & 15929
    get into

    review0[0]=0
    review0[1]=15929

    any solutions?

  8. Ed,

    That’s a tougher one to work-around. I’d be more likely to us javascript to change some of the values and field names. It would be a little bit tricky, and it depends on how your HTML is set-up to display previously-saved data (if any).

    Another way, a much messier way, is to write server-side code that will hopefully figure-out how to pick the right value. It could work, but depending on the form and your code, may not be worth the additional effort.

  9. 9 Greg

    If you know what you are expecting your POSTed data to be, which you should as you made the HTML form, then just create a new array from the POSTed one.

    You need to name the keys of the checkbox name array:
    EG

    When the form is posted, make a new array using ALL the key names you KNOW are used in the checkbox names

    Then use that new array to loop all keys. With each loop, check if the current key from your new array matches a key in the posted array.
    If no match then that key value is NO, if it is matched then that key value is YES.
    It’s IMPORTANT when you make the new array to make the keys in the same order as they appear in the html form or the loop wont match them in order and wont work correctly

    Here is the full script

    form.html page

    eat fruit
    eat bread
    eat apples

    post.php page

    //get check boxes user DID tick
    $post_array = $_POST['eat'];

    //make new array
    $array_keys = array(”fruit” => “”, “bread” => “”, “apples” => “”);

    //loop through new array, if key is matched then value is yes
    //else value is no

    foreach ($array_keys as $key => $value){
    if (array_key_exists($key, $post_array)){
    $new_array[$key]=”yes”;
    }else{
    $new_array[$key]=”no”;
    }
    }

    Your $new_array is now all the values submited fom tickboxes from the form, with the same key names, and for each one the user didnt tick the key is added and a value of “no” inserted.
    This makes it simple to insert into a db where user settings is a yes or no
    you can of course change what it outputs for the “yes” and “no” as desired

    Greg

  10. 10 Greg

    I should have realised my HTML code would be stripped.

    Here is the HTML for the above:

    form.html page

    Greg

  11. 11 Greg

    Ok, I’m trying one more time then giving up

    form.html page

    <input type="checkbox" name="eat[fruit]" value="yes" />
    <input type="checkbox" name="eat[bread]" value="yes" />
    <input type="checkbox" name="eat[apples]" value="yes" />

  12. Thank you! solved a lot of problems to me…
    the only problem i may think about this solution is the size of the document and the size of the post data,.
    i was already thinking about some very weird javascript solution.

  13. Using arrays in form fields, as we’ve seen, can be a difficult or tedious thing to work with.

    Here are a few thoughts I’ve had about this:
    1. In the past when I’ve used the arrayed fields, I was less concerned with the key than I was the actual value of the field being submitted. One example that comes to mind is having multiple file uploads from one page. Sure you can map each numeric key to a field in your database, but that can be solved by creating several different named fields: file1, file2, file3, etc. I’ve used the array for situations where I don’t know how many will be submitted, which ones will be submitted, or each key, regardless of order, corresponds to a new row in a database table.

    2. Rather than creating arrays that look like game[baseball], game[soccer], game[football], could you not just create single variables: baseball, soccer, football? Greg, your work-around is fine, but it accomplishes the same thing as creating $sports=array(baseball, soccer, football) and doing a foreach() on your POST array and seeing if the post key is in the $sports array.

    3. I thought about what could be the best of the best solutions: fully populating the object, e.g. $sports, with all the data from the database and simply pulling the field default values when the POST field doesn’t exist (implying the unchecked checkbox). But then I got to realizing that there are going to be cases where not every database field corresponding to my $sports object is going to be represented in an HTML form, which would default the DB field every time $_POST['football'] wasn’t there. So I was wrong – it’s not the best of the best… for me at least.

    4. How about creating an array of expected keys and default values for checkboxes in your PHP scripts? You can do that, but I think it’s too much extra work and specificity in larger apps. As much as possible I wan my apps to work with minimal additional coding. I would like to be able to extend my Games class with a BoardGame class without having to rewrite Games very much (at all), nor write a lot of code just to get BoardGame working. In my opinion $BoardGame->save(); should just work without having to write another save() method, except for those cases where differences in relational database schema need to be addressed.

    Food for thought….

  14. Somehow i missed the point. Probably lost in translation :) Anyway … nice blog to visit.

    cheers, Glabrous.

  15. 15 Ninenote

    Thanks man, that’s brilliant…

    great blog..

  16. 16 Greg

    Cameron, I understand your point, and in programming we should try to do as little as possible. Of course that’s not laziness, it’s good practice and usually leads to unbloated code, but sometimes you just have to sit and type what’s necessary however tedious.

    Using arrays for forms also allows for easier security checks.
    You can foreach the POSTED array and check each key only matches a key in your created array with in_array.
    As the array you create will only have key names that are allowed as per the html form, you can exit if a key name was found in the POSTED array that is not in your created array.

    This checks for people posting their own form with array key values that shouldn’t be there. Posted data from users is one of the main security issues in most websites in my opinion.

    Also, using a single array rather than a load of different input names also makes other sanitisation and security checking much easier for user inputted values as well as keys. As you simply run a foreach on the POSTED array and check each value for all your required checks.
    I.E. is_numeric if you are only expecting a numerical value from users, EREG a-Z0-9 etc

    Rather than having to duplicate the same checks for each form name, which you also have to type $_POST['name'] for each one as well.

    I do find arrays are a lot more useful in general when working with multiple user data.
    Obviously it’s not always best practice or necessary, but usually much easier.

    BTW, using this you posted above-
    “$sports=array(baseball, soccer, football)”
    will create an array called “sports” with VALUES, not keys. The keys will be automatically assigned as numerical starting from [0]

    Greg

  17. Just wanted to let you know I appreciate you posting this solution. Even though it is overwriting a value, and that’s not necessarily standard practice, and might cause problems in other situation, it fit my scenario perfectly and has yet to cause any problems.

    Kudos,
    joe

  18. 18 Adrian

    Works fine for me so far so thanks!!!!

  19. Joe,

    Though I haven’t come across any issues with this method yet, doesn’t mean it’s 100% perfect (though until somebody tells me otherwise, I’m going to assume it’s fine). I think the problem is that the checkbox input type should really have a default (non-checked) parameter.

    This method relies on the way server-side scripts interpret form input. As far as I’ve seen it’s in a very linear fashion, which is why this works.

    Greg,
    Good catch ($sports array). I wrote before I thought. Your points are good, and I have no problem with doing that. In fact, it’s a rather good solution to this problem. No matter how you look at this, we should all be validating user input.

  20. 20 Anton

    brilliant!

  21. a wonderful simple way to solve this “annoying” issue, i would also suggest creative a small javascript that can update the value on change, this would be difficult and might add more code to your “simple” form for new coders, but it’s more accurate and more dynamic, anyways, as far as a form with one or two check boxes this one is a nice small trick :) good jab cam.

  22. 22 Dre

    wow i dont usually post reply on anything but that was a amazing solution it really solved my problem so i just want to say thanks

  23. 23 vbkvbk

    How do you get this to work if you do not use PHP? I need to post to a txt file all checkbox fields (checked and unchecked, different value for each) to input into excel as csv file. If no field value is posted, the field is blank in the csv eg does not exist.

  24. @Rami, Definitely, and given a site that requires javascript (*gasp!*) for functional usage, that would be the thing to do. In that case, I would leave the name parameter off the checkbox altogether and just use the hidden field to avoid any potential problems; a quick script could also populate the boxes as well.

    @Dre, This blog is here to help – most entries are things I’ve dealt with at one point or another. I’m doing my part to share the wealth :)

    @vbkvbk,
    You’ll need some type of server-side app to process your post data. There are services online that allow you to create forms that they process. A simple Google search should give you what you need.

  25. 25 Tim

    THANK YOU! A simple solution to a painful, small and irritating problem.

  26. 26 Samo

    thank you :)

  27. 27 Adam

    Great solution, very much appreciated. The CakePHP documentation needs to have a gigantic “GOTCHA” section devoted to this stuff. Beginners like myself have wasted countless hours on nuances that weren’t otherwise obvious.

  28. Great solution, as simple as possible.
    Thank you !

  29. wowwwwwww…. yipeeee !!!! thanks a lot… brilliant !!!!

  30. 30 Tammy

    I have the exact problem. I need to do it in ASP and I’m not an ASP programmer, just try to do something quickly. How do I get rid of that comma delimited list and only get it to submit the hidden value when the box in unchecked?

    Or how do I do an if statment in the submit form so that a replacement of some sort can be done?

    thanks so much

    • This solution is back-end agnostic, so it’s up to the way your code handles POST data. I’m not familiar with ASP, but I imagine the variables you actually have access to might be whatever is written to the POST string last. That’s why the hidden input box works – the checkbox doesn’t even get sent unless it’s checked. If it was checked, the value would overwrite the value of the hidden input field. This all happens before your server gets a hold of the data. Make sense? You could also use JS to write a value to a hidden input field based on the value of the checkbox (checked/un-checked).

  31. 32 JC

    In JSP if you are using a bean (either via JSP tags or something else like Apache BeanUtils), you can use logic like this to make this work:

    class MyBean {

    Boolean checkval;

    public void setCheckval (boolean b) {
    if (checkval == null)
    checkval = b;
    else
    checkval = checkval | b;
    }

    }

    That will OR all of the “checkval” parameters together, but still leave MyBean.checkval as null if none were specified. If you aren’t using a bean, you can still apply similar logic when going through the request parameter map (go through the entire array of “checkval” values and do the same thing).

  32. 33 Shony

    Cameron, I love your thinking with this idea.
    is there any reason why we cannot do on the back end in PHP

    if ( empty($_POST['box1']) ) {
    $my_value = 0;
    } else {
    $my_value = $_POST['box1'];
    }

    Or we can also evaluate for isset instead of empty().

    And with this we may not even need the hidden input helper there on the form.

    No?

    • Shony,

      You can definitely do it that way, but it gets tedious if you have a lot of checkboxes – to have to pay attention to it in both your HTML and the PHP code. Consider the situation where you’re matching submitted form data against database field – only the matching set gets saved, you either have to manually write-in checks for every single checkbox field (a pain and error-prone if you forget one), or you can do something like this and not have to worry about it.

  33. 35 charliesvensson

    Fuckin hell! :D

    Ive been going crazy about this shit for a couple of months now! AND FINALLY SOME ONE DOES THE TRICK! :D

    Cant thank you enough!

  34. 36 James

    nice trick.
    saves a lot of hard work.
    thanks


  1. 1 Posting Unchecked Checkboxes in HTML Forms « planetOzh
  2. 2 Uncheck Checkbox Values | jappler.com

Leave a Reply