5

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.

3

3 Answers 3

2

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...?
Sign up to request clarification or add additional context in comments.

3 Comments

Re 1. add ng-init="add(data)" to the TreeController list, so you have <li ng-repeat="data in tree" ng-include="'my-tmpl'" ng-init="add(data)"></li>
When you say move the buttons to the right, what do you mean? To the right of the input boxes or to the far right of the page so that the buttons arent next to the nodes that they affect?
The buttons arent next the node that they affect.
0

Since the columns are saved as object properties you need to apply the following syntax for the first ng-repeat:

<div ng-repeat="(key, value) in myObj"> ... </div>

The valuevariable will contain your column array. You can iterate through the array with the deault syntax.

1 Comment

<tr ng-repeat="(C, R_array) in data.C2_R1_clicked"> <td ng-repeat="R in R_array"> {{R}} </td> </tr> - that doesn't seem to work..
0

Hmm I'm a lil' confused about the setup, but it sounds as though you would want something functioning as a recursive directive ? So perhaps:

app.directive('jsonObjectView',[function(){
  return {
    restrict: 'E',
    scope: {
      jsonObjectView: '=' // two-way bind about the directive's name
    },
    template: '<div ng-repeat="(property,object) in JSONObjects"><div class="object-container"><json-object-view="object"></json-object-view><button ng-click="addProperty(object)"></button></div></div>', // the html template
    compile: function (element,attributes){
      // craft your "addProperty" function (not sure if you want a pop-up or how you're going about it)
      return {
        post: function postLink(scope,elem,attr,ctrl){
          // Anything else you ought to do
        }
      };
    }
  };
}])
<json-object-view="object"></json-object-view>

<!-- Which would equate to: -->

<div ng-repeat="(property,object) in JSONObjects">
  <div class="object-container">
    <json-object-view="object"></json-object-view>
    <button ng-click="addProperty(object)"></button>
  </div>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.