angularjs how to ng-repeat array values as column headings - angularjs

How to ng-repeat the values of the below array as the column headings for my ng-table?
I am trying to display the value from $scope.cols array as the column headings of my table, in other words as the fields, and display all the rows.
here is my try:
<div ng-controller="mycontroller as projects">
<table ng-table-dynamic="projects.tableParams with projects.cols"
show-filter="true" class="table table-bordered table-striped">
<tr ng-repeat="row in $data">
<td ng-repeat="col in $columns">{{::row[col.field]}}</td>
</tr>
</table>
</div>
and here is my controller:
app.controller('mycontroller', ["$scope", "$filter", "ngTableParams", "DatabaseRef", "$firebaseArray",
function ($scope, $filter, ngTableParams, DatabaseRef, $firebaseArray) {
//show all projects
var showallprojects = DatabaseRef.ref("projects").orderByKey();
$scope.allprojectslist = $firebaseArray(showallprojects);
var data = $scope.allprojectslist;
data.$loaded().then(function(data) {
console.log(data.length); // data is loaded here
$scope.cols = Object.keys(data[0]);
console.log($scope.cols);
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 7, // count per page
sorting: { country: "asc" },
filter : {
}
}, {
filterSwitch: true,
total: 0, //data.length, // length of data
getData: function ($defer, params) {
// use build-in angular filter
var filteredData = params.filter() ?
$filter('filter')($scope.allprojectslist, params.filter()) :
$scope.allprojectslist;
var orderedData = params.sorting() ?
$filter('orderBy')(filteredData, params.orderBy()) :
$scope.allprojectslist;
params.total($scope.allprojectslist.length);
// set total for recalc pagination
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
});
}]);
note:
the ngtable dynamic model is taken from here and the doc is here.

EDIT
I've probably misunderstood your question, I thought the code above wasn't a copy of st-table examples.
In your scenario, if you want to display each $scope.cols value as a heading you need to ng-repeat="col in cols" and print out your current col value {{col}}.
I'm assuming your data inside the body of the table to be an array of objects, and each object to be in the form of [col] => value.
I'm updating the code sample below.
You simply need to structure better your table.
<div ng-controller="mycontroller as projects">
<table ng-table-dynamic="projects.tableParams with projects.cols"
show-filter="true" class="table table-bordered table-striped">
<thead>
<tr>
<th ng-repeat="col in cols">{{col}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in data">
<td ng-repeat="col in col">{{ row[col] || "empty"}}</td>
</tr>
</tbody>
</table>
</div>
So basically we're cycling the $columns array once for building the heading of the table; then we cycle the $data array to get an array of objects (I suppose), and each iteration is a new row; then inside of each row we cycle the $columns array again to get the col.field we're looking for, and each iteration will be a new <td> inside our row.
Hope this helps.

Related

How to display json data in two columns in a table using angular

I have data in my json it will be dynamic and I want to display the data in a table with two columns. I am trying but only the first two records are repeating. I don't see all the records in the table.. Any help?
http://plnkr.co/edit/Hnb7hkjA16XDbzRT8VAt?p=preview
This is my json : var data = '{
"output":{
"service-status":[
{
"service":"db",
"service-name":"Mongo DB"
},
{
"service":"license",
"service-name":"Smart License"
},
{
"service":"BRM",
"service-name":"Billing"
},
{
"service":"subscription",
"service-name":"subscription"
}
]
}
}';
my html code:
<table border="1px" width="100%" ng-repeat="data in serviceData" ng-if="$index % 2 == 0">
<tr>
<td>{{serviceData[index]["service-name"]}}</td>
</tr>
</table>
i want to display something like this
Mongo Db Smart License
Billing subscription
Transform your data in the controller:
var serviceDataView = function() {
var res = [];
for (var i = 0; i < $scope.serviceData.length; i+=2){
res.push({
col1: $scope.serviceData[i]['service-name'],
col2: $scope.serviceData[i+1] ? $scope.serviceData[i+1]['service-name'] : null
});
}
return res;
};
$scope.structuredData = serviceDataView();
So that it can be easily used in the view:
<table border="1px" width="100%">
<tr ng-repeat="data in structuredData">
<td>{{data.col1}}</td>
<td>{{data.col2}}</td>
</tr>
</table>
Plunker.
The iterator that uses ng-repeat is $index.
Others Iterator: https://docs.angularjs.org/api/ng/directive/ngRepeat
Replace your table for:
<table border="1px" width="100%" ng-repeat="data in serviceData">
<tr>
<td>{{serviceData[$index]["service"]}}</td>
<td>{{serviceData[$index]["service-name"]}}</td>
</tr>
</table>
As per my review, $index is not required at all for this issue. You can use filter for table ngRepeat.check this [link]http://plnkr.co/edit/Hnb7hkjA16XDbzRT8VAt?p=preview
html code here:
<table border="1px" width="100%" ng-repeat="data in serviceData |limitTo:2 ">
<tr>
<td>{{data["service-name"]}}</td>
<td>{{data.service}}</td>
</tr>

How to populate a table with AngularJS

I have a table:
<h4>Table of Results</h4>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Value</th>
<th scope="col">Sub-Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="object in results>
<td>{{object.field1}}</td>
<td>{{object.field2}}</td>
<td>{{object.field3}}</td>
</tr>
</tbody>
</table>
And I have a controller:
angular.module('app', [])
.controller("Ctrl",['$scope', function ($scope) {
$scope.BtnIndex;
$scope.results = [];
$scope.selectBtn = function (index, model1, model2) {
if (index == $scope.BtnIndex)
$scope.BtnIndex = -1;
else {
$scope.newItem = {
field1 : model2.name,
field2 : model2.val,
field3 : model1.name
}
$scope.results.push($scope.newItem);
}
};
I can't work out why the table is not populating with the data. I have checked the console and it is showing the data, as I expected, but it just isn't populating the table.
I'm expecting the answer to be right in front of me, but I can't see it.
You are not binding the results variable to the scope
Please change
results = [];
to this
$scope.results = [];
Here's the official information from Angular themselves
Scope is the glue between application controller and the view. During the template linking phase the directives set up $watch expressions on the scope. The $watch allows the directives to be notified of property changes, which allows the directive to render the updated value to the DOM.
This works - Plunker
JS
$scope.results = [];
$scope.selectBtn = function (index, model1, model2) {
if (index == $scope.BtnIndex)
$scope.BtnIndex = -1;
else {
$scope.newItem = {
field1 : index,
field2 : model1,
field3 : model2
}
$scope.results.push($scope.newItem);
}
}
Markup
<body ng-controller="MainCtrl">
<button ng-click='selectBtn("hello", "world", "today")'>Press me</button>
<h4>Table of Results</h4>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Value</th>
<th scope="col">Sub-Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="object in results">
<td>{{object.field1}}</td>
<td>{{object.field2}}</td>
<td>{{object.field3}}</td>
</tr>
</tbody>
</table>
</body>
It's not possible to see how you are calling $scope.selectBtn in your markup so I've created a simple example from your question.

How to use ng-repeat for array in array using single ng-repeat

I got a json of table which has columns and rows as below
$scope.table = {
Columns: [{Header:"22-Jul-15",SubHeaders: ["10:33 AM"]}
, {Header:"21-Jul-15",SubHeaders: ["03:40 AM"]}
, {Header:"17-Jul-15",SubHeaders: ["01:05 PM", "12:06 PM"]}]
, Rows:[{Items:[{Value:1},{Value:5},{Value:8},{Value:""}]}
,{Items:[{Value:2},{Value:6},{Value:9},{Value:""}]}
,{Items:[{Value:3},{Value:7},{Value:10},{Value:15}]}]
} //end of table
I want to display Columns.SubHeaders as Sub header row of a table.
Here what I tried, but did not work
<table class="table table-stripped table-bordered">
<thead>
<tr>
<th ng-repeat="col in table.Columns" colspan="{{col.SubHeaders.length}}">{{col.Header}}</th>
</tr>
<tr>
<td class="center text-black" ng-repeat="head in table.Columns[0].SubHeaders">{{head}}</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in table.Rows">
<td ng-repeat="item in row.Items">
{{item.Value}}
</td>
</tr>
</tbody>
</table>
I used head in table.Columns[0].SubHeaders just to show it is working for hard-coded index value.
How can I achieve this using single ng-repeat? I can use two ng-repeats but it will lead to unnecessary html markup.
Here is the complete fiddle
I created this fiddler (forked from yours):
https://jsfiddle.net/b50hvzef/1/
The idea is to join the subheaders as they are they actual columns:
<td class="center text-black" ng-repeat="head in subHeaders">{{head}}</td>
and the code looks like this:
var app = angular.module("app",[]);
app.controller("MyController", function ($scope, $http) {
$scope.table = {
Columns: [{Header:"22-Jul-15",SubHeaders: ["10:33 AM"]}
, {Header:"21-Jul-15",SubHeaders: ["03:40 AM"]}
, {Header:"17-Jul-15",SubHeaders: ["01:05 PM", "12:06 PM"]}]
,Rows:[{Items:[{Value:1},{Value:5},{Value:8}]}
,{Items:[{Value:2},{Value:6},{Value:9}]}
,{Items:[{Value:3},{Value:7},{Value:10}]}]
};
var subHeaders = [];
$scope.table.Columns.forEach(function(col) {
col.SubHeaders.forEach(function(subHeader) {
subHeaders.push(subHeader);
});
});
$scope.subHeaders = subHeaders;
});
Note that there is still a mismatch between columns and data. But it's up to you how to solve it.
Hope this helps.

ng-table not paginating table content, Only showing page numbers

I am trying pagination using ng-table. It's showing all the data in single page rather than paginating it. Its not giving any error and also showing page numbers but content is not getting paginated.
<body ng-app="AngularApp">
<table class="table table-bordered table-striped table-hover" id="log_table" ng-controller="ControllerCtrl" ng-table="tableParams">
<tr ng-repeat="logDetail in data">
<td>{{logDetail._source.log_datetime[0]}}</td>
<td>{{logDetail._source.event_src_correlation[0]}}</td>
<td>{{logDetail._source.content_subType[0]}}</td>
</tr>
</table>
</body>
angular.module('AngularApp',['ngTable'])
.controller('ControllerCtrl', function ($scope,$q, ngTableParams) {
$scope.data=[{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-22T17:17:56.689"],"event_src_correlation":[1]},"sort":[1]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-22T19:48:20.459"],"event_src_correlation":[1]},"sort":[2]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-22T19:49:00.981"],"event_src_correlation":[1]},"sort":[3]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-24T20:33:51.762"],"event_src_correlation":[1]},"sort":[4]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-24T20:33:51.763"],"event_src_correlation":[1]},"sort":[5]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-24T20:33:51.768"],"event_src_correlation":[1]},"sort":[6]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-24T20:33:51.770"],"event_src_correlation":[1]},"sort":[7]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-24T20:33:51.784"],"event_src_correlation":[1]},"sort":[8]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-24T20:33:59.943"],"event_src_correlation":[1]},"sort":[9]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-24T20:34:00.360"],"event_src_correlation":[1]},"sort":[10]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:18:08.149"],"event_src_correlation":[1]},"sort":[11]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:18:08.150"],"event_src_correlation":[1]},"sort":[12]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:18:08.151"],"event_src_correlation":[1]},"sort":[13]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:18:08.152"],"event_src_correlation":[1]},"sort":[14]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:18:08.165"],"event_src_correlation":[1]},"sort":[15]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:18:36.586"],"event_src_correlation":[1]},"sort":[16]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:18:36.965"],"event_src_correlation":[1]},"sort":[17]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:19:05.467"],"event_src_correlation":[1]},"sort":[18]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:19:05.468"],"event_src_correlation":[1]},"sort":[19]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:19:05.468"],"event_src_correlation":[1]},"sort":[20]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:19:05.469"],"event_src_correlation":[1]},"sort":[21]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:19:05.476"],"event_src_correlation":[1]},"sort":[22]},{"_source":{"content_subType":["tomcatLog"],"log_datetime":["2014-02-26T13:19:35.917"],"event_src_correlation":[1]},"sort":[23]}];
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: $scope.data.length, // length of data
getData: function($defer, params) {
$defer.resolve($scope.data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
});
Attached plunker link contains code for it : http://plnkr.co/edit/kWVNDXG0RlPAqX5lkwhS?p=preview
You just miss $ in ng-repeater should be logdetail in $data instad of logdetail in data
http://plnkr.co/edit/5etPezh3iCHRpYnzllw1?p=preview
<table class="table table-bordered table-striped table-hover" id="log_table" ng-table="tableParams">
<tr ng-repeat="logDetail in $data">
<td>{{logDetail._source.log_datetime[0]}}</td>
<td>{{logDetail._source.event_src_correlation[0]}}</td>
<td>{{logDetail._source.content_subType[0]}}</td>
</tr>
</table>

