Secret man
Secret man

Reputation: 23

How can i auto select children option when selected parent option Js, Jquery

I have structor like

<div id="choose-categories" class="ms-drop bottom" style="display: block;">
  <ul style="max-height: 250px;">
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="1">
        Du Lịch
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="3">
        Ẩm Thực
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="86">
        &nbsp;&nbsp;&nbsp;Ẩm Thực Đường Phố
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="87">
        &nbsp;&nbsp;&nbsp;Món Ngon
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="9">
        Videos Giải Trí
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="81">
        Làm Đẹp</label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="82">
        &nbsp;&nbsp;&nbsp;Nail
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="83">
        &nbsp;&nbsp;&nbsp;Trang Điểm
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="84">
        &nbsp;&nbsp;&nbsp;Làm Tóc
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="85">
        &nbsp;&nbsp;&nbsp;Tattoo
      </label>
    </li>
    <li class="ms-no-results" style="display: none;">
      No matches found
    </li>
  </ul>
</div>

What i need is i want choose level-0, it's will auto choose all lv-1 after it (child selection) and stop in lv-0 next. How can i do it with JS or Jquery

Upvotes: 2

Views: 696

Answers (5)

Mara Black
Mara Black

Reputation: 1751

If you can/are allowed to change the html, you can make it to look like a tree, like the snippet below.. and what I did was

  1. to add classes to each parent who has childrens and to each children itself (for the first group first-main-checkbox and first-sub-checkbox and for the second one with the second key word in class name)
  2. get all elements with document.querySelectorAll(".first-sub-checkbox"); which return a NodeList (see querySelectorAll )
  3. create a function who iterate through all elements returned by querySelectorAll and set the check state to true or false using a ternary operator
  4. apply the function at click, which select/deselect checkbox: addEventListener("click", function) (see addEventListener)

I'm not saying that it's the best solution, but it's a start..

var firstMain = document.querySelector(".first-main-checkbox");
var firstChildrens = document.querySelectorAll(".first-sub-checkbox");

var secondMain = document.querySelector(".second-main-checkbox");
var secondChildrens = document.querySelectorAll(".second-sub-checkbox");



function toggleCheck(childrens) {
  childrens.forEach(child => {
    child.checked = child.checked == true ? false : true
  })
}

