Angular ng-repeat not rendering data correctly - javascript

I was trying to make a table from json structure but not getting it to render properly.
Output is not shown properly for the first two cells; Partial is empty and it is filling the only last one. Please refer below image
controller.js
.controller('wController', function($scope, $http) {
console.log('i m in ctrl 3');
$http({
method: "GET",
url: "http://custom.url.ch:3021/routepath",
headers: {
'Authorization': 'Basic Ydaeq2FwaQw1='
}
// headers : {"Authorization": "Basic " + auth}
}).then(function(response) {
console.log("yoyo", JSON.stringify(response));
$scope.data = response.data;
}, function(response) {
console.log("oaapop" + JSON.stringify(response));
});
});
// index.html
<div class="table-responsive" ng-controller="woController">
<table class="table table-condensed" border="1">
<thead>
<tr>
<th>Sites</th>
<th ng-repeat="worstData in data">
<center>{{$index+1}}</center>
</th>
<!-- <th><center>2</center></th> -->
<!-- <th><center>3</center></th> -->
<!-- <th><center>4</center></th> -->
<!-- <th><center>5</center></th> -->
</tr>
</thead>
<!-- <tbody> -->
<tbody>
<tr>
<td> PartialSite</td>
<td ng-repeat="worstData in data">{{$index}} {{[worstData[0][$index].PartialSite]}}</td>
</tr>
<tr>
<td>FailSite</td>
<td> </td>
<td></td>
<td> </td>
</tr>
<tr>
<td> Jobs mn</td>
<td> </td>
<td></td>
<td> </td>
</tr>
<tr>
<td>Largest Points</td>
<td> </td>
<td></td>
<td> </td>
</tr>
</tbody>
</table>
</div>
// JSON structure to make table structure
{
"data": {
"statusCode": 200,
"message": "Getting Data",
"data": [
[{
"PartialSite": "LRS",
"Partial": 2
}, {
"PartialSite": "Sooking",
"Partial": 1
}, {
"PartialSite": "Late",
"Partial": 1
}],
[{
"FailSite": "Sotelia",
"fail": 2
}, {
"FailSite": "Pccor",
"fail": 1
}, {
"FailSite": "PccroHotels",
"fail": 0
}],
[{
"ExecSite": "Sotelia",
"time": 240
}, {
"ExecSite": "Late",
"time": 240
}, {
"ExecSite": "Pccor",
"time": 120
}],
[{
"DataSite": "LRS",
"totalDP": 16
}, {
"DataSite": "Sooking",
"totalDP": 14
}, {
"DataSite": "Pccor",
"totalDP": 12
}]
]
},
"status": 200,
"config": {
"method": "GET",
"transformRequest": [null],
"transformResponse": [null],
"url": "http://custom.url.ch:3021/routepath",
"headers": {
"Authorization": "Basic Ydaeq2FwaQw1=",
"Accept": "application/json, text/plain, */*"
}
},
"statusText": "OK"
}

Is this what you are looking for - https://plnkr.co/edit/aMYrwNPHCkGnxftZgke4?p=preview
<body data-ng-controller="sampleCtrl as ctrl">
<table class="table table-condensed" border ="1" >
<thead >
<tr>
<th>Sites</th>
<th ng-repeat="worstData in ctrl.data"><center>{{$index+1}}</center></th>
<!-- <th><center>2</center></th> -->
<!-- <th><center>3</center></th> -->
<!-- <th><center>4</center></th> -->
<!-- <th><center>5</center></th> -->
</tr>
</thead>
<!-- <tbody> -->
<tbody >
<tr >
<td > PartialSite</td>
<td ng-repeat="worstData in ctrl.data[0]">{{$index}} {{worstData.PartialSite}}</td>
</tr>
<tr>
<td>FailSite</td>
<td ng-repeat="worstData in ctrl.data[1]">{{$index}} {{worstData.FailSite}}</td>
</tr>
<tr>
<td> Jobs mn</td>
<td ng-repeat="worstData in ctrl.data[2]">{{$index}} {{worstData.time}}</td>
</tr>
<tr>
<td>Largest Points</td>
<td ng-repeat="worstData in ctrl.data[3]">{{$index}} {{worstData.totalDP}}</td>
</tr>
</tbody>
</table>
</body>

