3

I have an object that looks like this:

{
    "10": {},
    "12": {
        "20": {
            "value": 1,
            "id": 1,
        },
        "100": {
            "value": 12,
            "id": 1,
        }
    },
    "14": {
        "100": {
            "value": 14,
            "id": 2,
        }
    },
    "16": {},
    "18": {},
    "20": {
        "100": {
            "value": 23,
            "id": 1,
        },
        "150": {
            "value": 56,
            "id": 3,
        }
    },
    "22": {},
    "24": {},
    "26": {
        "50": {
...

I want to create a table based on this object that should be like this:

enter image description here

I am not sure how to create this table though, by using the correct combination of repeats. I am currently trying at this:

<table>
    <thead>
        <tr>
            <th>type</th>
            <th>module</th>
            <th>value</th>
            <th>id</th>
        </tr>
    </thead>
    <tbody>

        <tr ng-repeat-start="(row1, value1) in TestData">
            <td rowspan="{{value1.length}}">{{row1}}</td>
            <td ng-repeat="(label2, value2) in value1">{{label2}}</td>
        </tr>
    </tbody>
</table>
dearn44
  • 3,198
  • 4
  • 30
  • 63

1 Answers1

1

At first sight, you could do something like that by inserting a <tbody> (more information here: Angular.js ng-repeat across multiple tr's)

var myAppModule = angular.module('myApp', []).controller('MyController', MyController);

function MyController() {

  // https://stackoverflow.com/questions/1345939/how-do-i-count-a-javascript-objects-attributes
  this.objectCount = function(obj) {
    return Object.keys(obj).length;
  }

  this.data = {
    "10": {},
    "12": {
      "20": {
        "value": 1,
        "id": 1,
      },
      "100": {
        "value": 12,
        "id": 1,
      },
      "200": {
        "value": 120,
        "id": 10,
      }
    },
    "14": {
      "100": {
        "value": 14,
        "id": 2,
      }
    },
    "16": {},
    "18": {},
    "20": {
      "100": {
        "value": 23,
        "id": 1,
      },
      "150": {
        "value": 56,
        "id": 3,
      }
    },
    "22": {},
    "24": {}
  };

}
table,
th,
td {
  border: 1px solid black;
}
table {
  border-collapse: collapse;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>

<div ng-app="myApp" ng-controller="MyController as ctrl">
  <table>
    <thead>
      <tr>
        <th>type</th>
        <th>module</th>
        <th>value</th>
        <th>id</th>
      </tr>
    </thead>
    <tbody ng-repeat="(row1, value1) in ctrl.data" ng-switch="ctrl.objectCount(value1) === 0">
      <tr ng-switch-when="true">
        <td>{{row1}}</td>
        <td colspan="3"></td>
      </tr>
      <tr ng-switch-when="false" ng-repeat="(row2, value2) in value1">
        <td ng-if="$index === 0" rowspan="{{ctrl.objectCount(value1)}}">
          {{row1}}
        </td>
        <td>{{row2}}</td>
        <td>{{value2.value}}</td>
        <td>{{value2.id}}</td>
      </tr>
    </tbody>
  </table>
</div>

If you need something more refined with merging of rows and columns, you should think to build a more oriented view objects, so that the template is simpler, and your business logic is in JavaScript.

Community
  • 1
  • 1
Cyril Gandon
  • 16,830
  • 14
  • 78
  • 122
  • Hi Cyril, thanks for the input. I actually need the table to roughly be as I posted it, with the nested rows. I can change the data however I want within reasonable limits, but still I havent been able to achieve what I want. – dearn44 Jan 04 '16 at 14:33
  • So, this is only the 12 and 20 repeated which are the problem? – Cyril Gandon Jan 04 '16 at 14:37
  • Not exactly, that is the reason why I am using ngRepeat. Each original object, for example object 12, can have up to 6 modes, and there is no way for me to know until I get it. – dearn44 Jan 04 '16 at 14:39
  • I have updated the code, 12 has now 3 modes and it is printed nicely – Cyril Gandon Jan 04 '16 at 14:44