Kamran Hassan
Kamran Hassan

Reputation: 139

Checkbox tree view with nesting parent and child both.?

I am trying to create tree view of multiple checkbox as tree everything working fine I just not being able to achieve goal to when child checkbox been check let its parent checkbox also checked. I find example from

http://experiments.wemakesites.net/css3-treeview-with-multiple-node-selection.html

 <div class="form-group form-show-validation row">
    <label for="name" class="col-lg-3 col-md-3 col-sm-4 mt-sm-2 text-right">Permissions <span class="required-label">*</span></label>
    <div class="acidjs-css3-treeview col-lg-4 col-md-9 col-sm-8">
        <ul>
            <li>
                
                <input type="checkbox" id="node-0" checked="checked" /><label><input type="checkbox" /><span></span></label><label for="node-0">Libraries</label>
                <ul>
                    <li>
                        <input type="checkbox" id="node-0-0" checked="checked" /><label><input type="checkbox" /><span></span></label><label for="node-0-0">Documents</label>
                        <ul>
                            <li>
                                <input type="checkbox" id="node-0-0-0" checked="checked" /><label><input type="checkbox" /><span></span></label><label for="node-0-0-0">My Documents</label>
                                <ul>
                                    <li>
                                        <input type="checkbox" id="node-0-0-0-0" /><label><input type="checkbox" /><span></span></label><label for="node-0-0-0-0">Downloads</label>
                                    </li>
                                    <li>
                                        <input type="checkbox" id="node-0-0-0-1" /><label><input type="checkbox" /><span></span></label><label for="node-0-0-0-1">Projects</label>
                                    </li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <input type="checkbox" id="node-0-1" /><label><input type="checkbox" /><span></span></label><label for="node-0-1">Music</label>
                        <ul>
                            <li>
                                <input type="checkbox" id="node-0-1-0" /><label><input type="checkbox" /><span></span></label><label for="node-0-1-0">My Music</label>
                            </li>
                            <li>
                                <input type="checkbox" id="node-0-1-1" /><label><input type="checkbox" /><span></span></label><label for="node-0-1-1">Public Music</label>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <input type="checkbox" id="node-0-2" /><label><input type="checkbox" /><span></span></label><label for="node-0-2">Pictures</label>
                        <ul>
                            <li>
                                <input type="checkbox" id="node-0-2-0" /><label><input type="checkbox" /><span></span></label><label for="node-0-2-0">My Pictures</label>
                            </li>
                            <li>
                                <input type="checkbox" id="node-0-2-1" /><label><input type="checkbox" /><span></span></label><label for="node-0-2-1">Public Pictures</label>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <input type="checkbox" id="node-0-3" checked="checked" /><label><input type="checkbox" checked="checked" /><span></span></label><label for="node-0-3">Video</label>
                        <ul>
                            <li>
                                <input type="checkbox" id="node-0-3-0" /><label><input type="checkbox" checked="checked" /><span></span></label><label for="node-0-3-0">My Videos</label>
                            </li>
                            <li>
                                <input type="checkbox" id="node-0-3-1" /><label><input type="checkbox" checked="checked" /><span></span></label><label for="node-0-3-1">Public Videos</label>
                            </li>
                        </ul>
                    </li>
                </ul>
            </li>
        </ul>
    </div>
</div>

Here is javascript code which will be required

  <script>
    $(".acidjs-css3-treeview").delegate("label input:checkbox", "change", function() {
var
    checkbox = $(this),
    nestedList = checkbox.parent().next().next(),
    nestedListp = checkbox.parent().prev().prev(),
    selectNestedListCheckbox = nestedList.find("label:not([for]) input:checkbox");
    selectNestedListCheckboxp = nestedListp.find("label:not([for]) input:checkbox");

if(checkbox.is(":checked")) {
    return selectNestedListCheckbox.prop("checked", true);
    return selectNestedListCheckboxp.prop("checked", true);
  }
   selectNestedListCheckbox.prop("checked", false);
    });
  </script>

Upvotes: 1

Views: 3644

Answers (2)

Aurovrata
Aurovrata

Reputation: 2279

Since my first answer below, I have developed a Hybrid HTML Dropdown plugin to solve the general case problem of checked lists and nested lists as well as the option to create thumbnail based check lists fields. So the above problem can now be solved with the following html/js,

function docReady(fn) {
  if (document.readyState!='loading'){
    fn();
  }else if (document.addEventListener){
    document.addEventListener('DOMContentLoaded', fn);
  }
}
docReady( (e)=>{
  let sel= document.querySelector('#nested-list');
  let hyd = new HybridDropdown(sel,{});
});
<link href="https://aurovrata.github.io/hybrid-html-dropdown/assets/css/hybrid-dropdown.css" rel="stylesheet"/>
<script src="https://aurovrata.github.io/hybrid-html-dropdown/assets/js/hybrid-dropdown.js"></script>


<div id="nested-list" data-tree-view="true" data-color="#ff26ffc9"
data-background-color="#454d4f">
  <script type="application/json">
    {
      "":"Select a dish",
      "Japan":{
        "sushi":{
          "label":"Sushi",
          "ps":"Pumpkin sushi",
          "as":"Avocado sushi",
          "tc":"Tomato sushi",
          "cs":"Carrot sushi"
        }
      },
      "India":{
        "dosa":{
          "label":"Dosa",
          "pd":"Plain dosa",
          "md":"Masala dosa",
          "myd":"Mysore dosa",
          "pr":"Paper roast"
        }
      }
    }
   </script>
