I have a requirement to show a 5 column table data with 3 column header similar to the below screenshot (Please igonre the 1st column in table body with yellow star).
Help me with couple of problems given below.
last 3 runs
, I do not get filters.filterStatusFor0($column)
, filterStatusFor1($column)
& filterStatusFor2($column)
in my code?ngtable
<div class="col-md-8">
<table ng-table="taskDetailTableParams" show-filter="true" class="table upgradeTaskDetailTable text-left table-bordered">
<thead>
<th>Task Name</th>
<th>Type of Task</th>
<th colspan="3">Last 3 runs</th>
</thead>
<tbody>
<tr ng-repeat="item in $data" height="10px" class="animate" ng-animate="{enter: 'animate-enter', leave: 'animate-leave'}">
<td data-title="'Task Name'" class="text-left col-sm-4 col-md-4 col-lg-4" header-class="text-left" filter="{ 'name': 'text' }" sortable="'name'">{{ item.name }}</td>
<td data-title="'Type of Task'" class="text-left col-sm-2 col-md-2 col-lg-2" header-class="text-left" filter="{ 'type': 'text' }" sortable="'type'">{{item.type}}</td>
<td data-title="'latest Run'" class="text-left col-sm-2 col-md-2 col-lg-2" header-class="text-left" filter="{ 'selectIdFor0': 'select' }" sortable="'selectIdFor0'" filter-data="filterStatusFor0($column)"><img ng-src="{{ item.statusImageFor0 }}" title="{{ item.statusFor0 }}" data-toggle="tooltip" data-placement="bottom" /></td>
<td data-title="'2nd Latest Run'" class="text-left col-sm-2 col-md-2 col-lg-2" header-class="text-left" filter="{ 'selectIdFor1': 'select' }" sortable="'selectIdFor1'" filter-data="filterStatusFor1($column)"><img ng-src="{{ item.statusImageFor1 }}" title="{{ item.statusFor1 }}" data-toggle="tooltip" data-placement="bottom" /></td>
<td data-title="'3rd Latest Run'" class="text-left col-sm-2 col-md-2 col-lg-2" header-class="text-left" filter="{ 'selectIdFor2': 'select' }" sortable="'selectIdFor2'" filter-data="filterStatusFor2($column)"><img ng-src="{{ item.statusImageFor2 }}" title="{{ item.statusFor2 }}" data-toggle="tooltip" data-placement="bottom" /></td>
</tr>
</tbody>
</table>
</div>
Select filter code
$scope.filterStatusFor0 = function(column) {
var def = $q.defer(),
arr = [],
filterStatus = [];
angular.forEach($scope.taskDetailData, function(item) {
if (jQuery.inArray(item.selectIdFor0, arr) === -1) {
arr.push(item.selectIdFor0);
filterStatus.push({
'id': item.selectIdFor0,
'title': item.statusFor0
});
}
});
filterStatus.sort(function(a, b) {
if (a.id < b.id)
return -1;
if (a.id > b.id)
return 1;
return 0;
});
def.resolve(filterStatus);
return def;
};
Please check this plunker link
You could add a custom header with template-header="my_header.html"
as direcitve attribute and then the easiest way to get your colgroup would be to add a row above the normal header template.
So it's easier to have all the filters in place and for the other empty cells in that row you could do css styling to remove the borders to have a better looking table. (Not added in the updated plunkr).
For the second part of your question with the filter method. You're repeating the same code three times (that's not following DRY principle).
You could improve that by adding an id
to your function so you'll only have one filter method that's just called with different ids.
Below is the updated code with the added custom header template. You can also find the code in this plunkr.
var app = angular.module('main', ['ngTable'])
.controller('DemoCtrl', function($scope, $q, $filter, ngTableParams, $log) {
$scope.taskDetailData = [{
"index": 0,
"id": "000ABC0G000000000WQQ",
"name": "Jaantestsameepidentity",
"type": "Hadoop",
"statusFor0": "Failed",
"selectIdFor0": "Failed",
"statusImageFor0": "http://i.imgur.com/knyz0Ye.png",
"statusFor1": "Failed",
"selectIdFor1": "Failed",
"statusImageFor1": "http://i.imgur.com/knyz0Ye.png",
"statusFor2": "Failed",
"selectIdFor2": "Failed",
"statusImageFor2": "http://i.imgur.com/knyz0Ye.png"
}, {
"index": 1,
"id": "000ABC0I000000000WQC",
"name": "Salesorder_netsuite",
"type": "Salesforce",
"statusFor2": "No runs available",
"statusFor1": "No runs available",
"selectIdFor2": "stopped",
"selectIdFor1": "stopped",
"statusImageFor2": "http://i.imgur.com/L5c69tb.png",
"statusImageFor1": "http://i.imgur.com/L5c69tb.png",
"statusFor0": "Success",
"selectIdFor0": "Success",
"statusImageFor0": "http://i.imgur.com/ZkAwklS.png"
}, {
"index": 2,
"id": "000ABC0I000000000WQW",
"name": "today_record",
"type": "Oracle",
"statusFor2": "No runs available",
"statusFor1": "No runs available",
"selectIdFor2": "stopped",
"selectIdFor1": "stopped",
"statusImageFor2": "http://i.imgur.com/L5c69tb.png",
"statusImageFor1": "http://i.imgur.com/L5c69tb.png",
"statusFor0": "Success",
"selectIdFor0": "Success",
"statusImageFor0": "http://i.imgur.com/ZkAwklS.png"
}];
$scope.taskDetailTableParams = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
sorting: {
index: 'asc' // initial sorting
}
}, {
total: $scope.taskDetailData.length, // length of data
getData: function($defer, params) {
var filterData = params.filter() ? $filter('filter')($scope.taskDetailData, params.filter()) : $scope.taskDetailData;
var orderedData = params.sorting() ? $filter('orderBy')(filterData, params.orderBy()) : filterData;
var table_data = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());
params.total(orderedData.length);
$defer.resolve(table_data);
}
});
/**
* Filter for ngtable (Below 3 functions)
* @return {[type]} [description]
*/
$scope.filterStatus = function(column, id) { // for0 --> moved to id
//console.log(column);
var def = $q.defer(),
arr = [],
filterStatus = [];
angular.forEach($scope.taskDetailData, function(item) {
//console.log(item.selectIdFor0, item['selectIdFor' + id])
if (jQuery.inArray(item['selectIdFor' + id], arr) === -1) {
arr.push(item['selectIdFor' + id]);
filterStatus.push({
'id': item['selectIdFor' + id],
'title': item['statusFor' + id]
});
}
});
filterStatus.sort(function(a, b) {
if (a.id < b.id)
return -1;
if (a.id > b.id)
return 1;
return 0;
});
def.resolve(filterStatus);
return def;
};
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.3.3/ng-table.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.3.3/ng-table.min.js"></script>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<div ng-app="main" ng-controller="DemoCtrl">
<script type="text/ng-template" id="aw_ngtable_header.html">
<tr>
<!-- add new row above normal header for last 3 runs colgroup -->
<th ng-repeat="n in [].constructor($columns.length-2) track by $index" colspan="{{lastThree = ($index == $columns.length -3)? 3:''}}">
<span ng-if="lastThree">Last 3 runs</span>
</th>
</tr>
<tr>
<th ng-repeat="column in $columns"
ng-class="{
'sortable': parse(column.sortable),
'sort-asc': params.sorting()[parse(column.sortable)]=='asc',
'sort-desc': params.sorting()[parse(column.sortable)]=='desc'
}"
ng-click="sortBy(column, $event)"
ng-show="column.show(this)"
ng-init="template = column.headerTemplateURL(this)"
class="header {{column.class}}">
<div ng-if="!template" ng-show="!template" ng-bind="parse(column.title)"></div>
<div ng-if="template" ng-show="template"><div ng-include="template"></div></div>
</th>
</tr>
<tr ng-show="show_filter" class="ng-table-filters">
<th ng-repeat="column in $columns" ng-show="column.show(this)" class="filter">
<div ng-repeat="(name, filter) in column.filter">
<div ng-if="column.filterTemplateURL" ng-show="column.filterTemplateURL">
<div ng-include="column.filterTemplateURL"></div>
</div>
<div ng-if="!column.filterTemplateURL" ng-show="!column.filterTemplateURL">
<div ng-include="'ng-table/filters/' + filter + '.html'"></div>
</div>
</div>
</th>
</tr>
</script>
<table ng-table="taskDetailTableParams" template-header="aw_ngtable_header.html" show-filter="true" class="table upgradeTaskDetailTable text-left table-bordered">
<!--<thead>
<th>Task Name</th>
<th>Type of Task</th>
<th colspan="3">Last 3 runs</th>
</thead>-->
<tr ng-repeat="item in $data" height="10px" class="animate" ng-animate="{enter: 'animate-enter', leave: 'animate-leave'}">
<td data-title="'Task Name'" class="text-left col-sm-4 col-md-4 col-lg-4" header-class="text-left" filter="{ 'name': 'text' }" sortable="'name'">{{ item.name }}</td>
<td data-title="'Type of Task'" class="text-left col-sm-2 col-md-2 col-lg-2" header-class="text-left" filter="{ 'type': 'text' }" sortable="'type'">{{item.type}}</td>
<td data-title="'latest Run'" class="text-left col-sm-2 col-md-2 col-lg-2" header-class="text-left" filter="{ 'selectIdFor0': 'select' }" sortable="'selectIdFor0'" filter-data="filterStatus($column, 0)">
<img ng-src="{{ item.statusImageFor0 }}" title="{{ item.statusFor0 }}" data-toggle="tooltip" data-placement="bottom" />
</td>
<td data-title="'2nd Latest Run'" class="text-left col-sm-2 col-md-2 col-lg-2" header-class="text-left" filter="{ 'selectIdFor1': 'select' }" sortable="'selectIdFor1'" filter-data="filterStatus($column, 1)">
<img ng-src="{{ item.statusImageFor1 }}" title="{{ item.statusFor1 }}" data-toggle="tooltip" data-placement="bottom" />
</td>
<td data-title="'3rd Latest Run'" class="text-left col-sm-2 col-md-2 col-lg-2" header-class="text-left" filter="{ 'selectIdFor2': 'select' }" sortable="'selectIdFor2'" filter-data="filterStatus($column, 2)">
<img ng-src="{{ item.statusImageFor2 }}" title="{{ item.statusFor2 }}" data-toggle="tooltip" data-placement="bottom" />
</td>
</tr>
</table>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With