HTML Table dynamically generate columns using ng-repeat

0

Can you please help me generating HTML Table by using the JSON data with Angular ng-repeat.

Demo

JSON Data

{
  "account": {
    "accountId": "54545",
    "premise": {
      "address": {
        "address1": "1800 Bishop Gate Boulevard",
        "address2": "Apartment 129",
        "city": "Mount Laurel",
        "province": "NJ",
        "postalCode": "08054",
        "country": "US",
        "direction": null,
        "externalReference": null,
        "verified": false
      },
      "timeZone": "US_EASTERN",
      "locale": "EN",
      "camera": [
        {
          "id": "175277.2",
          "name": "camera1",
          "macAddress": "00:0E:8F:5B:AB:88",
          "manufacturer": "gabreal",
          "model": "iCamera",
          "serialNumber": "000E8F5BAB88",
          "firmwareVersion": "3.0.01.07",
          "hardwareVersion": null
        },
        {
          "id": "175277.3",
          "name": "camera2",
          "macAddress": "D4:21:22:D9:D0:73",
          "manufacturer": "gabreal",
          "model": "iCamera2-C",
          "serialNumber": "D42122D9D073",
          "firmwareVersion": "3.0.02.39",
          "hardwareVersion": null
        },
        {
          "id": "175277.1",
          "name": "camera3",
          "macAddress": "00:0E:8F:95:A8:A6",
          "manufacturer": "gabreal",
          "model": "SerComm_Camera_8021",
          "serialNumber": "000E8F95A8A6",
          "firmwareVersion": "1.0.24",
          "hardwareVersion": null
        }
      ],
      "thermostat": [
        {
          "id": "0024460000084172.10",
          "name": "Thermostat1",
          "type": "THERMOSTAT",
          "manufacturer": "RTCOA",
          "serialNumber": null,
          "firmwareVersion": "0x00000587",
          "hardwareVersion": "192",
          "model": "CT30S"
        },
        {
          "id": "000d6f0003ec6669.1",
          "name": "Thermostat2",
          "type": "THERMOSTAT",
          "manufacturer": "CentraLite Systems",
          "serialNumber": null,
          "firmwareVersion": "0x1418468c",
          "hardwareVersion": "2",
          "model": "3156105"
        }
      ],
      "zone": [
        {
          "id": 1,
          "name": "one",
          "type": "DOOR",
          "functionType": "ENTRY_EXIT",
          "sensor": [
            {
              "id": 1,
              "type": "DRY_CONTACT",
              "sourceType": "ZIGBEE",
              "serialNumber": "000d6f00030cdbcf.1",
              "model": "MCT-320 SMA",
              "manufacturer": "Visonic",
              "firmwareVersion": "0x00040008",
              "hardwareVersion": "1"
            }
          ]
        },
        {
          "id": 2,
          "name": "Motion",
          "type": "MOTION",
          "functionType": "INTERIOR_FOLLOWER",
          "sensor": [
            {
              "id": 2,
              "type": "MOTION",
              "sourceType": "ZIGBEE",
              "serialNumber": "000d6f0004b2af93.1",
              "model": "NEXT K85 SMA",
              "manufacturer": "Visonic",
              "firmwareVersion": "0x0004000b",
              "hardwareVersion": "1"
            }
          ]
        }
      ],
      "cpe": {
        "cpeId": "9c972684b2ca",
        "name": null,
        "deploymentModel": "WIFI_CLIENT_PSK_2_MODE",
        "serialNumber": null,
        "manufacturer": "Technicolor",
        "model": "TCA203",
        "hardwareRev": "5",
        "passPhrase": "528233",
        "cellularProfileName": null,
        "imeiNumber": 359942045924230,
        "iccId": "89011703258034552401",
        "simCardPhoneNumber": null,
        "simCardAccountNumber": null,
        "wifiMacAddress": "70:25:59:79:E2:EE",
        "firmwareVersion": "7_3_8_050000_201611152386",
        "widget": [
          {
            "name": "com.wsi.android.Gabreal",
            "version": "1.2"
          },
          {
            "name": "com.icontrol.apps.clock",
            "version": "1.0.0.0.3"
          }
        ],
        "module": []
      },
      "premiseId": null
    },
    "source": "INTERNAL"
  }
}

