Dixit
Dixit

Reputation: 1379

Dynamic table creation with ng-repeat in angularjs

I want to generate dynamic table with dynamic table header and row/columns according to json object comes from webapi.

enter image description here

Here are examples of json object which comes every time different.

[
  {"Country":"Australia","Toner Quantity":8},
  {"Country":"China","Toner Quantity":6},
  {"Country":"India","Toner Quantity":11},
  {"Country":"South Korea","Toner Quantity":1}
]

and some time it comes like

[
  {"CustomerName":"FORD","Australia":0,"China":2,"India":0,"South Korea":0},
  {"CustomerName":"ICICI PRUDENTIAL","Australia":0,"China":0,"India":5,"South Korea":0},
  {"CustomerName":"Kimberly Clark","Australia":0,"China":0,"India":0,"South Korea":1},
  {"CustomerName":"McDonalds","Australia":1,"China":0,"India":0,"South Korea":0},
  {"CustomerName":"Novartis","Australia":1,"China":0,"India":0,"South Korea":0},
  {"CustomerName":"Origin Energy","Australia":3,"China":0,"India":0,"South Korea":0}
]

So I have tried but not able to achieve dynamic table with headers and row/columns

my html code like

<table class="table striped">
  <thead>
    <tr role="row">
      <th ng-repeat="th in dataconfigureListData.previewData">{{th}}</th>
    </tr>
  </thead>
  <tbody>
    <tr role="row" data-ng-repeat="previewData in dataconfigureListData.previewData">
      <td> {{previewData.Country}}</td>
      <td> {{previewData['Total Toner Qty']}}</td>
    </tr>
  </tbody>
</table>

Upvotes: 4

Views: 26373

Answers (3)

lenilsondc
lenilsondc

Reputation: 9810

You can do this by using an ng-repeat inside another. And also, use the first line to render the headers.

Note on ngRepeat: For some reason, [email protected] previous versions sorted the keys alphabetically when using ng-repeat by key in object. A simple way to fix that is upgrading to angularjs@^1.4.0 which is where they fixed it.

Announce of this change by angular docs:

You need to be aware that the JavaScript specification does not define the order of keys returned for an object. (To mitigate this in Angular 1.3 the ngRepeat directive used to sort the keys alphabetically.)

Version 1.4 removed the alphabetic sorting. We now rely on the order returned by the browser when running for key in myObj. It seems that browsers generally follow the strategy of providing keys in the order in which they were defined, although there are exceptions when keys are deleted and reinstated. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete#Cross-browser_issues

Ref.: Iterating over object properties

The following snippet implements this solution.

angular.module('myApp', [])
  .controller('myController', function($scope) {
    $scope.myArray = [
      { "CustomerName": "FORD", "Australia": 0, "China": 2, "India": 0, "South Korea": 0 },
      { "CustomerName": "ICICI PRUDENTIAL", "Australia": 0, "China": 0, "India": 5, "South Korea": 0 },
      { "CustomerName": "Kimberly Clark", "Australia": 0, "China": 0, "India": 0, "South Korea": 1 },
      { "CustomerName": "McDonalds", "Australia": 1, "China": 0, "India": 0, "South Korea": 0 },
      { "CustomerName": "Novartis", "Australia": 1, "China": 0, "India": 0, "South Korea": 0 },
      { "CustomerName": "Origin Energy", "Australia": 3, "China": 0, "India": 0, "South Korea": 0 }
    ];
  });

