Setting HTML Checkbox and HTML Radio Button Defaults

If you’ve been coding on the web for more than a few minutes, you’ll have used a form or two with checkboxes and radio buttons. Consider the following code:

<form action="." method="post">
<label><input name="mycheckbox" type="checkbox" value="1" /> checkbox</label>
<label><input name="myradio" type="radio" value="1" /> radio 1</label>
<label><input name="myradio" type="radio" value="2" /> radio 2</label>
<button type="submit">Submit</button>
</form>

<!-- output -->
<p>Value of mycheckbox: <?php echo $_POST['mycheckbox']; ?></p>
<p>Value of myradio: <?php echo $_POST['myradio']; ?></p>

What value is shown for mycheckbox and myradio when you hit Submit without checking any box?

The answer: an error is raised. It would depend on your PHP settings but, assuming strict error reporting is enabled, you’ll see “Notice: Undefined index” for both fields.

When a checkbox is unchecked or no radio button is selected, nothing is sent for those fields in the HTTP POST. Unlike other input boxes, there’s no default value — the POSTed field simply doesn’t exist. To make it work correctly, you need to check its existence on the server, e.g.

<?php
$mycheckbox = isset($_POST['mycheckbox']);
$myradio = (isset($_POST['myradio']) ? (int) $_POST['myradio'] : 0);
?>

This is fine presuming you know what fields to expect in a form. However, if the form itself was generated in some way, you couldn’t determine what fields it contained by looking at the POSTed values.

I never questioned this state of affairs until Andy Kirk commented on my recent article How to Create a Toggle Switch in CSS3. He produced an example which used hidden form values with the same name as the checkboxes and radio buttons to set a default (unchecked) value, e.g.

<input name="mycheckbox" type="hidden" value="0" />
<label><input name="mycheckbox" type="checkbox" value="1" /> checkbox</label>
<input name="myradio" type="hidden" value="0" />
<label><input name="myradio" type="radio" value="1" /> radio 1</label>
<label><input name="myradio" type="radio" value="2" /> radio 2</label>

Therefore, values for mycheckbox and myradio are always posted regardless. Andy discovered it within the PHP Zend framework and used it ever since. I’m embarrassed to admit I’d never seen the trick before or worked it out for myself.

A Good Solution?

The hidden field default trick is simple although it makes me slightly uncomfortable. You’re adding unnecessary elements to an HTML page and data to the HTTP POST to solve a server-specific problem. As an alternative, you could use JavaScript to locate all checkboxes and radio buttons then create the hidden fields but, if that code failed or was disabled, it could cause server issues.

My suggestion: if you know what fields a form contains, you don’t require hidden fields to set defaults. However, on those rare occasions you need a generic parser which can analyze any form, it’s a reasonable solution to a quirky problem.

This may not be a fancy HTML5 tutorial, but it’s a great tip. Thanks Andy — you’ve taught an old dog a new trick!

And if you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like HTML5 & CSS3 For the Real World.