Pagination controls not showing up in ng-table when fetching data from backend

I am fetching a list of data from the backend and displaying it using ng-table. The problem is that its not showing the pagination controls. Previously, when I used dummy data to show the ng-table, pagination was working totally fine. Could someone help me out here?
This is my HTML:
<table ng-table="tableParams" show-filter="true" class="table">
<thead>
<tr>
<th ng-repeat="column in columns" ng-show="column.visible"
class="text-center" ng-class="{
'sort-asc': tableParams.isSortBy(column.field, 'asc'),
'sort-desc': tableParams.isSortBy(column.field, 'desc'),
'sortable': !$first
}"
ng-click="tableParams.sorting(column.field, tableParams.isSortBy(column.field, 'asc') ? 'desc' : 'asc')">
<div>{{column.title}}</div>
</th>
</tr>
</thead>
<tr ng-repeat="user in data | filter:searchText">
<td width="30" style="text-align: left">
<input type="checkbox" ng-model="checkboxes.items[user.id]" />
</td>
<td data-title="'Email Id'" class="text-center" sortable="email" ng-show="columns[1].visible">
<span>{{user.email}}</span>
</td>
<td data-title="'User Karma'" class="text-center" sortable="userkarma" ng-show="columns[2].visible">
<span>{{user.userkarma}}</span>
</td>
<td data-title="'Date Joined'" class="text-center" sortable="datejoined" ng-show="columns[3].visible">
<span>{{user.datejoined}}</span>
</td>
<td data-title="'Unsubscribed'" class="text-center" sortable="status" ng-show="columns[4].visible">
<span>{{user.unsubscribed}}</span>
</td>
</tr>
</table>
Below is my js file:
for (var i = 0; i < UserList.getUsers()
.length; i++) {
$scope.data.push({
id: UserList.getUsers()[i]._id,
email: UserList.getUsers()[i].email,
userkarma: UserList.getUsers()[i].healthScore,
datejoined: moment(UserList.getUsers()[i].firstSessionAt)
.format("MMMM Do YYYY"),
unsubscribed: UserList.getUsers()[i].unsubscribed
})
};
$scope.columns = [{
title: '',
field: 'checkbox',
visible: true
},
{
title: 'Email',
field: 'email',
visible: true
}, {
title: 'User Karma',
field: 'userkarma',
visible: true
}, {
title: 'Date Joined',
field: 'datejoined',
visible: true
}, {
title: 'Unsubscribed',
field: 'unsubscribed',
visible: true
}
];
$scope.tableParams = new ngTableParams({
page: 1,
count: 10, // count per page
filter: {
name: 'M' // initial filter
},
sorting: {
name: 'asc'
}
}, {
total: $scope.data.length, // length of data
getData: function ($defer, params) {
// use build-in angular filter
var filteredData = params.filter() ?
$filter('filter')($scope.data, params
.filter()) :
data;
var orderedData = params.sorting() ?
$filter('orderBy')($scope.data,
params.orderBy()) :
$scope.data;
params.total(orderedData.length); // set total for recalc paginationemail
$defer.resolve(orderedData.slice((
params.page() -
1) * params.count(),
params.page() *
params.count()));
}
});
This happens because the usual $scope.tableParams.reload() function used to refresh the data after an asynchronous data load does not refresh the total item count in the table. It didn't happen before because this value is correctly set at the beginning when you were using dummy data.
You need to add a params.total(data.length); the getData function to manually refresh the value.
For me, it's because I was using coffeescript, which automatically returns the value of the last thing in your function. This causes problems because ng-table's getData() gets back a promise, and if it doesn't get one, it creates one itself, from $defer. By using coffeescript and not quite properly converting the example from the Configuring your table with ngTableParams wiki page, I was returning something that wasn't a promise.
In coffeescript, make sure your callback to getData() ends with either
$defer.promise
or
return
so that ng-table gets a promise, or knows to make one itself.
I found the answer. Actually there is an issue with ng-table when loading dynamic data. When the data is dynamically loaded, the getData function is not called. So this is what I did. I created a refreshTable function to call the setTable function which then calls the getData function and renders the table.
$scope.refreshTable = function () {
console.log('\n\n refreshing table')
$scope['tableParams'] = {
reload: function () {},
settings: function () {
return {}
}
};
$timeout(setTable, 100)
};
$scope.refreshTable();
function setTable(arguments) {
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
filter: {
name: '' // initial filter
},
sorting: {
name: 'asc'
}
}, {
filterSwitch: true,
total: $scope.users.length, // length of data
getData: function ($defer, params) {
console.log(
'\n\nngTable getData called now')
var orderedData = params.sorting() ?
$filter('orderBy')($scope.users,
params.orderBy()) :
data;
params.total(orderedData.length);
$defer.resolve(orderedData.slice((params.page() -
1) * params.count(), params.page() *
params.count()));
}
});
}
I had this problem and applied solution provided here but it not solved my problem.My usage was like below
<table ng-table="tableParams" class="table ng-table table-striped" show-filter="{{::showFilter}}">
<tr ng-show="showHeaders">
<th class="th-select" ng-repeat="column in columns">{{column.title}}</th>
</tr>
<tr ng-repeat="row in $data">
<td ng-repeat="column in columns" ng-show="column.visible" sortable="column.field" ng-click="save(row)">
{{row[column.field][column.subfield] || row[column.field]}}
<span compile="column.getValue()" ></span>
</td>
</tr>
</table>
and after one day effort I understand that the problem is using css class "ng-table" . I mentioned this to save your time so other than adding
params.total(data.length)
you should check your css too and the working code is :
<table ng-table="tableParams" class="table table-striped" show-filter="{{::showFilter}}">
<tr ng-show="showHeaders">
<th class="th-select" ng-repeat="column in columns">{{column.title}}</th>
</tr>
<tr ng-repeat="row in $data">
<td ng-repeat="column in columns" ng-show="column.visible" sortable="column.field" ng-click="save(row)">
{{row[column.field][column.subfield] || row[column.field]}}
<span compile="column.getValue()" ></span>
</td>
</tr>
</table>
I had the same experience with loadData + asynchronous load.
On my side the problem was that the data returned by the API was an array of 2 other arrays meanwhile I was using only 1 of the 2 for my table.
See below:
*.js
return $http(options).then(function (resp) {
params.total(resp.data.users.length)
return resp.data
}
*.html
<tr ng-repeat="row in usrCtrl.servicesTable.data.users" ng-if="row.Services.hasOwnProperty(usrCtrl.selectedService)">
By returning "resp.data.users" on javascript side and correctly looping on "usrCtrl.servicesTable.data" on html side then the pager appeared!
Loïc

Resources