Answer is already got by some contributor named #Developer. I am just sharing the right code with you to fix this type of problem.
//index.html
<table class="table table-condensed" border ="1" >
<thead >
<tr>
<th>Sites</th>
<th ng-repeat="worstData in getHeaders(data[0].length) track by $index"><center>{{$index+1}}</center></th>
<!-- <th><center>2</center></th> -->
<!-- <th><center>3</center></th> -->
<!-- <th><center>4</center></th> -->
<!-- <th><center>5</center></th> -->
</tr>
</thead>
<!-- <tbody> -->
<tbody >
<tr >
<td > PartialSite</td>
<td ng-repeat="worstData in data[0]">{{$index}} {{worstData.PartialSite}}</td>
</tr>
<tr>
<td>FailSite</td>
<td ng-repeat="worstData in data[1]">{{$index}} {{worstData.FailSite}}</td>
</tr>
<tr>
<td> Jobs mn</td>
<td ng-repeat="worstData in data[2]">{{$index}} {{worstData.time}}</td>
</tr>
<tr>
<td>Largest Points</td>
<td ng-repeat="worstData in data[3]">{{$index}} {{worstData.totalDP}}</td>
</tr>
</tbody>
</table>
//script.js
angular.module("app", [])
.controller("sampleCtrl", function($scope) {
//var _this = this;
$scope.data = [
[{
"PartialSite": "LRS",
"Partial": 2
}, {
"PartialSite": "Sooking",
"Partial": 1
}, {
"PartialSite": "Late",
"Partial": 1
}],
[{
"FailSite": "Sotelia",
"fail": 2
}, {
"FailSite": "Pccor",
"fail": 1
}, {
"FailSite": "PccroHotels",
"fail": 0
}],
[{
"ExecSite": "Sotelia",
"time": 240
}, {
"ExecSite": "Late",
"time": 240
}, {
"ExecSite": "Pccor",
"time": 120
}],
[{
"DataSite": "LRS",
"totalDP": 16
}, {
"DataSite": "Sooking",
"totalDP": 14
}, {
"DataSite": "Pccor",
"totalDP": 12
}]
];
$scope.getHeaders = function(index) {
return new Array(index);
};
});

Related

Previous, Next and Back functionality using angular 8, typescript

