What is the best approach to render nested rows in a data-table?

Viewed 658

I'm planning to create a tree data table for file browser and wondering how to render rows for files in a folder. The data is in a flat list of file paths but I'm able to re-format it to be the same as the structure of the folders.

I am debating if I have to render children of a folder as nested rows inside a row or if I could have them as sibling rows and just modify the padding to indicate the hierarchy?

This is how the data looks like:

[ {
    "name" : "Parent Folder",
    "path" : "/home/desktop/report",
    "size" : 2156754,
    "createdOn" : -1,
    "fileType" : "FOLDER",
    "itemId" : 478202,
  }, {
    "name" : "nested file",
    "path" : "/home/desktop/report/test.js",
    "size" : 15402,
    "createdOn" : 1595072355000,
    "fileType" : "FILE",
    "itemId" : 478203,
    "parentId" : 478202,
  }, {
    "name" : "nested folder",
    "path" : "/home/desktop/report/build",
    "size" : 2141352,
    "createdOn" : 1595072355000,
    "fileType" : "FOLDER",
    "itemId" : 478204,
    "parentId" : 478202,
    "faulty" : false,
    "newItemCount" : 478498,
    "itemCount" : 478498
  },
  {
    "name" : "nested folder",
    "path" : "/home/desktop/report/build/main",
    "size" : 2141352,
    "createdOn" : 1595072355000,
    "fileType" : "FILE",
    "itemId" : 478204,
    "parentId" : 478204,
  }
  ]
2 Answers

There are a lot of ways to archive your goal, but I doubt that there is the best way, they are just different. And it is always a question: "best it what way?"

But first of all, I would advice you not to use tables at all.

<li> is more semantically correct. Here https://onaircode.com/html-css-tree-view-examples/ you can find a lot of examples with codepens.

But if you really want to use <table>, you definitely don't need nested rows. That will be a total mess both in code and in HTML.

There is nothing simpler that padding. You don't even need some special HTML markup or CSS for that - just add as many &nbsp; as needed to strings with filenames.

td { border-right: solid; }
table { border-spacing: 0px }
<table>
  <tr>
    <td>folder1</td><td></td><td>1 file & 1 folder</td>
  </tr>
  <tr>
    <td>&nbsp;&nbsp;folder2</td><td></td><td>1 file</td>
  </tr>
  <tr>
    <td>&nbsp;&nbsp;&nbsp;&nbsp;file1</td><td>pdf</td><td>123Kb</td>
  </tr>
  <tr>
    <td>&nbsp;&nbsp;file2</td><td>txt</td><td>123Kb</td>
  </tr>
</table>

If you don't like &nbsp; you can instead add <span>s with a padding

td { border-right: solid; }
table { border-spacing: 0px }
span { padding: 3px; }
<table>
  <tr>
    <td>folder1</td><td></td><td>1 file & 1 folder</td>
  </tr>
  <tr>
    <td><span></span>folder2</td><td></td><td>1 file</td>
  </tr>
  <tr>
    <td><span></span><span></span>file1</td><td>pdf</td><td>123Kb</td>
  </tr>
  <tr>
    <td><span></span>file2</td><td>txt</td><td>123Kb</td>
  </tr>
</table>

As for <li> and your need to display additional columns... well yea, that can be a little more difficult, so if you don't strive for semantics or for code composition, you probably should stick with <table>s for now.

But anyway, here is one way to do it:

.tree { width: 90%; }
.file_box { display: flex; flex-direction: row; justify-content: flex-end; }
.filename { margin-right: auto; }
.type { width: 130px; overflow: hidden; border-right: solid; border-left: solid; }
.size { width: 130px; overflow: hidden; }
<ul class="tree">
  <li>
    <div class="file_box"><span class="filename">folder1</span><span class="type"></span><span class="size">1 file & 1 folder</span></div>
    <ul>
      <li>
        <div class="file_box"><span class="filename">folder2</span><span class="type"></span><span class="size">1 file</span></div>
        <ul>
          <li>
            <div class="file_box"><span class="filename">file</span><span class="type">pdf</span><span class="size">123Kb</span></div>
          </li>
        </ul>
      </li>
      <li>
        <div class="file_box"><span class="filename">file</span><span class="type">txtasdfasdfasdfasdfasdfasdf</span><span class="size">123Kb</span></div>
      </li>
    </ul>
  </li>
</ul>

Here you must choose the width of extra columns. Width won't change with the content (see last row). But I don't think that changing width of columns without user's consent is a good idea. If you think it is, you can create separate columns for filename's <li>-tree, for file types and for file sizes and place them next to each other with the help of Flexbox or Grid Layout, of just float them.

Definitely render children of the folder as nested rows, especially if you plan to perform operations on them in the future.

So, let's further down the line if you want to fetch all the parents from the table or fetch children of a particular parent than it will be easier to do that. But if you just padding than it's not a really optimal solution and can result in inconsistency.

Nesting is definitely the professional way to go. And also if you are looking for a direct implementation I would suggest using ag-grid because it already has everything you need.

https://www.ag-grid.com/javascript-grid-tree-data/

Related