angular.element(document).ready(function() {
  angular.bootstrap(document, ['myApp']);
});
table {
  border-collapse: collapse;
}
td,
th {
  padding: 2px 4px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<table ng-controller="myController" border="1">
  <tr>
    <th ng-repeat="(key, val) in myArray[0]">{{ key }}</th>
  </tr>
  <tr ng-repeat="row in myArray">
    <td ng-repeat="column in row">
      {{ column }}
    </td>
  </tr>
</table>

The example bellow implements sorting columns dynamically by clicking on the column's header and also with reverse by clicking again on the selected column

angular.module('myApp', [])
  .controller('myController', function($scope) {
  
    $scope.sortByColumn = 'CustomerName';
    $scope.sortByReverse = false;
    $scope.sortBy = function(column) {
      if (column === $scope.sortByColumn) {
        $scope.sortByReverse = !$scope.sortByReverse;
      } else {
        $scope.sortByReverse = false;
      }

      $scope.sortByColumn = column;
    };
    
    $scope.getSortColumn = function () {
      // it has to be like this, otherwize, the `orderBy sortByColumn`
      // breaks for special names like "South Korea"
      return '"' + $scope.sortByColumn + '"';
    };
    
    $scope.myArray = [
      { "CustomerName": "FORD", "Australia": 0, "China": 2, "India": 0, "South Korea": 0 },
      { "CustomerName": "ICICI PRUDENTIAL", "Australia": 0, "China": 0, "India": 5, "South Korea": 0 },
      { "CustomerName": "Kimberly Clark", "Australia": 0, "China": 0, "India": 0, "South Korea": 1 },
      { "CustomerName": "McDonalds", "Australia": 1, "China": 0, "India": 0, "South Korea": 0 },
      { "CustomerName": "Novartis", "Australia": 1, "China": 0, "India": 0, "South Korea": 0 },
      { "CustomerName": "Origin Energy", "Australia": 3, "China": 0, "India": 0, "South Korea": 0 }
    ];
  });

angular.element(document).ready(function() {
  angular.bootstrap(document, ['myApp']);
});
table {
  border-collapse: collapse;
}

td,
th {
  padding: 2px 4px;
}

[ng-click] {
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<table ng-controller="myController" border="1">
  <tr>
    <th ng-repeat="(key, val) in myArray[0]" ng-click="sortBy(key)">
      {{ key }}
      <span ng-if="sortByColumn === key">{{ sortByReverse ? '▲' : '▼' }}</span>
    </th>
  </tr>
  <tr ng-repeat="row in myArray | orderBy : getSortColumn() : sortByReverse">
    <td ng-repeat="column in row">
      {{ column }}
    </td>
  </tr>
</table>

Upvotes: 8

sh6210
sh6210

Reputation: 4540

i'm using angular 1.6

 dynamic table header and according values.

Here marked columns are dynamic as well as its values. My table structures are below.

<table class="table table-bordered table-hover">
    <thead>
        <tr>
           <th>Doctor</th>
           <th>Target</th>
           <th ng-repeat="brand in doctorTargets.brands">{|| brand.name ||}</th>
         </tr>
    </thead>
    <tbody>
        <tr ng-repeat="item in doctorTargets.doctorTargets">
           <td>{|| item.doctorName ||}</td>
           <td>{|| item.target ||}</td>
           <td ng-repeat="brand in item.brands">{||brand.target||</td>                                    
        </tr>
     </tbody>
</table>

Upvotes: -2

Mosh Feu
Mosh Feu

Reputation: 29317

The logic is to get the header by iterating on the first object props using Object.keys.

To get only the values from to the cells itself you can do ng-repeat with (key, value) in some_obj.

Here is a full example:

angular.module('app', []).
controller('ctrl', function($scope) {
  $scope.data1 = [
    {"Country":"Australia","Toner Quantity":8},
    {"Country":"China","Toner Quantity":6},
    {"Country":"India","Toner Quantity":11},
    {"Country":"South Korea","Toner Quantity":1}
  ];

  $scope.data2 = [
    {"CustomerName":"FORD","Australia":0,"China":2,"India":0,"South Korea":0},
    {"CustomerName":"ICICI PRUDENTIAL","Australia":0,"China":0,"India":5,"South Korea":0},
    {"CustomerName":"Kimberly Clark","Australia":0,"China":0,"India":0,"South Korea":1},
    {"CustomerName":"McDonalds","Australia":1,"China":0,"India":0,"South Korea":0},
    {"CustomerName":"Novartis","Australia":1,"China":0,"India":0,"South Korea":0},
    {"CustomerName":"Origin Energy","Australia":3,"China":0,"India":0,"South Korea":0}
  ];

  $scope.getHeaders = function(arr) {
    return Object.keys(arr[0]);
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <table>
    <tr>
      <td ng-repeat="header in getHeaders(data1)">{{header}}</td>
    </tr>
    <tr ng-repeat="row in data1">
      <td ng-repeat="(key, value) in row">{{value}}</td>
    </tr>
  </table>
  <hr />
  <table>
    <tr>
      <td ng-repeat="header in getHeaders(data2)">{{header}}</td>
    </tr>
    <tr ng-repeat="row in data2">
      <td ng-repeat="(key, value) in row">{{value}}</td>
    </tr>
  </table>
</div>

Upvotes: 0

Related Questions