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>

4
  • 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 : jsfiddle.net/d5mh5qzs/1 Commented Mar 13, 2015 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! Commented Mar 13, 2015 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? Commented Mar 13, 2015 at 17:51
  • Just noticed your code sample. Lol. Going to update my answer for you. Apparently I was blind. Commented Mar 13, 2015 at 18:32

1 Answer 1

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/

Sign up to request clarification or add additional context in comments.

3 Comments

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
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.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.