I have implemented a custom Previous, Next functionality using angular 8. What this functionality does is, when i click on previous then it shows the results based matching the url routing. As i am getting the data from back end in the below format.
[
{
"id": "8a80800e6bd1733c016bd1b2c29b3f73",
"suggestionId": "tBAKv6Dh",
"projectId": "8a80800e6bd1733c016bd1b165d63d91",
"category": "Unsecured",
"severity": "Major",
"status": "NEW",
"issues": [
{
"autoSuggestionId": null,
"issueId": "NiEQOTRlELcsXFbDSQjm",
"jobId": "8a8080966bda207d016bda614f5d2a48",
"status": "open",
"runId": null,
"jobName": "Dev",
"envName": "Master"
}
],
},
{
"id": "8a80800e6bd1733c016bd1b2cb8e4018",
"suggestionId": "tBAKv6Dh",
"projectId": "8a80800e6bd1733c016bd1b165d63d91",
"category": "Unsecured",
"severity": "Major",
"status": "NEW",
"issues": [
{
"autoSuggestionId": null,
"issueId": "NiEQOTRlELcsXFbDSQjm",
"jobId": "8a8080966bda207d016bda614f5d2a48",
"status": "open",
"runId": null,
"jobName": "Dev",
"envName": "Master"
}
],
},
{
"id": "8a80800e6bd1733c016bd1b2cc844024",
"suggestionId": "tBAKv6Dh",
"projectId": "8a80800e6bd1733c016bd1b165d63d91",
"category": "Unsecured",
"severity": "Major",
"status": "NEW",
"issues": [
{
"autoSuggestionId": null,
"issueId": "NiEQOTRlELcsXFbDSQjm",
"jobId": "8a8080966bda207d016bda614f5d2a48",
"status": "open",
"runId": null,
"jobName": "Dev",
"envName": "Master"
}
],
}
]
For this see the below code:
Template Code
<button mat-raised-button class="float-right" (click)="nextVulnerability()">
Next<i class="material-icons">keyboard_arrow_right</i></button>
<button mat-raised-button class="float-right" (click)="previousVulnerability()">
<i class="material-icons">keyboard_arrow_left</i>Previous</button>
<table class="table">
<tbody>
<tr>
<th>Risk:</th>
<td>{{vulnerabilityDetails?.categoryName}}</td>
</tr>
<tr>
<th>API Endpoint:</th>
<td>{{vulnerabilityDetails?.method}}:{{vulnerabilityDetails?.endPoint}}</td>
</tr>
<tr>
<th>Auth:</th>
<td>{{vulnerabilityDetails?.auth}}</td>
</tr>
<tr>
<th>Severity:</th>
<td>
<span *ngIf="vulnerabilityDetails.severity == 'Critical'" class="text-danger"><i
class="fa fa-exclamation-circle"></i>
{{vulnerabilityDetails.severity}}</span>
<span *ngIf="vulnerabilityDetails.severity == 'Major'" class="text-danger"><i class="fa fa-warning"
aria-hidden="true"></i> {{vulnerabilityDetails.severity}}</span>
<span *ngIf="vulnerabilityDetails.severity == 'Minor'" class="text-warning"><i
class="fa fa-angle-double-down" aria-hidden="true"></i> {{vulnerabilityDetails.severity}}</span>
<span *ngIf="vulnerabilityDetails.severity == 'trivial'" class="text-warning"><i
class="fa fa-arrow-down"></i>
{{element.severity}}</span>
</td>
</tr>
<tr>
<th>Status:</th>
<td>
<span *ngIf="vulnerabilityDetails.status == 'NEW'" class="text-danger">Open</span>
<span *ngIf="vulnerabilityDetails.status == 'CLOSED' || vulnerabilityDetails.status == 'SKIPPED'"
class="text-success">Closed</span>
</td>
</tr>
<tr>
<th>Vulnerability Description:</th>
<td>{{vulnerabilityDetails?.issueDesc}}</td>
</tr>
<tr>
<th>Suggested Fix Time:</th>
<td>{{vulnerabilityDetails?.estimates}}</td>
</tr>
<tr>
<th>Discovered Date:</th>
<td>{{vulnerabilityDetails?.createdDate | timeAgo}}</td>
</tr>
<tr>
<th>Resource:</th>
<td>{{vulnerabilityDetails?.resourceName}}</td>
</tr>
<tr>
<th>Playbook:</th>
<td> <a href="javascript:;" [routerLink]="['/app/projects', id, 'template',playbookName]">
{{vulnerabilityDetails?.testSuiteName}}
</a>
</td>
</tr>
<tr>
<th>Scan:</th>
<td>
<a href="javascript:;" [routerLink]="[scanHistoryURL]">
Recent Scan
</a>
</td>
</tr>
<tr>
<th>Status Code:</th>
<td>{{vulnerabilityDetails?.respStatusCode}}</td>
</tr>
<tr>
<th>Suggestions:</th>
<td>{{vulnerabilityDetails?.suggestion}}</td>
</tr>
<tr>
<th>Bug Bounty Program Savings:</th>
<td>{{vulnerabilityDetails?.bounty | currency:0}}</td>
</tr>
<tr>
<th>False Positive:</th>
<td>{{vulnerabilityDetails?.falsePositive}}</td>
</tr>
<tr>
<th>Issue Id:</th>
<td>{{vulnerabilityDetails?.issues[0]?.issueId}}</td>
</tr>
</tbody>
</table>
The below is the code of ts for handling previous and next functionality
nextVulnerability() {
this.getDetailsByVulId("next")
}
previousVulnerability() {
this.getDetailsByVulId("prev")
}
getDetailsByVulId(action: string) {
if(this._clockSubscription != null)
{
this._clockSubscription.unsubscribe();
}
this.handler.activateLoader();
this.projectService.getVulDetailsPrevNext(this.id, this.vulnerabilityId, action).subscribe(vulRes => {
this.handler.hideLoader();
if (this.handler.handle(vulRes)) {
return;
}
this.vulnerabilityResult = vulRes['data'];
console.log("this.runNumResult = ", this.vulnerabilityResult);
this.router.navigate(['/app/projects', this.projectId, 'recommendations', this.id, 'details']);
}, error => {
this.handler.hideLoader();
this.handler.error(error);
});
}
The service written from where i am getting data.
getVulDetailsPrevNext(id,autoSuggestionId,action: string){
return this.http.get(this.serviceUrl + "/" + id + "/auto-suggestion/"+autoSuggestionId + action);
}
Can anyone suggest me what i have done wrong. I am not able to understand. When i click on previous and next buttons then it gives the below errors like "invalid id" from the back end.

