A very simple on off toggle checkbox

Turn your checkbox into an on off switch. The focus of this demonstration is not css so you will largely be tackling that yourself as an exercise for the reader.

Our finished product switches on and off all day.

It changes in state from on to off and from off to on. Underlaying the visual is an optional checkbox input which responds with it.

class OnOffSwitch
{
    private _isActive: boolean = false;

    onActive: Function;
    onInactive: Function;

    element: HTMLElement;
    parts: {
        handle: HTMLElement,
        checkbox: HTMLInputElement
    };
}

Lets take a look at our class. We are storing a boolean called _isActive we will always trust it is the current state of the switch. There are available onActive and onInactive functions for times that we want our switch to trigger a callback.

Our primary element is defined, a handle within it, and a checkbox. We will populate all of these things when we get to our constructor. But at this point we should take a look at what the HTML looks like.

<div class="on-off-switch">
    <div class="handle"></div>
    <input type="checkbox" checked>
</div>

In this case we are including the optional checkbox input, which is placed within the on-off-switch parent and we are providing it with a checked attribute. You will probably include a name on the input and a value as well. When your form is submitted it will register just like a normal checkbox.

Importantly in your css the input should be set display: none;. The rest of the element can look like whatever you like.

We will be setting and unsetting an is-active classname on the primary element.

constructor (element: HTMLElement, onActive?: Function, onInactive?: Function)
{
    this.element = element;
    this.parts = {
        handle: <HTMLElement>element.querySelector(".handle"),
        checkbox: <HTMLInputElement>element.querySelector("input[type=checkbox]")
    };

    this.onActive = onActive;
    this.onInactive = onInactive;
    this.element.addEventListener("click", this._onClick.bind(this));

    let isActive = !!this.element.dataset["checked"];
    if (this.parts.checkbox)
        isActive = this.parts.checkbox.checked;

    this.toggle(isActive);
}

private _onClick ()
{
    this.toggle();
}

isActive (): boolean
{
    return this._isActive;
}

Here we store references to important elements. Our callbacks are registered, and we set an event listener to monitor click events.

During instantiation we try to figure out the intended initial state of the control. We check for a data-checked attribute on element, then override it with the value of the underlaying checkbox if one exists. By default using this scheme the checkbox would be off.

At the end of initialisation to ensure everything is appropriately set up we run the toggle method on our class.

toggle (force: boolean = !this._isActive): boolean
{
    if (this.parts.checkbox)
        this.parts.checkbox.checked = force;
    this._isActive = force;

    this.element.classList.toggle("is-active", force);

    if (force && this.onActive)
        this.onActive();
    if (!force && this.onInactive)
        this.onInactive();

    return force;
}

Our toggle method takes an optional parameter named force which indicates whether the switch is changing from on to off or off to on. This parameter defaults to the opposite of what it is currently. Toggle the checkbox's checked attribute based on this value.

Toggle the is-active class on element to update the visual aspect of the event. Check whether callbacks are defined and if so run them.

We are finished with our class! Beneath we should run some code on page loaded to instantiate our switch objects.

document.addEventListener('DOMContentLoaded', () => {
    let elements = document.querySelectorAll(".on-off-switch");
    for (let i = 0; i < elements.length; i++) {
        new OnOffSwitch(<HTMLElement>elements.item(i));
    }
});

All elements given the class name on-off-switch will be imbued with masterful toggle switch prettiness.