Question

I am looking to have multiple levels of selection, but the selecting function triggers the parent first, rather than the children and sometimes doesn't even register the children. I want to do something like:

<ul>
  <li>Level 1a
    <ul>
      <li>Level 2a</li>
      <li>Level 2b</li>
    </ul>
  </li>
  <li>Level 1b
    <ul>
      <li>Level 2c</li>
      <li>Level 2d</li>
    </ul>
  </li>
</ul>

Any ideas on how to make the click on the level 2 items register? I am looking to override it so that when selecting level 2, it unselects the parent and only shows the level 2 as highlighted.

Was it helpful?

Solution 2

The only solution I could come up with an unordered list was with invalid markup by closing the list items before the secondary unordered list like:

<ul>
  <li>Level 1a</li>
    <ul>
      <li>Level 2a</li>
      <li>Level 2b</li>
    </ul>
  </li>
  <li>Level 1b</li>
    <ul>
      <li>Level 2c</li>
      <li>Level 2d</li>
    </ul>
  </li>
</ul>

I didn't like this, so I setup the structure like:

<div class="selectable">
  <div id="level1">Level 1</div>
  <div class="subgroup level1">
    <div id="level1a">Level 1a</div>
    <div id="level1b">Level 1b</div>
  </div>
  <div id="level2">Level 2</div>
  <div class="subgroup level2">
    <div id="level2a">Level 2a</div>
    <div id="level2b">Level 2b</div>
  </div>
</div>

I then setup the selectable like:

$('.selectable').selectable({
  selected: function (event, ui) {
    if ($(ui.selected).hasClass('click-selected')) {
      $(ui.selected).removeClass('click-selected');
      $('.'+ui.selected.id).removeClass('click-selected');
      $('.'+ui.selected.id+' div').removeClass('click-selected');
    } else {
      $(ui.selected).addClass('click-selected');
      $('.'+ui.selected.id).addClass('click-selected');
      if ($(ui.selected).parent('.subgroup').length) {
        $(ui.selected).parent('.subgroup').removeClass('click-selected');
        var cNames = $(ui.selected).parent('.subgroup').attr('class').replace("subgroup","").split(" ");
        $.each(cNames, function(i,c){
          if ($(ui.selected).parent('.subgroup').children().length == $(ui.selected).parent('.subgroup').children('.click-selected').length) {
            $('#'+c).addClass('click-selected');
          } else {
            $('#'+c).removeClass('click-selected');
          }
        });
      }
    }
  },
  filter: "div:not(.subgroup)"
});

What this does is make any div a selector except for the subgroup one. I then add a new class click-selected as I wanted to be able to click selections on and off, while keeping the existing selections. I wanted the first level to be selected if all children were selected or unselected if they weren't and have the first level toggle all children on and off.

OTHER TIPS

You would want to make the children ul selectable, not the parent. Using your current example, do the following:

$(function() {
    $('ul').children('li').children('ul').selectable();
 });

DEMO: http://jsfiddle.net/dirtyd77/FHBMq/1/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top