Json object through Ajax to Html Datatable

I have a PHP code that returns a JSON object which is actually an array of data , and i want to display the JSON content on a datatable but i have been getting this error :
DataTables warning: table id=example - Invalid JSON response
PHP , HTML and JS are below , any help is appreciated , thank you.
PHP :
<?php
include "../config.php";
$db = config::getConnexion();
$sql = "SELECT * FROM produits";
$req = $db->prepare($sql);
$req->execute();
$liste = $req->fetchAll();
//Convert Array to JSON Obj
$someJSON = json_encode($liste);
echo $someJSON;
//var_dump($someJSON);
?>
HTML :
<table id="example" class="table table-striped table-bordered" style="width:100%">
<thead>
<tr>
<th>nom</th>
<th>num</th>
<th>prix</th>
<th>qte</th>
<th>cat</th>
<th>desc</th>
</tr>
</thead>
<tbody>
<tr>
<tr>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
<td ></td>
</tr>
</tbody>
<tfoot>
<tr>
<th>nom</th>
<th>num</th>
<th>prix</th>
<th>qte</th>
<th>cat</th>
<th>desc</th>
</tr>
</tfoot>
</table>
Javascript :
<script type="text/javascript">
$(document).ready(function() {
$("#example").DataTable({
ajax: {
url: "TestAjax.php",
dataSrc: ""
},
columns: [
{ data: "nom" },
{ data: "num" },
{ data: "prix" },
{ data: "qte" },
{ data: "descr" },
{ data: "cat" }
],
iDisplayLength: 1,
iDisplayStart: 0
});
});;
</script>
JSON data :
[{"nom":"chaise1236","0":"chaise1236","num":"1231564658","1":"1231564658","prix":"800","2":"800","qte":"80","3":"80","descr":"description","4":"description","cat":"Interieur","5":"Interieur"},{"nom":"lilyouss","0":"lilyouss","num":"1231564672","1":"1231564672","prix":"5000","2":"5000","qte":"500","3":"500","descr":"youss","4":"youss","cat":"Exterieur","5":"Exterieur"},{"nom":"chaise125","0":"chaise125","num":"1231564660","1":"1231564660","prix":"500","2":"500","qte":"125","3":"125","descr":"descrchaise125","4":"descrchaise125","cat":"Exterieur","5":"Exterieur"},{"nom":"chaise3","0":"chaise3","num":"1231564661","1":"1231564661","prix":"125","2":"125","qte":"500","3":"500","descr":"descr3","4":"descr3","cat":"Interieur","5":"Interieur"},{"nom":"chaise5","0":"chaise5","num":"1231564662","1":"1231564662","prix":"1256","2":"1256","qte":"500","3":"500","descr":"descr55","4":"descr55","cat":"Exterieur","5":"Exterieur"},{"nom":"Fauteuil","0":"Fauteuil","num":"1231564663","1":"1231564663","prix":"550","2":"550","qte":"0","3":"0","descr":"Fauteuil Comfort","4":"Fauteuil Comfort","cat":"Interieur","5":"Interieur"},{"nom":"Fauteuil 2 Places","0":"Fauteuil 2 Places","num":"1231564664","1":"1231564664","prix":"2500","2":"2500","qte":"32","3":"32","descr":"faut Comfortable","4":"faut Comfortable","cat":"Interieur","5":"Interieur"},{"nom":"Tableau Artistique","0":"Tableau Artistique","num":"1231564665","1":"1231564665","prix":"5000","2":"5000","qte":"0","3":"0","descr":"tableau","4":"tableau","cat":"Interieur","5":"Interieur"},{"nom":"Table","0":"Table","num":"1231564667","1":"1231564667","prix":"230","2":"230","qte":"200","3":"200","descr":"Tbmx","4":"Tbmx","cat":"Interieur","5":"Interieur"},{"nom":"AspirateurAS","0":"AspirateurAS","num":"1231564668","1":"1231564668","prix":"125","2":"125","qte":"500","3":"500","descr":"Aspirateur Samsung","4":"Aspirateur Samsung","cat":"Interieur","5":"Interieur"},{"nom":"TableTs","0":"TableTs","num":"1231564669","1":"1231564669","prix":"500","2":"500","qte":"250","3":"250","descr":"Descr","4":"Descr","cat":"Interieur","5":"Interieur"},{"nom":"Prodtest","0":"Prodtest","num":"1231564671","1":"1231564671","prix":"500","2":"500","qte":"500","3":"500","descr":"description test","4":"description test","cat":"Interieur","5":"Interieur"}]