Comments on this article are closed. Have a question about HTML? Why not ask it on our forums?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Chris Emerson

    Isn’t this relying on undocumented behaviour? Who’s to say that every browser will always pass through the checkbox/radio fields when they are used rather than the hidden fields? Seems dodgy to me.

    • http://www.optimalworks.net/ Craig Buckler

      I’m not convinced it’s undocumented — it certainly seems to work everywhere. But I agree that it feels a little dirty and I wouldn’t use it unless there was no alternative.

  • Graham Bradley

    I don’t think browsers will pass through the checkbox value instead of the hidden value; it will pass both. The HTML5 spec says the form data set is a tuple (no mention of overwriting existing values), and you can see the effect by using GET rather than POST e.g.

    ?mycheckbox=0&mycheckbox=1

    • Andy Kirk

      Yes, but output $_GET (at least in PHP) and you’ll see that the latter overrides the former.

      Cheers

  • DaveMaxwell

    I’ve used that methodology for years to allow for validations. It’s a tried and true, and simple method. Having them the same name is a bad idea, though as it can cause issues when retrieving them on the backside of the process.

    • Andy Kirk

      Hi – can you elaborate on what issues you’ve encountered using this method (with the same name)? I’ve never had any problems using it and would be curious to know…

      Cheers

  • http://clinov.com sylvain

    thanks Craig, I have implemented this approach to evaluate it.

  • John

    Many MVC frameworks, like Rails, Django, Laravel and ASP.NET, already do this by default with their HTML helpers. At least I know this is the case with checkboxes, where they set the default value to false and the checkbox value to true, so they evaluate to booleans on the server.

  • Liam

    For generated forms, make use of posting arrays of information, either using ids as the keys (as you would for radio buttons)

    <input type=”checkbox” name=”checkbox[1]” value=”1″ />
    <input type=”checkbox” name=”checkbox[2]” value=”1″ />
    <input type=”checkbox” name=”checkbox[37]” value=”1″ />

    or using ids as the values (easier to manage, and ideal for check boxes)

    <input type=”checkbox” name=”checkbox[]” value=”1″ />
    <input type=”checkbox” name=”checkbox[]” value=”2″ />
    <input type=”checkbox” name=”checkbox[]” value=”37″ />

    Then on the PHP side you are doing:

    if(!empty($_POST['checkbox'])) foreach($_POST['checkbox'] as $sKey => $sValue) {

    }

  • http://www.brothercake.com/ James Edwards

    I agree with your basic conclusion — this is a server-side issue, and nothing to do with HTML.

  • http://www.tonymarston.net Tony Marston

    I think this points to a hole in HTML. If a form contains a control then a value for that control should be included in the GET/POST array. If a control is Boolean then it should always return either TRUE/ON/1 or FALSE/OFF/0. Simply not sending anything instead of FALSE is not intuitive and therefore not good enough.

    I have been using the hidden control to send back FALSE for years, and it has worked flawlessly in every browser.

    • http://www.optimalworks.net/ Craig Buckler

      Well, it’s been like it since day one so I’m not convinced the hole will ever be filled.

  • Andy Kirk

    Hi Craig, thanks for the mention :-)
    “… adding unnecessary elements …” – they’re only unnecessary if you don’t need ‘em. In my opinion they’re necessary because I do need ‘em.

    Cheers

    • Lennie

      Can’t argue with that logic.

  • http://www.r-global.com Bill Rae

    It’s an interesting hack and that may work for radio buttons and checkboxes if the item is not checked when submitted. On the other hand if there is a single checkbox on the form which is checked by the user when the form is posted you end up with a list – in your example ’0,1′ once the form is posted. This means that you are no longer validating a single value or a boolean but a list and if you don’t handle it you will probably have an error. Somehow I think that is just as much work to handle than a simple server side check to see if the form field exists when posted and, if not, creating it and giving it a value of 0.

    I was pushed (forced) to do handle it on the front end I would probably use a javascript or jQuery function on form submit to give the unchecked item a value and make it checked so that it gets passed, something like this:

    $(document).ready(function(){
    $(‘#frmTest’).submit(function(e){
    e.preventDefault();
    if (!$(‘[name="mycheckbox"]‘).is(‘:checked’)) {
    $(“[name='mycheckbox']“).val(0);
    $(“[name='mycheckbox']“).prop(‘checked’, true);
    }
    frmTest.submit();
    });
    });

    Provided your form id is frmTest this should work with the latest jQuery js.

    The upside of using this method is that when/if the browser developers ever do change the browsers to handle the checkbox or radio fields more elegantly when forms are submitted you won’t have to change your code.

  • Nykeri

    Instead of bulking up your html with hidden elements, why not just create just create a functionmethod which determines whether the field is posted and return it or null. I’ve been using this and have encountered 0 problems and to me is a much better solution.

    // Determine whether the field was posted and return it or return null otherwise
    function post($name) {
    return (isset($_POST[$name])) ? $_POST[$name] : null;
    }

    // usage [Note the use of '===' rather than '==']
    if (post(‘mycheckbox’) !== null) { /* execute commands */ }