Alex Park
Alex Park

Reputation: 714

Make a tree view from data

I have data about folders and them sub-folders. My problem is I don't know how to make nested sub-folders, for example, I have an array with folders. I got a folder 'test' which has an array of sub-folders labels and there's a folder 'daamn' and inside that 'daamn' there are other sub-folders. But that 'daamn' sub-folders not inside the second array, it's in the first array.

[
  {
    "path": ".TemporaryItems",
    "label": ".TemporaryItems",
    "rec": false
  },
  {
    "path": "1",
    "label": "1",
    "rec": false
  },
  {
    "path": "test/",
    "label": "test",
    "rec": true,
    "subDirectories": [
      {
        "name": "daamn",
        "isDir": true,
        "isEmpty": false
      },
      {
        "name": "New folder",
        "isDir": true,
        "isEmpty": true
      },
      {
        "name": "New folder (2)",
        "isDir": true,
        "isEmpty": true
      },
      {
        "name": "New folder (3)",
        "isDir": true,
        "isEmpty": true
      },
      {
        "name": "New folder (4)",
        "isDir": true,
        "isEmpty": true
      },
      {
        "name": "New folder (5)",
        "isDir": true,
        "isEmpty": true
      }
    ]
  },
  {
    "path": "test/daamn/",
    "label": "daamn",
    "rec": true,
    "subDirectories": [
      {
        "name": "anotherone",
        "isDir": true,
        "isEmpty": false
      }
    ]
  },
  {
    "path": "test/daamn/anotherone/",
    "label": "anotherone",
    "rec": true,
    "subDirectories": [
      {
        "name": "vade",
        "isDir": true,
        "isEmpty": true
      }
    ]
  },
  {
    "path": "test/daamn/anotherone/vade",
    "label": "vade",
    "rec": false
  },
  {
    "path": "test/New folder",
    "label": "New folder",
    "rec": false
  },
  {
    "path": "test/New folder (2)",
    "label": "New folder (2)",
    "rec": false
  },
  {
    "path": "test/New folder (3)",
    "label": "New folder (3)",
    "rec": false
  },
  {
    "path": "test/New folder (4)",
    "label": "New folder (4)",
    "rec": false
  },
  {
    "path": "test/New folder (5)",
    "label": "New folder (5)",
    "rec": false
  }
]

A 'rec' flag means there are other sub-folders or not.

As expected output, I need a DOM(actually just a list with <ul> and <li>). Something like this, sorry for paint enter image description here

Upvotes: 3

Views: 111

Answers (2)

tam.dangc
tam.dangc

Reputation: 2032

I use recursion to rebuild the tree, by that the sub-folder is children of the parent folder.

const arr = [
  {
    "path": ".TemporaryItems",
    "label": ".TemporaryItems",
    "rec": false
  },
  {
    "path": "1",
    "label": "1",
    "rec": false
  },
  {
    "path": "test/",
    "label": "test",
    "rec": true,
    "subDirectories": [
      {
        "name": "daamn",
        "isDir": true,
        "isEmpty": false
      },
      {
        "name": "New folder",
        "isDir": true,
        "isEmpty": true
      },
      {
        "name": "New folder (2)",
        "isDir": true,
        "isEmpty": true
      },
      {
        "name": "New folder (3)",
        "isDir": true,
        "isEmpty": true
      },
      {
        "name": "New folder (4)",
        "isDir": true,
        "isEmpty": true
      },
      {
        "name": "New folder (5)",
        "isDir": true,
        "isEmpty": true
      }
    ]
  },
  {
    "path": "test/daamn/",
    "label": "daamn",
    "rec": true,
    "subDirectories": [
      {
        "name": "anotherone",
        "isDir": true,
        "isEmpty": false
      }
    ]
  },
  {
    "path": "test/daamn/anotherone/",
    "label": "anotherone",
    "rec": true,
    "subDirectories": [
      {
        "name": "vade",
        "isDir": true,
        "isEmpty": true
      }
    ]
  },
  {
    "path": "test/daamn/anotherone/vade",
    "label": "vade",
    "rec": false
  },
  {
    "path": "test/New folder",
    "label": "New folder",
    "rec": false
  },
  {
    "path": "test/New folder (2)",
    "label": "New folder (2)",
    "rec": false
  },
  {
    "path": "test/New folder (3)",
    "label": "New folder (3)",
    "rec": false
  },
  {
    "path": "test/New folder (4)",
    "label": "New folder (4)",
    "rec": false
  },
  {
    "path": "test/New folder (5)",
    "label": "New folder (5)",
    "rec": false
  }
]

const folrLvl = str => str.split('/').filter(e => e !== "").length

function recursion(lvl = 1, path) {
    const rs = [] 
    const matched = arr.filter(e => 
      folrLvl(e.path) === lvl && (!path || e.path.indexOf(path) === 0))
    matched.forEach(ee => {
      const { path, rec, label } = ee
      if(!rec) rs.push(ee)
      else rs.push({path, label, rec, children: recursion(lvl + 1, path)})
    })
    return rs
}

const rs = recursion()
console.log(rs)

Upvotes: 1

I found react-ui-tree in which you can call renderNode in order to render a custom React Element.

<Tree
 paddingLeft={20}              // left padding for children nodes in pixels
 tree={this.state.tree}        // tree object
 onChange={this.handleChange}  // onChange(tree) tree object changed
 renderNode={this.renderNode}  // renderNode(node) return react element
/>

Upvotes: 2

Related Questions