Adjust HTML table with content want to displayed, Angular

My page is about showing data table from user on shift indicator.
My dashboard.component.html
<table class="table">
<thead>
<tr>
<th *ngFor="let col of tablePresetColumns">
{{col.content}}
</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of tablePresetData ">
<td *ngFor="let cell of row"> {{cell.content}}</td>
<td *ngFor="let cell of row">
<span class ="dot" [ngClass]="{
'dot-yellow' : cell.content == 'Busy',
'dot-green' : cell.content == 'Idle',
'dot-red' : cell.content == 'Overload'}">
</span>
</td>
</tr>
</tbody>
</table>
My example data :
tablePresetColumns = [{ id: 1, content: "Username" }];
tablePresetData = [
[{ id: 1, content: "Adiet Adiet" }, { id: 2, content: "Idle" }],
[{ id: 1, content: "Andri Irawan" }, { id: 2, content: "Idle" }],
[{ id: 1, content: "Ari Prabudi" }, { id: 2, content: "Idle" }]
];
How should i do to :
removes the status in the page that I want to display, so it just
appear username and color indicator
I've tried to change *ngFor into this (with index 1) :
<td *ngFor="let cell of row"> {{cell.content[1]}}
but it didn't works at all
Try
<td> {{row[0].content}}</td>
instead of
<td *ngFor="let cell of row"> {{cell.content[1]}}
How about this
<table class="table">
<thead>
<tr>
<th *ngFor="let col of tablePresetColumns">{{col.content}}</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of tablePresetData">
<ng-container *ngFor="let cell of row, let i = index">
<td *ngIf="i == 0">{{cell.content}}</td>
<td *ngIf="i == 0">
<span
[ngClass]="{
'dot-yellow' : row[1].content == 'Busy',
'dot-green' : row[1].content == 'Idle',
'dot-red' : row[1].content == 'Overload'}"
>
</span>
</td>
</ng-container>
</tr>
</tbody>
</table>
See here for a live example: https://codesandbox.io/s/7y2r69992j
Note
I think your data structure is a but awkward and un-semantic. It would be better, if your data would look like this:
tablePresetColumns = ["Username", "Status"];
tablePresetData = [
{username: "Adiet Adiet", status: "Idle"},
{username: "Andri Irawan", status: "Busy" },
{username: "Ari Prabudi", status: "Overload" }
];
So you could show the table like this
<table class="table">
<thead>
<tr>
<th *ngFor="let col of tablePresetColumns">{{col}}</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of tablePresetData">
<td>{{ row.username }}</td>
<td>
<span [ngClass]="{
'dot-yellow' : row.status == 'Busy',
'dot-green' : row.status == 'Idle',
'dot-red' : row.status == 'Overload'
}">
</span>
</td>
</tr>
</tbody>
</table>
Much easier to read and maintain.
Also a live example: https://codesandbox.io/s/o27pv052z
You need to use .map on tablePresetData and have some changes on object structure
angular code here:
tablePresetColumns: any = [
{thTitle:"id", thWidth:'30px'},
{thTitle:"Username", thWidth:'160px'},
{thTitle:"Status", thWidth:'100px'},
{thTitle:"", thWidth:'60px'}
];
tablePresetData: any = [
{ id: 1, Username: "Adiet Adiet", status: "Idle" },
{ id: 2, Username: "Andri Irawan", status: "Overload" },
{ id: 3, Username: "Ari Prabudi", status: "Busy" }
];
constructor() {}
ngOnInit() {
this.tablePresetData.map((item: any) => {
if (item.status === "Busy") {
item["className"] = "dot-yellow";
}
if (item.status === "Idle") {
item["className"] = "dot-green";
}
if (item.status === "Overload") {
item["className"] = "dot-red";
}
});
console.log("this.tablePresetData", this.tablePresetData);
}
Html code
<table>
<thead>
<tr>
<th
*ngFor="let tableHd of tablePresetColumns"
[width]="tableHd.thWidth" >
{{tableHd.thTitle}}
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let tableCol of tablePresetData">
<td>{{tableCol.id}}</td>
<td>{{tableCol.Username}}</td>
<td>{{tableCol.status}}</td>
<td>
<span [ngClass]='tableCol.className' class="circle"></span>
</td>
</tr>
</tbody>
</table>
CSS Class -
.circle{border-radius: 10px; display: inline-block; height: 10px; width: 10px; }
.dot-yellow{background-color: yellow;}
.dot-green{background-color:green;}
.dot-red{background-color:red;}

