how to create a nested grid in ngtable? - angularjs

I am trying to create a nested grid in my ngtable like this:
<table ng-table="tableParams" class="table">
<tr ng-repeat="user in $data">
<td data-title="'Name'">{{user.name}}</td>
<td data-title="'Age'">{{user.age}}</td>
<td data-title="'kids'">
<table ng-table="nestedtableParams" class="table">
<tr ng-repeat="nesteduser in $nesteddata">
<td data-title="'Name'">{{nesteduser.name}}</td>
<td data-title="'Age'">{{nesteduser.age}}</td>
</tr>
</table>
</td>
</tr>
</table>
question is: why is the nested data not displaying? here is a plunkr:
http://plnkr.co/edit/dKTtU89f7z6nQptgEZxN?p=preview

Got this working by adding the data to the $scope: (partial example code)
$scope.nesteddata = [{
name: "Kid Moroni",
age: 50
}, {
name: "Kid Tiancum",
age: 43
}, {
name: "Kid Jacob",
age: 27
}, {
name: "Kid Nephi",
age: 29
}, {
name: "Kid Enos",
age: 34
}];
And then, in the controller functions, refer to these $scope variables:
$scope.nestedtableParams = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: $scope.nesteddata.length, // length of data
getData: function($defer, params) {
$defer.resolve($scope.nesteddata.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
Finally in the markup I left out the $ prefix, since this data is now in the scope:
<table ng-table="tableParams" class="table">
<tr ng-repeat="user in data">
<td data-title="'Name'">{{user.name}}</td>
<td data-title="'Age'">{{user.age}}</td>
<td>
<table ng-table="nestedtableParams" class="table">
<tr ng-repeat="user in nesteddata">
<td data-title="'Name'">{{user.name}}</td>
<td data-title="'Age'">{{user.age}}</td>
</tr>
</table>
</td>
</tr>
</table>
Working Plunker (Although I doubt that it makes sense to nest grids like this)

Related

Angular 1.x - How to display table with dynamic rows and columns

Aim - Display a dynamic table for both rows and columns as below -
Dynamic Header - The fund codes are values for "name" from the json object array.
Dynamic rows with values for Application, Redemption and Net
JSON object :
[
{
name: 'VBIF',
application: 1000,
redemption: -200,
netAppRed: 800
},
{
name: 'VCIF',
application: 1500,
redemption: -200,
netAppRed: 800
},
{
name: 'VMPF',
application: 2000,
redemption: 0,
netAppRed: 2000
},
{
name: 'VBIF-A',
application: 800,
redemption: 100,
netAppRed: 700
},
{
name: 'VMPF-A',
application: 43540,
redemption: 12550,
netAppRed: 30990
}
]
HTML :
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Fund Code</th>
<th>Application</th>
<th>Redemption</th>
<th>Net Application Redemption</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="cashflow in cashflows">
<td>{{cashflow.name}}</td>
<td>{{cashflow.application | currency}}</td>
<td>{{cashflow.redemption | currency}}</td>
<td>{{cashflow.netAppRed | currency}}</td>
</tr>
</tbody>
</table>
</div>
Current view displays :
Another option without need to change model:
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Fund Code</th>
<th data-ng-repeat="cashflow in cashflows">{{cashflow.name}} </th>
</tr>
</thead>
<tbody>
<tr >
<td>Application</td>
<td data-ng-repeat="cashflow in cashflows">{{cashflow.application | currency}}</td>
</tr>
<tr >
<td>Redemption</td>
<td data-ng-repeat="cashflow in cashflows">{{cashflow.redemption | currency}}</td>
</tr>
<tr >
<td>NetAppRed</td>
<td data-ng-repeat="cashflow in cashflows">{{cashflow.netAppRed | currency}}</td>
</tr>
</tbody>
</table>
</div>
Resovled it by changing the model in the controller as below -
$scope.getHeaders = function (){
var keys = [];
angular.forEach(object, function (val, key) {
if(key !== '$$hashKey') { keys.push(key); }
});
return keys;
};
$scope.getValue = function () {
var values = [];
angular.forEach(object, function (val, key) {
if(key !== '$$hashKey') { values.push(val); }
});
return values;
};
The HTML updated as below -
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th></th>
<th ng-repeat="(header, value) in cashflows">
{{value.name}}
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Application</td>
<td ng-repeat="row in cashflows">
{{row.application}}
</td>
</tr>
<tr>
<td>Redemption</td>
<td ng-repeat="row in cashflows">
{{row.redemption}}
</td>
</tr>
<tr>
<td>Net App & Red</td>
<td ng-repeat="row in cashflows">
{{row.netAppRed}}
</td>
</tr>
</tbody>
</table>
</div>
Final Output :
you can use ng-tables to show your dynamic data
here is example
[https://www.tutlane.com/tutorial/angularjs/angularjs-tables-with-ng-table][1]
if any query ask me on comment

ngtable custom filter of $index instead of filtering from dataset

<table ng-table="demo.tableParams" class="table table-condensed table-bordered table-striped">
<tr ng-repeat="row in $data">
<td data-title="'Name'" filter="{name: 'text'}">{{$index}}</td>
<td data-title="'Age'" filter="{age: 'number'}">{{row.age}}</td>
<td data-title="'Money'">{{row.money}}</td>
<td data-title="'Country'" filter="{ country: 'select'}" filter-data="demo.countries">{{row.country}}</td>
</tr>
</table>
</div>
I have {{$index}} to print out the index number. I understand that i can filter easily using filter={age: 'number'} however i cannot do the same for $index as it is not part of the dataset from the JS.
I want to be able to filter $index via a input box instead of automatically filtering upon loading the page.
I don't think you can filter on $index. But you can simply extend you dataset before rendering the table.
Controller
$scope.data = [{
name: 'greg',
age:29,
money: 100.10
}, {
name: 'bob',
age:30,
money: 250.00
}];
for(var i = 0; i < $scope.data.length; i++) {
$scope.data[i].index = i;
}
$scope.table = new NgTableParams({ }, {
dataset: $scope.data
});
View:
<table ng-table="table" class="table table-condensed table-bordered table-striped">
<tr ng-repeat="row in $data">
<td data-title="'Index'" filter="{index: 'number'}">{{row.index}}</td>
<td data-title="'Name'" filter="{name: 'text'}">{{row.name}}</td>
<td data-title="'Age'" filter="{age: 'number'}">{{row.age}}</td>
<td data-title="'Money'" filter="{money: 'number'}">{{row.money}}</td>
</tr> </table>

Angular: ng-repeat displaying order in a table

I have an specific requirement where the json data comes like this:
[{Id : "a", Name : "John", age : 50},
{Id : "b", Name : "Bob", age : 40}]
I want to show it in a table using ng-repeat, but in a way where headers come in the first column, as below:
<table>
<tr>
<td>Id</td>
<td>a</td>
<td>b</td>
</tr>
<tr>
<td>Name</td>
<td>John</td>
<td>Bob</td>
</tr>
<tr>
<td>Age</td>
<td>50</td>
<td>40</td>
</tr>
</table>
Is there a way to achieve this using angularjs?
Thanks
Provided you have a controller:
angular.module('MyApp', [])
.controller('MyController', function($scope) {
$scope.data = [
{Id : "a", Name : "John", age : 50},
{Id : "b", Name : "Bob", age : 40}
];
});
Your markup would then be as follows. If the data isn't going to change after it is displayed:
<table>
<tr>
<td>Id</td>
<td ng-repeat="item in ::data">{{::item.Id}}</td>
</tr>
<tr>
<td>Name</td>
<td ng-repeat="item in ::data">{{::item.Name}}</td>
</tr>
<tr>
<td>Age</td>
<td ng-repeat="item in ::data">{{::item.age}}</td>
</tr>
</table>
If the data is going to change after it is displayed, and you want the view to update accordingly, then:
<table>
<tr>
<td>Id</td>
<td ng-repeat="item in data track by $index">{{item.Id}}</td>
</tr>
<tr>
<td>Name</td>
<td ng-repeat="item in data track by $index">{{item.Name}}</td>
</tr>
<tr>
<td>Age</td>
<td ng-repeat="item in data track by $index">{{item.age}}</td>
</tr>
</table>
You can convert your array in an object, then you can use nested ng-repeats in view, as below:
(function() {
"use strict";
angular.module('app', [])
.controller('mainCtrl', function($scope) {
var array = [
{
"Id":"a",
"Name":"John",
"age":50
},
{
"Id":"b",
"Name":"Bob",
"age":40
}
];
// If you're sure that the properties are always these:
$scope.mainObj = {
"Id": [],
"Name": [],
"age": []
};
// If you're unsure what are the properties:
/*
$scope.mainObj = {};
Object.keys(array[0]).forEach(function(value) {
$scope.mainObj[value] = [];
});
*/
// Iterates over its properties and fills the arrays
Object.keys($scope.mainObj).forEach(function(key) {
array.map(function(value) {
$scope.mainObj[key].push(value[key]);
})
});
});
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>
<body ng-controller="mainCtrl">
<table>
<tr ng-repeat="(key, values) in mainObj track by $index">
<td ng-bind="key"></td>
<td ng-repeat="value in values track by $index" ng-bind="value"></td>
</tr>
</table>
</body>
</html>
I hope it helps!

no pager using ngtable and angularjs

I have an ng-table in my project. My problem is that no pager displays. The table loads multiple rows and I paged from 10 to 10, I assign value 10 to count, but nothing happens.
This is my code:
$scope.tableParams = new ngTableParams({
page: 1,
count: 10,
filter: {
message: ''
},
sorting: {
asset: 'asc'
}
},
{
total: $scope.data.length,
counts: [],
getData: function ($defer, params) {
var orderedData = params.sorting() ?
$filter('orderBy')($scope.data, params.orderBy()) :
$scope.data;
params.total(orderedData.length);
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
<table ng-table="tableParams" class="table table-striped table-hover table-bordered">
<tr ng-repeat="ws in data | filter:search" style="text-align:center;">
<td data-title="'Tag Name'" sortable="'tagname'">{{ws.tagname}}</td>
<td data-title="'Description'" sortable="'tagname'">{{ws.tagdescription}}</td>
<td data-title="'Data Type'" sortable="'datatype'">{{ws.datatype}}</td>
<td data-title="'Tag Unit'" sortable="'tagdescription'">{{ws.tagunit}}</td>
<td data-title="'Birth Date'" sortable="'birthdate'">{{ws.birthdate | date:'yyyy-MM-dd h:mm:ss'}}</td>
<td data-title="'Last Date'" sortable="'lastdate'">{{ws.lastdate | date:'yyyy-MM-dd h:mm:ss'}}</td>
<td data-title="'Last Value'" sortable="'lastvalue'">{{ws.lastvalue}}</td>
</tr>
</table>
Try repeating over $data instead of data in your table:
<table ng-table="tableParams" class="table table-striped table-hover table-bordered">
<tr ng-repeat="ws in $data | filter:search" style="text-align:center;">
<td data-title="'Tag Name'" sortable="'tagname'">{{ws.tagname}}</td>
<td data-title="'Description'" sortable="'tagname'">{{ws.tagdescription}}</td>
<td data-title="'Data Type'" sortable="'datatype'">{{ws.datatype}}</td>
<td data-title="'Tag Unit'" sortable="'tagdescription'">{{ws.tagunit}}</td>
<td data-title="'Birth Date'" sortable="'birthdate'">{{ws.birthdate | date:'yyyy-MM-dd h:mm:ss'}}</td>
<td data-title="'Last Date'" sortable="'lastdate'">{{ws.lastdate | date:'yyyy-MM-dd h:mm:ss'}}</td>
<td data-title="'Last Value'" sortable="'lastvalue'">{{ws.lastvalue}}</td>
</tr>
</table>
$data is used internally by ngTable to handle pagination among other things.

Nested interpolation

I return an array of people from the database eg,
[
{
id: 1,
name: 'Jim',
address: "123 Test Street",
phone: "999999999"
},
{
id: 2,
name: 'Tom',
address: "123 Test Street",
phone: "888888888"
},
{
id: 3,
name: 'Harry',
address: "123 Test Street",
phone: "012345678"
}
]
my API allows me to select a partial person by setting the fields parameter
eg for this example,
&fields=id,name,address,phone
full url for this example,
?q=&fields=id,name,address,phone&id=1,2,3
I want to be able to dynamically generate a table based on the fields selected.
Something like this,
<table>
<thead>
<tr>
<th ng-repeat="field in fields">[[ field.text ]]</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in people">
<td ng-repeat="field in fields">[[ person.[[ field.id ]] ]]</td>
</tr>
</tbody>
</table>
How can I interpolate the field.id so i can use to it select the key in person.
Edit, I have changed the interpolation characters to [[ & ]].
This line
<td ng-repeat="field in fields">[[ person.[[ field.id ]] ]]</td>
should be
<td ng-repeat="field in fields">[[ person[field.id] ]]</td>
If working with newer versions of Angular, using curly brackets with the nested interpolation in square brackets will do the trick.
<table id="dynamicTable" class="table table-hover" cellspacing="0">
<thead>
<tr>
<th *ngFor="let col of Columns">{{col.column_name}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of Table">
<td *ngFor="let col of Columns">{{row[[col.column_name]]}}</td>
</tr>
</tbody>
</table>

Resources