The table I want to generate as below

<table>
  <tr>
    <th>Property<br></th>
    <th>camera</th>
    <th>camera</th>
    <th>camera</th>
    <th>thermostat</th>
    <th>thermostat</th>
    <th>sensor</th>
    <th>sensor</th>
  </tr>
  <tr>
    <td>id</td>
    <td>175277.2</td>
    <td>175277.3</td>
    <td>175277.1</td>
    <td>0024460000084172.10</td>
    <td>000d6f0003ec6669.1</td>
    <td>1</td>
    <td>2</td>
  </tr>
  <tr>
    <td>name</td>
    <td>camera1</td>
    <td>camera2</td>
    <td>camera3</td>
    <td>Thermostat1</td>
    <td>Thermostat2</td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td>macAddress</td>
    <td>00:0E:8F:5B:AB:88</td>
    <td>D4:21:22:D9:D0:73</td>
    <td>00:0E:8F:95:A8:A6</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td>manufacturer</td>
    <td>gabreal</td>
    <td>gabreal</td>
    <td>gabreal</td>
    <td>RTCOA</td>
    <td>CentraLite Systems</td>
    <td>Visonic</td>
    <td>Visonic</td>
  </tr>
</table>

Note : Aruna has answered the question, but it fails when there different type JSON Object like zone object is different from others.

javascript
html
angularjs
angularjs-ng-repeat
html-table
asked on Stack Overflow Nov 29, 2016 by Ron • edited Dec 1, 2016 by Ron

1 Answer

3

This is a generic solution with the object and the properties.

Updated as per the json change on the Bounty request.

var app = angular.module('studentApp', []);

