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.

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.

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.