Three state checkbox plugin with indeterminate state as a question mark

4.8k Views Asked by At

I'm developing a website and I've been looking for a plugin which allows me to use three state checkboxes.

Unfortunatly, all the stuff I've found (like here : http://extremefe.github.io/bootstrap-checkbox/) has their "indeterminate" state as a full square or as a dash. I need it to be a question mark ?

Do anyone has a solution to this ?

1

There are 1 best solutions below

15
On BEST ANSWER

You cannot have ? as an alias to null.

In simple words, this plugin uses three keywords to determine the three states of the checkbox, namely:

  • Checked: true
  • Unchecked: false
  • Intermediate: null

All these do not equate to undefined, which is technically not null in JavaScript and can be used for boolean operations. To use this plugin, you just need to include the jQuery Plugin:

<script src="jquery.js"></script>
<script src="bootstrap-checkbox.js"></script>

To use the three state checkbox, you just need to create a checkbox first:

<input type="checkbox" name="myCheck" id="myCheck" />

And then make it a three state one:

$("#myCheck").checkbox().chbxChecked(null);

To get the values from it:

switch ($("#checkbox2").chbxChecked()) {
    case true:
        console.log("Checkbox is Checked!");
        break;
    case false:
        console.log("Checkbox is Unhecked!");
        break;
    case null:
        console.log("Checkbox is in the Intermediate!");
        break;
}

You can have the full code here:

$(document).ready( function () {
    $("#myCheck").checkbox().chbxChecked(null);
    switch ($("#checkbox2").chbxChecked()) {
        case true:
            console.log("Checkbox is Checked!");
            break;
        case false:
            console.log("Checkbox is Unhecked!");
            break;
        case null:
            console.log("Checkbox is in the Intermediate!");
            break;
    }
});

And to change the icon from icon-stop to icon-question, please edit the source file, bootstrap-checkbox.js on line number 37:

if (checked === null) {
  element.addClass('ambiguous');
  element.html('<i class="icon-stop"></i>');
} else if (checked) {

And change it to:

if (checked === null) {
  element.addClass('ambiguous');
  element.html('<i class="icon-question"></i>');
} else if (checked) {

Hope this helps!

Fiddle:

/**
 * bootstrap-checkbox.js
 * (c) 2013~ Jiung Kang
 * Licensed under the Apache License, Version 2.0 (the "License");
 */

(function($) {
  "use strict";

  var replaceCheckboxElement = function(checkbox, element) {
    var value = element.val(),
        id = element.attr('id'),
        className = element.attr('class'),
        style = element.attr('style'),
        checked = !!element[0].checked,
        welNew = $('<div></div>');

    element.replaceWith(welNew);

    if (id) { welNew.attr('id', id) }
    if (className) { welNew.attr('class', className) }
    welNew.addClass('bootstrap-checkbox');
    if (style) { welNew.attr('style', style); }
    if (checked) { welNew.addClass('checked'); }

    checkbox.value = value;
    checkbox.checked = checked;
    checkbox.element = welNew;
  };

  var changeCheckView = function(element, checked) {
    element.removeClass('ambiguous');
    element.removeClass('checked');

    if (checked === null) {
      element.addClass('ambiguous');
      element.html('<i class="icon-question-sign"></i>');
    } else if (checked) {
      element.addClass('checked');
      element.html('<i class="icon-ok"></i>');
    } else {
      element.html('');
    }
  };

  var attachEvent = function(checkbox, element) {
    element.on('click', function(e) {
      var checked;
      if (checkbox.checked) {
        checked = false;
      } else if (checkbox.checked === false && checkbox.ambiguous === true){
        checked = null;
      } else {
        checked = true;
      }

      checkbox.checked = checked;
      changeCheckView(checkbox.element, checked);

      checkbox.element.trigger({
        type: 'check',
        value: checkbox.value,
        checked: checked,
        element: checkbox.element
      });
    });
  };

  var Checkbox = function(element, options) {
    replaceCheckboxElement(this, element);
    attachEvent(this, this.element);
    if (options && options.label) {
      attachEvent(this, $(options.label));
    }
  };

  $.fn.extend({
    checkbox : function(options) {
      var aReplaced = $(this.map(function () {
        var $this = $(this),
            checkbox = $this.data('checkbox');

        if (!checkbox) {
          checkbox = new Checkbox($this, options);
          checkbox.element.data('checkbox', checkbox);
        }

        return checkbox.element[0];
      }));

      aReplaced.selector = this.selector;
      return aReplaced;
    },

    chbxVal : function(value) {
      var $this = $(this[0]);
      var checkbox = $this.data('checkbox');

      if (!checkbox) {
        return;
      }
      if ($.type(value) === "undefined") {
        return checkbox.value;
      } else {
        checkbox.value = value;
        $this.data('checkbox', checkbox);
      }
    },

    chbxChecked : function(checked) {
      var $this = $(this[0]);
      var checkbox = $this.data('checkbox');

      if (!checkbox) {
        return;
      }
      if ($.type(checked) === "undefined") {
        return checkbox.checked;
      } else {
        checkbox.ambiguous = checked === null;
        changeCheckView($this, checked);

        checkbox.checked = checked;
        $this.data('checkbox', checkbox);
      }
    }
  });
})(jQuery);
$(document).ready(function () {
  $("#myCheck").checkbox().chbxChecked(null);
});
@import url("http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css");
@import url("http://extremefe.github.io/bootstrap-checkbox/css/bootstrap-checkbox.css");
body {font-family: 'Segoe UI'; margin: 10px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<label>
  <input type="checkbox" name="myCheck" id="myCheck" /> Click Me!
</label>

Check out the above working demo!