app.controller('StudentCntrl', function($scope,$http) {
    //$http.get('data.json').then(function (response){
	              //console.log(response.data.pages);
                //$scope.deviceInfo = response.data.account.premise;
        //});
  
var responseData = {
  "account": {
    "accountId": "54545",
    "premise": {
      "address": {
        "address1": "1800 Bishop Gate Boulevard",
        "address2": "Apartment 129",
        "city": "Mount Laurel",
        "province": "NJ",
        "postalCode": "08054",
        "country": "US",
        "direction": null,
        "externalReference": null,
        "verified": false
      },
      "timeZone": "US_EASTERN",
      "locale": "EN",
      "camera": [
        {
          "id": "175277.2",
          "name": "camera1",
          "macAddress": "00:0E:8F:5B:AB:88",
          "manufacturer": "gabreal",
          "model": "iCamera",
          "serialNumber": "000E8F5BAB88",
          "firmwareVersion": "3.0.01.07",
          "hardwareVersion": null
        },
        {
          "id": "175277.3",
          "name": "camera2",
          "macAddress": "D4:21:22:D9:D0:73",
          "manufacturer": "gabreal",
          "model": "iCamera2-C",
          "serialNumber": "D42122D9D073",
          "firmwareVersion": "3.0.02.39",
          "hardwareVersion": null
        },
        {
          "id": "175277.1",
          "name": "camera3",
          "macAddress": "00:0E:8F:95:A8:A6",
          "manufacturer": "gabreal",
          "model": "SerComm_Camera_8021",
          "serialNumber": "000E8F95A8A6",
          "firmwareVersion": "1.0.24",
          "hardwareVersion": null
        }
      ],
      "thermostat": [
        {
          "id": "0024460000084172.10",
          "name": "Thermostat1",
          "type": "THERMOSTAT",
          "manufacturer": "RTCOA",
          "serialNumber": null,
          "firmwareVersion": "0x00000587",
          "hardwareVersion": "192",
          "model": "CT30S"
        },
        {
          "id": "000d6f0003ec6669.1",
          "name": "Thermostat2",
          "type": "THERMOSTAT",
          "manufacturer": "CentraLite Systems",
          "serialNumber": null,
          "firmwareVersion": "0x1418468c",
          "hardwareVersion": "2",
          "model": "3156105"
        }
      ],
      "zone": [
        {
          "id": 1,
          "name": "one",
          "type": "DOOR",
          "functionType": "ENTRY_EXIT",
          "sensor": [
            {
              "id": 1,
              "type": "DRY_CONTACT",
              "sourceType": "ZIGBEE",
              "serialNumber": "000d6f00030cdbcf.1",
              "model": "MCT-320 SMA",
              "manufacturer": "Visonic",
              "firmwareVersion": "0x00040008",
              "hardwareVersion": "1"
            }
          ]
        },
        {
          "id": 2,
          "name": "Motion",
          "type": "MOTION",
          "functionType": "INTERIOR_FOLLOWER",
          "sensor": [
            {
              "id": 2,
              "type": "MOTION",
              "sourceType": "ZIGBEE",
              "serialNumber": "000d6f0004b2af93.1",
              "model": "NEXT K85 SMA",
              "manufacturer": "Visonic",
              "firmwareVersion": "0x0004000b",
              "hardwareVersion": "1"
            }
          ]
        }
      ],
      "cpe": {
        "cpeId": "9c972684b2ca",
        "name": null,
        "deploymentModel": "WIFI_CLIENT_PSK_2_MODE",
        "serialNumber": null,
        "manufacturer": "Technicolor",
        "model": "TCA203",
        "hardwareRev": "5",
        "passPhrase": "528233",
        "cellularProfileName": null,
        "imeiNumber": 359942045924230,
        "iccId": "89011703258034552401",
        "simCardPhoneNumber": null,
        "simCardAccountNumber": null,
        "wifiMacAddress": "70:25:59:79:E2:EE",
        "firmwareVersion": "7_3_8_050000_201611152386",
        "widget": [
          {
            "name": "com.wsi.android.Gabreal",
            "version": "1.2"
          },
          {
            "name": "com.icontrol.apps.clock",
            "version": "1.0.0.0.3"
          }
        ],
        "module": []
      },
      "premiseId": null
    },
    "source": "INTERNAL"
  }
};
  
var headerProperty = $scope.headerProperty = 'deviceType';
  
rebuildDeviceInfo(responseData);
  
function rebuildDeviceInfo(data) {
  var deviceInfoData = responseData.account.premise;
  var deviceInfo = [], deviceProperties = [];
  
  // Parse devices
  angular.forEach(deviceInfoData, function(devices, deviceKey) {
    if(angular.isArray(devices)) {
       deviceInfo = deviceInfo.concat(parseDevices(devices, deviceKey));
    }
  });
  
  // Parse device properties
  for(var i = 0; i < deviceInfo.length; i++) {
    var device = deviceInfo[i];
    angular.forEach(device, function(value, deviceProperty) {
      if(deviceProperties.indexOf(deviceProperty) === -1) {
        deviceProperties.push(deviceProperty);
      }
    });
  }
  
  $scope.deviceInfo = deviceInfo;
  $scope.deviceProperties = deviceProperties;
}
  
function parseDevices(dataArray, dataKey) {
     var deviceInfo = [];
     if(angular.isArray(dataArray)) {
       for(var i = 0; i < dataArray.length; i++) {
         var data = dataArray[i];
         if(data.hasOwnProperty('manufacturer') || data.hasOwnProperty('model')) {
           data[headerProperty] = dataKey;
           deviceInfo.push(data);
         } else {
            angular.forEach(data, function(devices, deviceKey) {
              if(angular.isArray(devices)) {
                 deviceInfo = deviceInfo.concat(parseDevices(devices, deviceKey));
              }
            });
         }
       }
     }
    
     return deviceInfo;
}
  
});
<!DOCTYPE html>
<html ng-app="studentApp">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
  <script  src="https://code.angularjs.org/1.4.7/angular.js"></script>
</head>

<body ng-controller="StudentCntrl">

 
    <div class="table-responsive">
        <table class="table table-striped">
          <thead>
            <tr>
              <th>Property</th>
              <th ng-repeat="device in deviceInfo track by $index">{{device[headerProperty]}}</th>
            </tr>
          </thead>
          <tbody>
             <tr ng-repeat="prop in deviceProperties track by $index" ng-if="prop != headerProperty">
                <td>{{prop}}</td>
                <td ng-repeat="device in deviceInfo track by $index">{{device[prop]}}</td>
             </tr>
          </tbody>
        </table>
      </div>
</body>
</html>

answered on Stack Overflow Nov 29, 2016 by Aruna • edited Dec 1, 2016 by Aruna

User contributions licensed under CC BY-SA 3.0