return 0
return 0

Reputation: 4366

<li> tree structure traversal not working in javascript/jquery

I have a piece of codetree structure in html document I want to traversal using javascript. The codetree (directory tree) is displayed as the following in html:

<ol id="start">
    <li>
        <label for="1">..</label>
        <input type="checkbox" id="1">
        <ol>
            <li>
                <label for="2">..</label>
                <input type="checkbox" id="2">
                <ol>
                    <li>
                        <label for="3">..</label>
                        <input type="checkbox" id="3">
                        <ol>
                            <li>
                                <label for="4">..</label>
                                <input type="checkbox" id="4">
                                <ol>
                                    <li>
                                        <label for="5">..</label>
                                        <input type="checkbox" id="5">
                                        <ol>
                                            <li class="file badfile">
                                            </li>
                                        </ol>
                                    </li>
                                </ol>
                            </li>
                            <li>
                                <label for="6">..</label>
                                <input type="checkbox" id="6">
                                <ol>
                                    <li>
                                        <label for="7">..</label>
                                        <input type="checkbox" id="7">
                                        <ol>
                                            <li class="file">
                                            </li>
                                        </ol>
                                    </li>
                                </ol>
                            </li>
                        </ol>
                    </li>
                </ol>
            </li>
        </ol>
    </li>
</ol>

I want to collapse the directory tree if the "file" (on the leave of the tree) is NOT a "badfile", else keep the tree expanded. The labels aren't exactly what I have for real code, but the structure is exactly the same. The <input> attribute "checkbox" determines whether the directory is expanded or collapsed.

Here is what I tried:

function collapse(node) {
    if ($(node > 'li').hasClass('file')) {
        if (!$(node > 'li').hasClass('badfile')) {
            $(node > 'li').addClass('hidden');
        }
        return;
    }
    else {
        $(node > 'li').each(function() {
            collapse($(this));
        })
        if (node.children(':visible').length == 0) {
            $(node).prop("checked", false);
        }
        return;
    }
}

collapse($("#start"));

The collapse doesn't respond at all, could anyone help me to troubleshoot this recursive function? Thanks!

Update: I revised to this, it still doesn't work, can anyone take a look?

function collapse(node) {
  node.children().each(function() {
    if ($(this).hasClass('file')) {
      if ($(this).hasClass('badfile')) {
        $(this).addClass('hidden');
      }
      return;
    }
    else {
      collapse($(this));
      if (node.children(':visible').length == 0) {
        node.prop('checked', false);
      }
    }
  });
}

Upvotes: 0

Views: 96

Answers (1)

Newbie
Newbie

Reputation: 4819

1) As 'charlietfl' pointed. You can not do $(node > 'li') as is not possible either all the content of $() is an object or a string. so $(node).children('li')

2) I will suggest you to read something about 'DOM Tree' http://www.w3schools.com/ is good to start. Even if jQuery will accept your function .children() or character > will always analize just the first level childs (in depth) so your most-outer <li> and nothing else. As objects with class badfile is a deep child of node you can only perform .find('li').each() that will select all matching objects either if direct childs or childs of childs and more...

function collapse(node) 
{
  node.children().each(function() 
  { 
    if ($(this).hasClass('file')) 
	{
      if ($(this).hasClass('badfile')) 
	  {
        $(this).addClass('hidden');
      }
      return;
    }
    else 
	{
      collapse($(this));
      if (node.children('ol').children(':visible').length == 0)
	  {
        node.children('input').prop('checked', false);
      }
	  else
	  {
		node.children('input').prop('checked', true);
	  }
    }
  });
}

collapse($("#start"));

As I told you, check how DOM tree works.

.hidden
{
	overflow: hidden;
	height: 0;
	display: none;
}

Upvotes: 1

Related Questions