Checkbox Edge-Cases: How to ensure a checkbox was actually unchecked or just not displayed?

Working with checkboxes is usually simple. But there are some edge cases and lesser well-known features/attributes. Here I take a look at a few of these features, approaches to solving checkbox-related edge-cases, and HTML5-compliance.

A note before we start: The following examples are mostly written in HTML/Blade and Laravel, but the same applies to any framework, VanillaPHP and, of course, other languages too. The principles remain the same no matter which language you choose. With this, let's get started.

Checking if a checkbox is selected: the standard way. #

This is the trivial stuff. Validating if a checkbox was checked in normal circumstances is easy:

if ($request->has('name_of_your_checkbox')) {
// Is checked
} else {
// Isn't checked.
}

Assuming your $request-variable exposes a method has to check if a parameter was set (as it with Laravel), you can simply check if a checkbox was selected. As you can see, this is very trivial.

Checking if an optional checkbox is selected #

But if your checkbox isn't always visible (as it is an optional form element), you need to add a small workaround. Let's say you have this section in your form:

<form action="/save-article" method="POST">

<!-- other form fields -->

@if (auth()->user()->can('disableComments'))
<input
type="checkbox"
name="comments"
checked
>

@endif

<!-- more form fields -->

</form>

Here, the checkbox is only included in the form if auth()->user()->can('disableComments') returns true and thereby allowing the user to switch comments on or off. Hence, it might be included the request coming in or not. This in itself is fine, but how do you determine if the checkbox simply wasn't selected or wasn't displayed in the first place?

Let's go through the cases here:

To address this edge case we need to add a flag in form of a hidden form field to ensure we know if the checkbox was visible in the first place. Our form looks like this:

<form action="/save-article" method="POST">

<!-- other form fields -->

@if (auth()->user()->can('disableComments'))
<input
type="hidden"
name="has_comments_option"
value="1"
>


<input
type="checkbox"
name="allowComments"
checked
>

@endif

<!-- more form fields -->

</form>

Now, we can ensure our checks return sufficient details. The check would simply reduce to this:

// Enable comments if the user never had the checkbox or selected it...
$enableComments = !$request->has('has_comments_option') || $request->has('allowComments');

Until we might see an improved HTML which supplies any form fields, even if they are null or empty, we have to solve this checkbox edge case.

Ensure checkbox is unchecked after reloading #

In some cases, you want to ensure the checkbox has been explicitly checked, e.g. avoid it being re-checked by the browser after reloading. Such cases might include read confirmations for terms and conditions. You can achieve this by adding unchecked to the checkbox:

<input
type="checkbox"
name="read_and_accepted_terms_and_conditions"
unchecked
>

Alternatively, autocomplete="off" does the trick too.

HTML5-conform pre-selection of a checkbox #

Let's start with some basics. How are the checkboxes by default pre-selected?
Following w3c guidelines both the long as well as short-hand version are valid:

<input
type="checkbox"
name="your-checkbox"
checked="checked"
/>


<!-- or -->

<input
type="checkbox"
name="your-checkbox"
checked
/>

🙏🙏🙏

Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated 💖! For feedback, please ping me on Twitter.

Published