Show button on one row table

I have table:
<table class="table table-condensed">
<thead>
<tr>
<th>id</th>
<th>task</th>
<th>date</th>
</tr>
</thead>
<tbody>
<tr v-for="row in tasks">
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"> {{row.id}}</td>
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"> {{row.text}}<button v-if="showBatton">Test</button></td>
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"> {{row.date_current}}</td>
<td span #mouseover="showButtonFunction" #mouseleave="hideButtonFunction"><button v-if="showBatton">Test</button></td>
</tr>
</tbody>
</table>
As intended, the button should appear on the line on which the mouse is hovering.
But now it appears on all visible lines.
Script:
data:{
showBatton:false,
},
showButtonFunction(){
// this.title="dsds2"
console.log("test")
this.showBatton=true;
},
hideButtonFunction(){
this.showBatton=false;
}
How to implement it?
You can do this with css only:
// CSS
tr button {
display: none;
}
tr:hover button {
display: inline-block;
}
// HTML
<tr v-for="row in tasks">
<td span>{{row.id}}</td>
<td span>{{row.text}}<button>Test</button></td>
<td span>{{row.date_current}}</td>
<td span><button>Test</button></td>
</tr>
You can do it Using VueJS Also Like:
<div id="app">
<table class="table table-condensed">
<thead>
<tr>
<th>id</th>
<th>task</th>
<th>date</th>
</tr>
</thead>
<tbody>
<tr v-for="row in tasks" #mouseover="showButtonFunction(row.id)" #mouseleave="hideButtonFunction" :key="row.id">
<td>{{row.id}}</td>
<td>{{row.text}}<button v-show="buttonIndex === row.id">Test</button></td>
<td>{{row.date_current}}</td>
<td><button v-show="buttonIndex === row.id">Test</button></td>
</tr>
</tbody>
</table>
</div>
JS Code:
var vue = new Vue({
el: '#app',
data:{
buttonIndex: false,
tasks: [
{
id: 1,
text: "Hello",
date_current: new Date()
},
{
id: 2,
text: "Hello2",
date_current: new Date()
},
{
id: 3,
text: "Hello3",
date_current: new Date()
}
]
},
methods:{
showButtonFunction(id){
// this.title="dsds2"
this.buttonIndex=id;
},
hideButtonFunction(){
this.buttonIndex=false;
}
}
})
Check this Link :)

