Skip to content
Advertisement

how to add “indeterminate” stage in parent checkbox by click child checkbox

enter image description here

Hello, I’m creating a select all functionality by check box, When we check one checkbox (City) it selects all checkboxes (Bombay, Delhi, Agra) of its child ul. And when uncheck a checkbox (City) it unchecks all checkboxes (Bombay, Delhi, Agra).

Now I need to add the “indeterminate” stage also. when the user uncheck any checkbox (Bombay, Delhi, Agra). It should add “indeterminate” stage in parent checkbox (City). How to achieve this, Kindly check the image for better understanding.

HTML

<ul class="theme-list-p">
                              <li>
                                <span class="fa fa-plus switch-btn"></span>&nbsp;&nbsp;<input type="checkbox"  name="" class="mt">&nbsp;&nbsp;City
                                <ul class="theme-list-c" style="display: none;">
                                  <li><input type="checkbox" class="red" name="">&nbsp;&nbsp;Bombay</li>
                                  <li><input type="checkbox" name="">&nbsp;&nbsp;Delhi</li>
                                  <li><input type="checkbox" name="">&nbsp;&nbsp;Agra</li>
                                </ul>
                              </li>
                              <li><span class="fa fa-plus switch-btn"></span>&nbsp;&nbsp;<input type="checkbox" name="">&nbsp;&nbsp;Colors
                                <ul class="theme-list-c" style="display: none;">
                                  <li><input type="checkbox" name="">&nbsp;&nbsp;Red</li>
                                  <li><input type="checkbox" name="">&nbsp;&nbsp;Green</li>
                                  <li><input type="checkbox" name="">&nbsp;&nbsp;Blue</li>
                                </ul>
                              </li>
                             
                            </ul>

jquery

<script type="text/javascript">
  $(document).on('change', '.theme-list-p li input', function() {

  if($('.theme-list-c li input').is(':checked')){
    
   
     $(this).parent('li input').prop('indeterminate', $(this).prop("checked"));
  }

  $(this).next('.theme-list-c').find('li input').prop('checked', $(this).prop("checked"));
});

  $(document).on('click', '.switch-btn', function(){
   $(this).toggleClass('fa-minus')
   $(this).closest("li").find(".theme-list-c").toggle()
  });

</script>

Advertisement

Answer

Consider the following.

$(function() {
  $(document).on('change', '.theme-list-p li input', function() {
    var prop = $(this).prop("checked");
    if ($(this).closest("ul").hasClass("theme-list-p")) {
      // Select & De-select All Scenario - Top Level
      console.log("Select All", prop);
      $(this).next("ul").find("li > input").prop("checked", prop);
    } else {
      // Child Selected
      console.log("Select Child", prop);
      if ($(this).closest("ul").find("input:checked").length == $(this).closest("ul").find("input").length) {
        // Match All case
        $(this).closest("ul").parent().find("> input").prop({
          checked: true,
          indeterminate: false
        });
      } else if ($(this).closest("ul").find("input:checked").length > 0) {
        // Match one or more, not all
        $(this).closest("ul").parent().find("> input").prop("indeterminate", true);
      } else {
        // Match None
        $(this).closest("ul").parent().find("> input").prop({
          checked: false,
          indeterminate: false
        });
      }
    }
  });

  $(document).on('click', '.switch-btn', function() {
    $(this).toggleClass('fa-minus')
    $(this).closest("li").find(".theme-list-c").toggle()
  });
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga+ri4AuTroPR5aQvXU9xC6qOPnzFeg==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="theme-list-p">
  <li>
    <span class="fa fa-plus switch-btn"></span>&nbsp;&nbsp;<input type="checkbox" name="" class="mt">&nbsp;&nbsp;City
    <ul class="theme-list-c" style="display: none;">
      <li><input type="checkbox" class="red" name="">&nbsp;&nbsp;Bombay</li>
      <li><input type="checkbox" name="">&nbsp;&nbsp;Delhi</li>
      <li><input type="checkbox" name="">&nbsp;&nbsp;Agra</li>
    </ul>
  </li>
  <li><span class="fa fa-plus switch-btn"></span>&nbsp;&nbsp;<input type="checkbox" name="">&nbsp;&nbsp;Colors
    <ul class="theme-list-c" style="display: none;">
      <li><input type="checkbox" name="">&nbsp;&nbsp;Red</li>
      <li><input type="checkbox" name="">&nbsp;&nbsp;Green</li>
      <li><input type="checkbox" name="">&nbsp;&nbsp;Blue</li>
    </ul>
  </li>

</ul>

Please see: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#indeterminate_state_checkboxes

In your code, you were targeting with .parent() and when when click was on a child element, of a list, that was a child of another list, you did not get the expected results.

Your logic also did not allow for multiple selection or if the selection is All or None. This code accounts for all these scenarios.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement