The steps to building a personalized checkbox that includes an indeterminate state

I've been attempting to achieve an indeterminate state for a custom checkbox without success. My efforts using css have not yielded the desired outcome.

This is what I've tried so far:

$(document).ready(function() {

  var checkboxes = document.querySelectorAll('input.subOption'),
    checkall = document.getElementById('option');

  for (var i = 0; i < checkboxes.length; i++) {
    checkboxes[i].onclick = function() {
      var checkedCount = document.querySelectorAll('input.subOption:checked').length;

      checkall.checked = checkedCount > 0;
      checkall.indeterminate = checkedCount > 0 && checkedCount < checkboxes.length;
    }
  }

  checkall.onclick = function() {
    for (var i = 0; i < checkboxes.length; i++) {
      checkboxes[i].checked = this.checked;
    }
  }
  
  // intermediate class 

  // $("input[type='checkbox'].subOption").change(function(){
  //     var a = $("input[type='checkbox'].subOption");
  //     if(a.length == a.filter(":checked").length){
  //         alert('all checked');
  //     }else{
  //         alert('one checked');
  //         $(this).parent().parent().parent().prev().find('span').addClass('intermediate');
  //         $(this).parent().parent().parent().prev().find('input:checked');
  //     }
  // });

});
/* Customize the label (the container) */

.container-check {
  position: relative;
  padding-left: 25px;
  margin-bottom: 11px;
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  font-weight: normal;
}

.container-list ul {
  list-style: none;
  margin-left: -14px;
}


/* Hide the browser's default checkbox */

.container-check input {
  position: absolute;
  opacity: 0;
}


/* Create a custom checkbox */

.checkmark {
  position: absolute;
  top: 0;
  left: 0;
  height: 16px;
  width: 16px;
  background-color: #fff;
  border: solid 1px #626579;
  border-radius: 4px;
}


/* On mouse-over, add a grey background color */

.container-check:hover input~.checkmark {
  background-color: #fff;
}


/* When the checkbox is checked, add a blue background */

.container-check input:checked~.checkmark {
  background-color: #25a5bd;
  border: solid 1px #25a5bd;
}


/* Create the checkmark/indicator (hidden when not checked) */

.checkmark:after {
  content: "";
  position: absolute;
  display: none;
}


/* Show the checkmark when checked */

.container-check input:checked~.checkmark:after {
  display: block;
}


/* Style the checkmark/indicator */

.container-check .checkmark:after {
  left: 5px;
  top: 2px;
  width: 4px;
  height: 9px;
  border: solid white;
  border-width: 0 2px 2px 0;
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
}


/* disabled checkmark */

.container-check.disabled {
  cursor: not-allowed;
  opacity: 0.5;
}


/* Intermediate css */

