4

I'm currently doing some DOM traversal with jQuery, I'm trying to select each element one at a time in #treeList when button is clicked, but once it goes through the second list #innerList, it will select all elements in that list, and continue on down the list on click. How can you continue through #innerList like it does with #treeList?

$("#MoveDown").click(function() {
  $('.parentStyle + li, li:eq(0)')
    .last()
    .addClass('parentStyle').siblings('li')
    .removeClass('parentStyle');
});
    .parentStyle {

      background-color: #F99;

    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <ul id="treeList">
    <li class="parent">Aunt Grace</li>
    <li class="parent">Mother Joan</li>
    <li class="parent">Father Joe
      <ul id="innerList">
        <li class="child">Son John</li>
        <li class="child">Son James</li>
        <li class="child">Daughter Aine</li>
      </ul>
    </li>
    <li class="parent">Uncle Tom</li>
    <li class="parent">Aunt Jen</li>
  </ul>
</div>

<button id="MoveDown">Move down</button>
Blazemonger
  • 90,923
  • 26
  • 142
  • 180
SPeoples
  • 57
  • 10
  • 1
    If you want to only select `Father Joe` when currently selected, you need to add a `span` or `div` wrapping so you can add your color. To select children `li`, you need to rework your entire code : http://jsfiddle.net/d5mh5qzs/1/ – Karl-André Gagnon Mar 13 '15 at 15:48
  • I didn't even consider the use of indexes... The only real reason for the use of the color is to show that the selection was made on button click. Thank you, i very much appreciate it! – SPeoples Mar 13 '15 at 15:52
  • Are you wanting to go through the upper list, and if you get to an LI that contains a UL, traverse that one before continuing with the next LI? Or do you want to traverse through level 1, then into level 2? – Daved Mar 13 '15 at 17:51
  • Just noticed your code sample. Lol. Going to update my answer for you. Apparently I was blind. – Daved Mar 13 '15 at 18:32

1 Answers1

3

I am not 100% on how you want the traversal to work but I am going to take a stab at it with this assumption:

The way you would like it to work is to travel through all LIs that are immediate children of a given UL (lvl 0). If an LI contains a UL (lvl1) you would like to dip into that sub-list (lvl 1) before continuing back through the parent adjacent LIs (lvl 0).

If this assumption is accurate, this code would accomplish that:

$('.clickit').click(function() {
    var level = 0;
    var $list = $('#treeList');
    traverseList($list, level);
});

function traverseList($list, level) {
    if ($list.length > 0) { 
        $list.children('li').each(function() {
            $(this).prepend(level);
            if ($(this).children('ul')) {
                traverseList($(this).children('ul'), level + 1);
            }
        });
    }
}

And an accompanying Fiddle would demo it: http://jsfiddle.net/xhh4wqv7/1/

Update: Because I didn't read your original code sample, or didn't pay proper attention, I didn't answer with exactly what you were looking for. Since I saw you are going 1 by 1 to the next one and adding a class, I updated a new Fiddle.

Using the index() method, you can keep track of where you are in the tree. I think this might be the easiest way to traverse. The only complication comes if you want to keep styling on the parent node, or want to add a different class, but that can be accomplished with a .closest('li') at the least.

Code:

$("#MoveDown").click(function () {
    var $tree = $('#treeList');
    var $li = getLi($tree);
    $tree.find('li').removeClass('parentStyle');
    $li.addClass('parentStyle');    
});

function getLi($tree) {
    var $li = $tree.find('.parentStyle').last();
    var $liList = $tree.find('li');
    var idx = $liList.index($li);
    if (idx < 0 || idx == $liList.length) { return $liList.first(); }
    else { return $liList.eq(idx + 1); }
}

Fiddle: http://jsfiddle.net/xhh4wqv7/4/

Daved
  • 2,082
  • 1
  • 18
  • 23
  • That's actually a nice explanation, but per @Karl-André Gagnon's jsfiddle, I fiddled around with divs and such and got it working the way I needed so that each individual element is selected on click! Thanks anyway – SPeoples Mar 13 '15 at 19:51
  • 1
    Commented before I got back to my machine and updated it ;) Glad you got something working. I did post an alternative more according to what you need too, jic. – Daved Mar 13 '15 at 19:53
  • Haha. I just noticed the fiddle you referred. I think it's the exact same approach I did. Bah, not my day for paying attention apparently. – Daved Mar 13 '15 at 19:54