Problem Solved: Custom Checkbox not Working on Edge

Problem Solved: Custom Checkbox not Working on Edge

The problem

In the current project, I made a custom checkbox. The custom implementation used native control and didn't rely on any JavaScript, but for some reason, it didn't work on Edge.

It is a common technique to give style for the native HTML checkbox by having a label that contains input (for functionality) and span (for styling). Let's see simplified implementation.

See the Pen Custom checkbox example by Tatu Tamminen (@ttamminen) on CodePen.

Embedded JavaScript

The HTML specification says that all "successful controls" are part of submission. What it means is that, for example, a checkbox that is unchecked will not be part of the form post. Form not sending checkbox state causes issues to MVC frameworks as it cannot determine between unchecked and non-existing control.

There is an easy solution, add a hidden field with unselected value, for example, 0 or False. The name of the field should be same as checkbox name.

<label class="custom-checkbox">
  <input type="hidden" name="alarm" value="False" />
  <input class="custom-checkbox-input" name="alarm" type="checkbox" value="True">
  <span class="custom-checkbox-text">Alarm</span>
</label>

Here is a working example:

See the Pen Custom checkbox example with hidden field by Tatu Tamminen (@ttamminen) on CodePen.

Embedded JavaScript

Wait! Try with Edge, and you'll notice that checkbox state doesn't change.

The reason is that on Edge label is connected to the first input. Even if it is a hidden field.

To verify that this is the case, I added click event handler to the hidden field, and on Edge it did trigger.

Think about it, hidden field getting the click event!

The solution

There are two options: 1) move checkbox to be the first input element or 2) add for-attribute to the label.

Solution number one would look like this:

<label class="custom-checkbox">
  <input class="custom-checkbox-input" name="alarm" type="checkbox" value="True">
  <input type="hidden" name="alarm" value="False" />
  <span class="custom-checkbox-text">Alarm</span>
</label>

Solution number two:

<label for="alarm-state" class="custom-checkbox">
  <input type="hidden" name="alarm" value="False" />
  <input id="alarm-state" class="custom-checkbox-input" name="alarm" type="checkbox" value="True">
  <span class="custom-checkbox-text">Alarm</span>
</label>

I hope this will help you avoid same mistakes I made.