How to hide table column if all json value is null for any property using angular js

Plunker sample
How to hide table column if all json value is null for any property
using angular js
index.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.isArray = angular.isArray;
$scope.data = [{
"Id": null,
"Title": "US",
"Description": "English - United States",
"Values": [{
"Id": 100,
"LanId": 1,
"KeyId": 59,
"Value": "Save"
}]
}, {
"Id": null,
"Title": "MX",
"Description": "test",
"Values": [{
"Id": 100,
"LanId": 1,
"KeyId": 59,
"Value": "Save"
}]
}, {
"Id": null,
"Title": "SE",
"Description": "Swedish - Sweden",
"Values": [{
"Id": 100,
"LanId": 1,
"KeyId": 59,
"Value": "Save"
}]
}]
$scope.cols = Object.keys($scope.data[0]);
$scope.notSorted = function(obj) {
if (!obj) {
return [];
}
return Object.keys(obj);
}
});
index.html
<table border=1 style="margin-top: 0px !important;">
<thead>
<tr>
<th ng-repeat="(k,v) in data[0]">{{k}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data">
<td ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)">
<table ng-if="isArr" border=1>
<thead>
<tr>
<td>
<button ng-click="expanded = !expanded" expand>
<span ng-bind="expanded ? '-' : '+'"></span>
</button>
</td>
</tr>
<tr>
<th ng-repeat="(sh, sv) in value[0]">{{sh}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="sub in value" ng-show="expanded">
<td ng-repeat="(sk, sv) in sub">{{sv}}</td>
</tr>
</tbody>
</table>
<span ng-if="!isArr">{{value}}</span>
</td>
</tr>
</tbody>
</table>
You can filter out columns that have only null values with:
JavaScript
$scope.cols = Object.keys($scope.data[0]).filter(function(col) {
return $scope.data.some(function(item) {
return item[col] !== null;
});
});
and check in template if this column should be rendered:
HTML
<table border=1 style="margin-top: 0px !important;">
<thead>
<tr>
<!-- Iterate over non-null columns -->
<th ng-repeat="col in cols">{{col}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data">
<!-- Use ngIf to hide redundant column -->
<td ng-if="cols.indexOf(prop)>=0" ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)" >
...
Plunker
http://plnkr.co/edit/PIbfvX6xvX5eUhYtRBWS?p=preview
So the id is null for every element in the array, then do
<th ng-repeat="(k,v) in data[0]" ng-show="v">{{k}}</th>
and
<td ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)" ng-show="value">
plnkr: http://plnkr.co/edit/rra778?p=preview
You need to make use of the cols property you defined in your $scope, but you also need to make sure its correct and responsive. You do that like this:
var colsFromData = function(data) {
var activeCols = {};
data.forEach(function(o) {
Object.keys(o).forEach(function(k) {
if(null == o[k])
return;
activeCols[k] = 1;
})
});
return Object.keys(activeCols);
}
$scope.cols = colsFromData($scope.data);
$scope.$watchCollection('data', colsFromData);
Then in your template, to use the now correct cols array:
...
<thead>
<tr>
<th ng-repeat="k in cols">{{k}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data">
<td ng-repeat="(prop, value) in item" ng-init="isArr = isArray(value)" ng-if="cols.indexOf(prop) >= 0">
...
And the updated plunker

Categories

Resources