.container-check .intermediate:after {
  left: 5px;
  top: 2px;
  width: 0px;
  height: 9px;
  border: solid white;
  border-width: 0px 0px 6px 3px;
  -webkit-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  transform: rotate(90deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="container-list">
  <ul>
    <li>
      <label class="container-check" for="option"><input id="option" type="checkbox"><span class="checkmark"></span>
                            Checkbox Selected</label>

      <ul>
        <li>
          <label class="container-check">
                                <input class="subOption" type="checkbox">
                                <span class="checkmark"></span>
                                Checkbox label 01</label>
        </li>
        <li>
          <label class="container-check">
                                <input class="subOption" type="checkbox">
                                <span class="checkmark"></span>
                                Checkbox label 02</label>
        </li>
        <li>
          <label class="container-check">
                                <input class="subOption" type="checkbox"> 
                                <span class="checkmark"></span>
                                Checkbox label 03</label>
        </li>
      </ul>
    </li>
  </ul>
</div>

Answer №1

Check out this CodePen

Also, take a look at this article on indeterminate checkboxes

$('input[type="checkbox"]').change(function(e) {
  var checked = $(this).prop("checked"),
    container = $(this).parent(),
    siblings = container.siblings();

  container.find('input[type="checkbox"]').prop({
    indeterminate: false,
    checked: checked
  });

  function checkSiblings(el) {
    var parent = el.parent().parent(),
      all = true;
      
    el.siblings().each(function() {
      return all = ($(this).children('input[type="checkbox"]').prop("checked") === checked);
    });
    
    if (all && checked) {
      parent.children('input[type="checkbox"]').prop({
        indeterminate: false,
        checked: checked
      });
      
      checkSiblings(parent);
    } else if (all && !checked) {
      parent.children('input[type="checkbox"]').prop("checked", checked);
      parent.children('input[type="checkbox"]').prop("indeterminate", (parent.find('input[type="checkbox"]:checked').length > 0));
      checkSiblings(parent);
    } else {
      el.parents("li").children('input[type="checkbox"]').prop({
        indeterminate: true,
        checked: true
      });
    }
  }
  checkSiblings(container);
});
body {
  padding: 20px;
}

ul {
  list-style: none;
  margin: 5px 20px;
}

li {
  margin: 10px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<h1>Indeterminate Checkboxes</h1>

<ul>
  <li>
    <input type="checkbox" name="tall" id="tall">
    <label for="tall">Tall Things</label>

    <ul>
      <li>
        <input type="checkbox" name="tall-1" id="tall-1">
        <la...*Removed lengthy HTML code for brevity*...

EDIT

Updated version of Pedrams:

$(document).ready(function() {

  var checkboxes = document.querySelectorAll('input.subOption'),
    checkall = document.getElementById('option');

  for (var i = 0; i < checkboxes.length; i++) {
    checkboxes[i].onclick = function() {
      var checkedCount = document.querySelectorAll('input.subOption:checked').length;

      checkall.checked = checkedCount > 0;
      checkall.indeterminate = checkedCount > 0 && checkedCount < checkboxes.length;
    }
  }

  checkall.onclick = function() {
    for (var i = 0; i < checkboxes.length; i++) {
      checkboxes[i].checked = this.checked;
    }
  }
});
.container-check input:indeterminate~.checkmark {
  background: #25a5bd;
}

.container-check input:indeterminate~.checkmark:before {
  content: ' ';
  position: absolute;
  top: 50%;
  left: 10%;
  transform: translate(0, -50%);
  width: 80%;
  height: 3px;
  background: white;
}


/* Customize the label (the container) */

.container-check {
  position: relative;
  padding-left: 25px;
  margin-bottom: 11px;
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  font-weight: normal;
}

.container-list ul {
  list-style: none;
  margin-left: -14px;
}


/* Hide the browser's default checkbox */

.container-check input {
  position: absolute;
  opacity: 0;
}


/* Create a custom checkbox */

.checkmark {
  position: absolute;
  top: 0;
  left: 0;
  height: 16px;
  width: 16px;
  background-color: #fff;
  border: solid 1px #626579;
  border-radius: 4px;
}


/* When the checkbox is checked, add a blue background */

.container-check input:checked~.checkmark {
  background-color: #25a5bd;
  border: solid 1px #25a5bd;
}


/* Create the checkmark/indicator (hidden when not checked) */

.checkmark:after {
  content: "";
  position: absolute;
  display: none;
}


/* Show the checkmark when checked */

.container-check input:checked~.checkmark:after {
  display: block;
}


/* Style the checkmark/indicator */

.container-check .checkmark:after {
  left: 5px;
  top: 2px;
  width: 4px;
  height: 9px;
  border: solid white;
  border-width: 0 2px 2px 0;
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
}


/* disabled checkmark */

.container-check.disabled {
  cursor: not-allowed;
  opacity: 0.5;
}


/* Intermediate css */

.container-check .intermediate:after {
  left: 5px;
  top: 2px;
  width: 0px;
  height: 9px;
  border: solid white;
  border-width: 0px 0px 6px 3px;
  -webkit-transform: rotate(90deg);... *Continued CSS code removed for brevity*
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="container-list">
  <ul>
    <li>
      <label class="container-check" for="option"><input id="option" type="checkbox"><span class="checkmark"></span>
      Checkbox Selected</label>
      <ul>
        <li>
          <label class="container-check">
          <input class="subOption" type="checkbox">
          <span class="checkmark"></span>
          Checkbox label 01</label>
        </li>
        <li>
          <label class="container-check">
          <input class="subOption" type="checkbox">
          <span class="checkmark"></span>
          Checkbox label 02</label>
        </li>
        <li>
          <label class="container-check">
          <input class="subOption" type="checkbox">
          <span class="checkmark"></span>
          Checkbox label 03</label>
        </li>
      </ul>
    </li>
  </ul>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A comprehensive guide on personalizing Bootstrap 4 tooltips to suit your specific needs

I would like to customize the tooltip in Bootstrap 4 based on the screenshot provided below: https://i.stack.imgur.com/wg4Wu.jpg <!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap Example</title> <meta chars ...

Tips for creating a dynamic text that adjusts to different screen sizes within a bootstrap button

When utilizing the w3.css and bootstrap libraries to add a link button, an issue arises when resizing the screen as the text inside the button does not respond accordingly. How can we ensure that the text fits within the button based on the screen resoluti ...

Is there a way to automatically apply a class named "bottom" to the element with the ID "sidebar" when it reaches the bottom of its container?

I have implemented code that adds a CSS class called fixed to the element with ID #sidebar once it reaches a specific distance from the top of the webpage, depending on the page type (e.g. home, single, or page). In a similar manner, I am looking to add a ...

Adding Labels to Doughnut Charts in React using Chart.js 2.0

Currently, I'm exploring the world of data visualizations using react, react-chartjs-2, and chart.js version 2.2.1. While searching for a solution to my inquiry, I came across a potentially relevant answer on this link (specifically check out the upda ...

Navigating through the Document Object Model within a table

I'm working with an HTML table that contains a delete button in each row's last column. When the button is clicked, I want to delete the entire row. However, my current code only deletes the button itself and not the entire row: var buttons = do ...

Troubleshooting a text alignment problem with form-group in the Bootstrap framework

Currently, I am in the process of building a form that consists of several form-group elements. My main issue arises when dealing with long text as it causes alignment problems. Could you kindly take a look at the problem through this link: http://jsfidd ...

Tips for arranging three images in a single row

I have 3 payment logos in my footer that I want to center and align in one row. Can someone help me with this? sliki { text-align: justify; } sliki img { display: inline-block; width: 75px; height: 100px; padding: 7px; margin-top: -5px; ...

Preventing page unloading by utilizing a modal window

I am working on a functionality to detect any changes in textareas on a page and prompt the user with a custom modal window before they navigate away without submitting. I want to give the user the option to either leave the page or stay and submit the dat ...

Changing the size of a dynamic watermark png in php

I'm trying to automate the resizing of a watermark to cover 1/4 of an image. The code for the watermark is functioning, but I'm facing issues with resizing it correctly. <?php $image = $_GET['src']; $path_parts = pathinfo($image); ...

Tips for changing the font size of labels in a tree view using Material UI

While working with material ui treeview, I have customized the fontSize for each treeItem as shown below: <TreeItem key={mainCategory.name} nodeId={mainCategory.name} label={mainCategory.name} disabled={ ...

Styling images and text in CSS within a jQuery UI autocomplete widget

I am currently using an autocomplete widget that displays text along with images. The results I have right now are not meeting my requirements. I want to customize the appearance of my results so that the words 'test' and either 'Federico&a ...

The feature to Select/DeSelect All does not function properly when dealing with individual records

Here's the JavaScript code I'm working with: if (document.forms[0].Check_All.value=="Select All") { for (i = 0; i < chk.length; i++) { chk[i].checked = true; document.forms[0].Check_All.value = "DeSel ...

Having trouble getting AJAX POST request to Slim framework to work

Trying to send data via jQuery's ajax to my slim api Below is the jQuery code: $.ajax({type:'POST',url:'/api/insert',dataType:'json',data:{name:'matname',label:'Material Name'}, success:funct ...

Difficulty replicating 3 input fields using JavaScript

Combining the values of 3 input fields into 1 Displaying 'fname mnane lname' in the fullname input field. Then copying the fullname value into another input field called fullname2. Check out the code below for both HTML and JavaScript implemen ...

Failure of jQuery ajax success callback to trigger

I have been using jQuery's $.ajax method in my code to fetch data from a JSONP-compatible web service. It seems like everything is working fine as I am able to receive the response and display the data in my HTML. However, I am facing an issue where t ...

Having trouble getting rid of the border-bottom?

I have been attempting to customize the appearance of the React Material UI tabs in order to achieve a design similar to this: https://i.stack.imgur.com/tBS1K.png My efforts involved setting box-shadow for the selected tab and removing the bottom border. ...

Removing an item from an array using AngularJS with Underscore or another method

Although my question may seem similar to others, it is unique! Please review to understand my specific situation. I am dealing with an array of objects that looks like this $scope.events =[ { $$hashKey: "009" _allDay:false _i ...

Preventing default form submission in jQuery: How to cancel it when a certain condition is met

I have a contact form where I validate the input values upon clicking on the submit button. If there is at least one empty input, I trigger an alert and prevent the form submission by using preventDefault. However, if all inputs are filled and submitted, t ...

Node.js is throwing an error code 344, indicating that it is not possible to manipulate headers after they have already been

I'm still learning about Node and I've encountered this confusing error that I can't seem to figure out. I've searched for similar cases online, but none of them quite match mine. Any help would be greatly appreciated. From what I gathe ...

I'm currently working with React and experiencing issues with my components being unrendered

I'm currently navigating a React tutorial and I'm having issues getting this code to display some buttons. I'm utilizing codepen.io to work on the code and can provide the tutorial link if needed. const clips = [ { keyCode: 81, key ...