firstMain.addEventListener("click", function() {
  toggleCheck(firstChildrens)
});
secondMain.addEventListener("click", function() {
  toggleCheck(secondChildrens)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="choose-categories" class="ms-drop bottom" style="display: block;">
  <ul style="max-height: 250px;">
    <li class="level-0">
      <label><input type="checkbox" name="selectItemallow[]" value="1">Du Lịch</label>
    </li>

    <li class="level-0">
      <label><input class="first-main-checkbox" type="checkbox" name="selectItemallow[]" value="3">Ẩm Thực</label>
      <ul>
        <li class="level-1">
          <label><input class="first-sub-checkbox" type="checkbox" name="selectItemallow[]" value="86">Ẩm Thực Đường Phố</label>
        </li>
        <li class="level-1">
          <label><input class="first-sub-checkbox" type="checkbox" name="selectItemallow[]" value="87">Món Ngon</label>
        </li>
      </ul>
    </li>

    <li class="level-0">
      <label><input type="checkbox" name="selectItemallow[]" value="9">Videos Giải Trí</label>
    </li>
    <li class="level-0">
      <label><input class="second-main-checkbox" type="checkbox" name="selectItemallow[]" value="81">Làm Đẹp</label>
    </li>
    <ul>
      <li class="level-1">
        <label><input class="second-sub-checkbox"type="checkbox" name="selectItemallow[]" value="82"> Nail</label>
      </li>
      <li class="level-1">
        <label><input class="second-sub-checkbox" type="checkbox" name="selectItemallow[]" value="83">Trang Điểm</label>
      </li>
      <li class="level-1">
        <label><input class="second-sub-checkbox" type="checkbox" name="selectItemallow[]" value="84">Làm Tóc</label>
      </li>
      <li class="level-1">
        <label><input class="second-sub-checkbox" type="checkbox" name="selectItemallow[]" value="85">Tattoo</label>
      </li>
    </ul>
    <li class="level-0">
      <label><input type="checkbox" name="selectItemallow[]" value="1">another lv 0 item</label>
    </li>
    <li class="ms-no-results" style="display: none;">
      No matches found
    </li>
  </ul>
</div>

Upvotes: 0

Mister Jojo
Mister Jojo

Reputation: 22353

you can do that

with a bonus on checked/unchecked level-1 action to resume level-0

const 
  allCats = document.querySelector('#choose-categories')
, LevCats = [...allCats.querySelectorAll('li')]  
;
allCats.onclick = ({target}) =>
  {
  if (!target.matches('input[type=checkbox]')) return
 
  let liParent = target.closest('li')
    , liRef    = LevCats.findIndex(x=>x===liParent)
    ;
  if (liParent.classList.contains('level-0'))
    {
    for (let i = ++liRef; i < LevCats.length; ++i)
    if (LevCats[i].classList.contains('level-1') )
      LevCats[i].querySelector('input[type=checkbox]').checked = target.checked
    else
      break 
    }
  else // if (liParent.classList.contains('level-1')) *** BONUS ***
    {
    while ( !LevCats[--liRef].classList.contains('level-0') ) {}
    if (target.checked)
      LevCats[liRef].querySelector('input[type=checkbox]').checked = true
    else
      {
      checkedCount = 0
      for (let i = ++liRef; i < LevCats.length; ++i)
      if (LevCats[i].classList.contains('level-1') )
        { if (LevCats[i].querySelector('input[type=checkbox]').checked ) checkedCount++ }
      else
        break;
      if (checkedCount === 0) LevCats[--liRef].querySelector('input[type=checkbox]').checked = false
      }
    }
  }
li.level-1 span::before { content : '\2015\2015'; color:lightgrey; }
<div id="choose-categories" class="ms-drop bottom" style="display: block;">
  <ul style="max-height: 250px;">
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="1">
        <span>Du Lịch</span>
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="3">
        <span>Ẩm Thực</span>
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="86">
        <span>Ẩm Thực Đường Phố</span>
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="87">
        <span>Món Ngon</span>
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="9">
        <span>Videos Giải Trí</span>
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="81">
        <span>Làm Đẹp</span>
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="82">
        <span>Nail</span>
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="83">
        <span>Trang Điểm</span>
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="84">
        <span>Làm Tóc</span>
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="85">
        <span>Tattoo</span>
      </label>
    </li>
    <li class="ms-no-results" style="display: none;">
      No matches found
    </li>
  </ul>
</div>

Upvotes: 0

charlietfl
charlietfl

Reputation: 171690

I believe this is what you want. When a level-0 checkbox changes you want each of the following level-1 to change the same as the one you changed.

You traverse to the parent <li> and use nextUntil() to get the following group. Then change checked property of each of those checkboxes

$('.level-0 :checkbox').change(function(){
   // from parent <li> get all siblings until next level-0
   const $level_1 = $(this).closest('li.level-0').nextUntil('.level-0');
   // set checked in them based on checked state of current one
   $level_1.find(':checkbox').prop('checked', this.checked);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="choose-categories" class="ms-drop bottom" style="display: block;">
  <ul style="max-height: 250px;">
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="1">
        Du Lịch
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="3">
        Ẩm Thực
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="86">
        &nbsp;&nbsp;&nbsp;Ẩm Thực Đường Phố
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="87">
        &nbsp;&nbsp;&nbsp;Món Ngon
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="9">
        Videos Giải Trí
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="81">
        Làm Đẹp</label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="82">
        &nbsp;&nbsp;&nbsp;Nail
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="83">
        &nbsp;&nbsp;&nbsp;Trang Điểm
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="84">
        &nbsp;&nbsp;&nbsp;Làm Tóc
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="85">
        &nbsp;&nbsp;&nbsp;Tattoo
      </label>
    </li>
    <li class="ms-no-results" style="display: none;">
      No matches found
    </li>
  </ul>
</div>

Upvotes: 3

Hanlet Esca&#241;o
Hanlet Esca&#241;o

Reputation: 17380

jQuery's nextUntil might be able to help a bit with this:

$(function() {
  $('.level-0').change(function () {
    var status = $('input[type="checkbox"]', this).is(':checked');
    var nextChks = $(this).nextUntil('.level-0');
    if (nextChks && nextChks.length > 0) {
      for (var i = 0; i < nextChks.length; i++) {
        $('input[type="checkbox"]', nextChks[i]).attr('checked', status).prop('checked', status);
      }
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="choose-categories" class="ms-drop bottom" style="display: block;">
  <ul style="max-height: 250px;">
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="1">
        Du Lịch
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="3">
        Ẩm Thực
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="86">
        &nbsp;&nbsp;&nbsp;Ẩm Thực Đường Phố
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="87">
        &nbsp;&nbsp;&nbsp;Món Ngon
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="9">
        Videos Giải Trí
      </label>
    </li>
    <li class="level-0">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="81">
        Làm Đẹp</label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="82">
        &nbsp;&nbsp;&nbsp;Nail
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="83">
        &nbsp;&nbsp;&nbsp;Trang Điểm
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="84">
        &nbsp;&nbsp;&nbsp;Làm Tóc
      </label>
    </li>
    <li class="level-1">
      <label>
        <input type="checkbox" name="selectItemallow[]" value="85">
        &nbsp;&nbsp;&nbsp;Tattoo
      </label>
    </li>
    <li class="ms-no-results" style="display: none;">
      No matches found
    </li>
  </ul>
</div>

Upvotes: 1

Filip Kov&#225;č
Filip Kov&#225;č

Reputation: 579

I am not sure but gonna try.

You have element inside of event parameter so get li from it by calling parent('li') then find all siblings that are after it by calling next('li') and do loop like this

const nexts = [];
par.next('li').foreach(function (elem) {
     if (elem.hasClass('level-0') && nexts.length > 0)
          return false; // break loop
     if (elem.hasClass('level-1'))
          nexts.push(elem); // add li element
});

then just go through nexts and for each find its input which you marked as checked. That's it.

Upvotes: -1

Related Questions