1

I have an autogenerated nested list structure, like so

<ul>
  <li>AAA</li>
  <li>BBB
    <ul>
      <li>111
        <ul>
          <li>XXX</li>
        </ul>
      </li>
      <li>222</li>
    </ul>
  </li>
  <li>CCC</li>
  ...etc...
</ul>

I want to layout in columns like so:

AAA    111    XXX
BBB    222
CCC

Using JQuery and a few CSS tags, it's then relatively easy to create a navigation style menu. e.g. select BBB from the first column, then this makes its children appear in the second column. Any other second level depth ULs are hidden.

What's leaving me stuck is simply how to style the list in the first place to put the depths into columns. I can add tags to each UL or LI to show the depth. But if I simply use relative positioning and move each column left, then column 1 will leave a vertical gap where each of the entries have been moved across. Absolute positioning works, but doesn't seem too neat. Any better ideas?

3
  • So how is that auto generated? Well, more importantly: can you change it in any way? maybe add classes or id's? Commented Jul 21, 2011 at 9:10
  • Can you show the actual code somewhere, so I can visualize your problem? Commented Jul 21, 2011 at 9:18
  • @Lollero - yes, I have some control over generation - so classes and IDs are possible. e.g. to mark the depth. Commented Jul 22, 2011 at 7:49

1 Answer 1

1

Using recursive functions this can be quite straight-forward: http://jsfiddle.net/uvxfm/1/.

If you want interactivity you could save which elements are children of which parent and show the appropriate ones on click.

var $tr = $("#tr");

function text(x) { // returns text without children
    return x.clone()
            .children()
            .remove()
            .end()
            .text();
}

function add(elem, level) {
    elem.children().each(function() { // iterate children
        var $this = $(this);
        var appendToThis = $tr.find("td").eq(level); // find td to append this level to
        var appendedText = text($this) + "<br>"; // text to append
        if(appendToThis.length) { // if td exists
            appendToThis.append(appendedText);
        } else { // if td doesn't exist yet
            $tr.append($("<td>").append(appendedText));
        }
        var children = $this.children();
        if(children.length) { // call recursively for children, if any
            add(children, level + 1);
        }
    });
}

add($("ul:eq(0)"), 0); // start the process

References: http://viralpatel.net/blogs/2011/02/jquery-get-text-element-without-child-element.html

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

1 Comment

Great example. This has pointed me in a sensible direction. Thanks

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.