Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How make a nested or "tree" table/list in AngularJS

I'm new to AngularJS (and web development) but quite excited about the two-way binding and ng-repeat possibilities.

I would like to build a table like structure of textfields where i can add more fields to a column and then it adds fields to the columns at the right. Wish to use it to build a nested JSON file.

enter image description here

Currently thinking of an json structure like this, but would like to have a more flat structure instead...

{
  "NoClicks": 
    { "C1": ["R1"],
      "C2": ["R1"],
      "C3": ["R1"]
    },
  "C1_R1_clicked":
    { "C1": ["R1", "R2"],
      "C2": ["R1", "R2"],
      "C3": ["R1", "R2"]
    },
  "C2_R1_clicked":
    { "C1": ["R1"],
      "C2": ["R1", "R2"],
      "C3": ["R1", "R2"]
    }
    ,
  "C3_R1_clicked":
    { "C1": ["R1"],
      "C2": ["R1"],
      "C3": ["R1", "R2"]
    }
}

Update

I have tried to answer my own question and are getting very close to the target..

But I would be thankful for any answer (or mod of my answer) that lets me archive the goal. This will of course marked as the solution to the question.

like image 793
Norfeldt Avatar asked Oct 31 '22 06:10

Norfeldt


1 Answers

Combinding this stackoverflow question Display nested list like a table with AngryCat's Amazing JSFiddle of nested nodes seems to get me half of the way

Becomes this: JSFiddle

HTML

<script type="text/ng-template" id="my-tmpl">
  {{data.name}}
  <button class="btn" ng-click="add(data)" ng-show="levelLimit(data)">
    Add node </button>

  <button class="btn" ng-click="delete(data)" ng-show="hasNodes(data)">
    Delete nodes </button>

  <ul>
    <li ng-repeat="data in data.nodes" ng-include="'my-tmpl'"></li>
  </ul>
</script>

<ul ng-controller="TreeController">
  <li ng-repeat="data in tree" ng-include="'my-tmpl'"></li>
</ul>

JS

    angular.module("myApp", [])
  .controller("TreeController", function($scope) {
    var levelLimit = function(data) {
      if (data.level < 3) {
        return true;
      } else {
        return false;
      };
    };

    var addNode = function(data) {
      var post = data.nodes.length + 1;
      var newName = data.name + '-' + post;
      var newLevel = data.level + 1;
      if (levelLimit(data)) {
        var node = {
          name: newName,
          nodes: [],
          level: newLevel
        };
        data.nodes.push(node);
        addNode(node);
      }
    };

    $scope.tree = [{
      name: "Node",
      nodes: [],
      level: 1
    }];

    $scope.hasNodes = function(data) {
      return (data.nodes.length > 0)
    };

    $scope.levelLimit = levelLimit;

    $scope.delete = function(data) {
      data.nodes = [];
    };

    $scope.add = addNode;
  });

CSS

li {
  display: inline-flex;
  border: 1px solid #000;
  padding: 0px;
  list-style: none;
}
li li {
  display:flex;
}

I just need to figure out 3 parts

  1. Call the add() first time it loads
  2. Move the add and delete buttons to the right (but still having the same function)
  3. Be able to add major rows.. Or somehow get the first list level to be a header...?
like image 168
Norfeldt Avatar answered Nov 14 '22 04:11

Norfeldt