</div>

Upvotes: 0

Aurovrata
Aurovrata

Reputation: 2279

Here is working demo by Fabien

$(function() {

  $('input[type="checkbox"]').change(checkboxChanged);

  function checkboxChanged() {
    var $this = $(this),
        checked = $this.prop("checked"),
        container = $this.parent(),
        siblings = container.siblings();

    container.find('input[type="checkbox"]')
    .prop({
        indeterminate: false,
        checked: checked
    })
    .siblings('label')
    .removeClass('custom-checked custom-unchecked custom-indeterminate')
    .addClass(checked ? 'custom-checked' : 'custom-unchecked');

    checkSiblings(container, checked);
  }

  function checkSiblings($el, checked) {
    var parent = $el.parent().parent(),
        all = true,
        indeterminate = false;

    $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
      })
      .siblings('label')
      .removeClass('custom-checked custom-unchecked custom-indeterminate')
      .addClass(checked ? 'custom-checked' : 'custom-unchecked');

      checkSiblings(parent, checked);
    } 
    else if (all && !checked) {
      indeterminate = parent.find('input[type="checkbox"]:checked').length > 0;

      parent.children('input[type="checkbox"]')
      .prop("checked", checked)
      .prop("indeterminate", indeterminate)
      .siblings('label')
      .removeClass('custom-checked custom-unchecked custom-indeterminate')
      .addClass(indeterminate ? 'custom-indeterminate' : (checked ? 'custom-checked' : 'custom-unchecked'));

      checkSiblings(parent, checked);
    } 
    else {
      $el.parents("li").children('input[type="checkbox"]')
      .prop({
          indeterminate: true,
          checked: false
      })
      .siblings('label')
      .removeClass('custom-checked custom-unchecked custom-indeterminate')
      .addClass('custom-indeterminate');
    }
  }
});
* { margin: 0; padding: 0; }

#page-wrap {
  margin: auto 0;
}

.treeview {
  margin: 10px 0 0 20px;
}

ul { 
  list-style: none;
}

.treeview li {
  background: url(http://jquery.bassistance.de/treeview/images/treeview-default-line.gif) 0 0 no-repeat;
  padding: 2px 0 2px 16px;
}

.treeview > li:first-child > label {
  /* style for the root element - IE8 supports :first-child
  but not :last-child ..... */
  
}

.treeview li.last {
  background-position: 0 -1766px;
}

.treeview li > input {
  height: 16px;
  width: 16px;
  /* hide the inputs but keep them in the layout with events (use opacity) */
  opacity: 0;
  filter: alpha(opacity=0); /* internet explorer */ 
  -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"; /*IE8*/
}

.treeview li > label {
  background: url(https://www.thecssninja.com/demo/css_custom-forms/gr_custom-inputs.png) 0 -1px no-repeat;
  /* move left to cover the original checkbox area */
  margin-left: -20px;
  /* pad the text to make room for image */
  padding-left: 20px;
}

/* Unchecked styles */

.treeview .custom-unchecked {
  background-position: 0 -1px;
}
.treeview .custom-unchecked:hover {
  background-position: 0 -21px;
}

/* Checked styles */

.treeview .custom-checked { 
  background-position: 0 -81px;
}
.treeview .custom-checked:hover { 
  background-position: 0 -101px; 
}

/* Indeterminate styles */

.treeview .custom-indeterminate { 
  background-position: 0 -141px; 
}
.treeview .custom-indeterminate:hover { 
  background-position: 0 -121px; 
}
    <div id="page-wrap">
    
       <h2>Treeview with Custom Checkboxes and Indeterminate State</h2>
        
     <ul class="treeview">
        <li>
            <input type="checkbox" name="tall" id="tall">
            <label for="tall" class="custom-unchecked">Tall Things</label>
            
            <ul>
                 <li>
                     <input type="checkbox" name="tall-1" id="tall-1">
                     <label for="tall-1" class="custom-unchecked">Buildings</label>
                 </li>
                 <li>
                     <input type="checkbox" name="tall-2" id="tall-2">
                     <label for="tall-2" class="custom-unchecked">Giants</label>
                     <ul>
                         <li>
                             <input type="checkbox" name="tall-2-1" id="tall-2-1">
                             <label for="tall-2-1" class="custom-unchecked">Andre</label>
                         </li>
                         <li class="last">
                             <input type="checkbox" name="tall-2-2" id="tall-2-2">
                             <label for="tall-2-2" class="custom-unchecked">Paul Bunyan</label>
                         </li>
                     </ul>
                 </li>
                 <li class="last">
                     <input type="checkbox" name="tall-3" id="tall-3">
                     <label for="tall-3" class="custom-unchecked">Two sandwiches</label>
                 </li>
            </ul>
        </li>
        <li class="last">
            <input type="checkbox" name="short" id="short">
            <label for="short" class="custom-unchecked">Short Things</label>
            
            <ul>
                 <li>
                     <input type="checkbox" name="short-1" id="short-1">
                     <label for="short-1" class="custom-unchecked">Smurfs</label>
                 </li>
                 <li>
                     <input type="checkbox" name="short-2" id="short-2">
                     <label for="short-2" class="custom-unchecked">Mushrooms</label>
                 </li>
                 <li class="last">
                     <input type="checkbox" name="short-3" id="short-3">
                     <label for="short-3" class="custom-unchecked">One Sandwich</label>
                 </li>
            </ul>
        </li>
    </ul>
    
    </div>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
  <script src="main.js"></script>

Upvotes: 1

Related Questions