jlb83
jlb83

Reputation: 2178

Displaying nested HTML ul list in columns

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?

Upvotes: 1

Views: 600

Answers (1)

pimvdb
pimvdb

Reputation: 154818

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

Upvotes: 1

Related Questions