I have an leave array with leave counts of different leave types, I have to return the total of every leave types
array = {
"Jan 2021": [
{
"WFH": 17.5
},
{
"CL": 3.5
}
],
"Feb 2021": [
{
"WFH": 19.5
},
{
"CL": 2.5
}
],
"Mar 2021": [
{
"WFH": 13
}
]
}
This is my html file:
<table class="table table-statitics2 table-bordered" aria-label="Leave">
<thead>
<tr>
<th scope="col"></th>
<th scope="col" class="casual">CL</th>
<th scope="col" class="earned">EL</th>
</tr>
</thead>
<tbody *ngIf="leaves">
<tr *ngFor="let item of leaves | keyvalue : keepOriginalOrder">
<td class="date">{{item.key}}</td>
<td>{{getMonthyItem(item.value, "CL")}}</td>
<td>{{getMonthyItem(item.value, "EL")}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="2" class="text-center text-danger" scope="row">Total</th>
<th scope="row">Total of CL</th>
<th scope="row">Total of EL</th>
</tr>
</tfoot>
</table>
this is my function to return Leave Count
getMonthyItem(items, object)
{
let result = '';
items.forEach(element => {
if(Object.keys(element) == object)
{
result = element[object];
}
});
return result;
}
How can I return total of every leave types on footer section of table, also is there any simple way to return leave counts directly on html page without the function, that have used.
Expected result is,
CL
WFH
Jan 2021
3.5
17.5
Feb 2021
2.5
19.5
Mar 2021
1
13
Total
7
50
Thanks............................................................................................................................................................................................
<table class="table table-statitics2 table-bordered" aria-label="Leave">
<thead>
<tr>
<th scope="col"></th>
<th scope="col" class="casual">CL</th>
<th scope="col" class="earned">EL</th>
</tr>
</thead>
<tbody *ngIf="leaves">
<tr *ngFor="let item of leaves | keyvalue : keepOriginalOrder">
<td class="date">{{item.key}}</td>
<td>{{getMonthyItem(item.value, "CL")}}</td>
<td>{{getMonthyItem(item.value, "EL")}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="2" class="text-center text-danger" scope="row">Total</th>
<th scope="row">Total of CL</th>
<th scope="row">Total of EL</th>
</tr>
<tr>
<td>total('CL')</td>
<td>total('EL')</td>
</tr>
</tfoot>
</table>
and then in your .ts function define a new function. As I see you already keep as field the leaves which contains all the information. So it would be
public total (type: string): number {
let sum = 0;
Object.keys(this.leaves).forEach(key => {
this.leaves[key].forEach(element => {
sum = sum + (element[type] ? element[type] : 0);
});
});
return sum;
}
The way I would go about it is to calculate the total in a function and add an extra row manually with the data in:
HTML:
<table class="table table-statitics2 table-bordered" aria-label="Leave">
<thead>
<tr>
<th scope="col"></th>
<th scope="col" class="casual">CL</th>
<th scope="col" class="earned">EL</th>
</tr>
</thead>
<tbody *ngIf="leaves">
<tr *ngFor="let item of leaves | keyvalue : keepOriginalOrder">
<td class="date">{{item.key}}</td>
<td>{{getMonthyItem(item.value, "CL")}}</td>
<td>{{getMonthyItem(item.value, "EL")}}</td>
</tr>
<tr>
<td class="date">Total</td>
<td>{{total(leaves, "CL")}}</td>
<td>{{total(leaves, "WFH")}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="2" class="text-center text-danger" scope="row">Total</th>
<th scope="row">Total of CL</th>
<th scope="row">Total of EL</th>
</tr>
</tfoot>
</table>
Function:
total(items, object)
{
let result = 0;
items.forEach(x => {
if(Object.keys(x) == object)
{
result = result + x[object];
}
});
return result;
}
Related
There are some values returned by ngFor in Total Column. Now I wanted to add those value to get a one grandTotal. I didn't get the idea. Anyone can help me??
In below second table:
I want {{sales.Total}} values to be added and return grand total.
/*****First Table*****/
<table class="table">
<thead>
<tr>
<th scope="col">S.N</th>
<th scope="col">Items</th>
<th scope="col">Quantity</th>
<th scope="col">Rate</th>
<th scope="col">Total</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let sales of salesTransaction, let i = index">
<th>{{i+1}}</th>
<!-- <td mat-cell *matCellDef="let salesTransaction">{{salesTransaction.ProductName}}</td> -->
<td>{{sales.ProductName}}</td>
<td>{{sales.Quantity}}</td>
<td>{{sales.Rate}}</td>
<td>{{sales.Total}}</td>
</tr>
</tbody>
</table>
/*****Second Table*****/
<table class="right-table">
<tbody>
<tr>
<th>Sub-Total</th>
<td *ngFor="let sales of salesTransaction">{{sales.Total}}</td>
</tr>
<hr class="divider">
<tr>
<th>Tax</th>
<td>Happy</td>
</tr>
<hr class="divider">
<tr>
<th>Grand Total</th>
<td>0000</td>
</tr>
</tbody>
</table>
You need to create a method that returns grand total
getGrandTotal(): number {
return this.salesTransaction.reduce((acc, val) => acc += val.Total, 0);
}
<tr>
<th>Grand Total</th>
<td>{{getGrandTotal()}}</td>
</tr>
<table class="right-table">
<tbody>
<tr>
<th>Sub-Total</th>
<td *ngFor="let sales of salesTransaction">{{sales.Total}}</td>
</tr>
<hr class="divider">
<tr>
<th>Tax</th>
<td>Happy</td>
</tr>
<hr class="divider">
<tr>
<th>Grand Total</th>
<td>{{salesTransaction.reduce((total, value) => total += value.Total, 0)}}</td>
</tr>
</tbody>
</table>
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
I have a table which prints data from a JSON. Every row have an delete option.
I want to print the deleted data into a new table. I have managed to print data in console but unable to add it into view.
Below is the code:
Controller
$scope.deletedItems = [];
var counter = 0
$scope.removeRow = function (idx) {
console.log(idx);
$scope.TTNdata.splice(idx, 1);
var deletedArray = $scope.TTNdata.slice(idx, 1);
//console.log(deletedArray);
$scope.deletedItems.push(deletedArray);
console.log($scope.deletedItems);
counter++;
$('#counter').html(counter);
};
View:
<table id="deleted-rows" class="">
<thead>
<th>Sr. No</th>
<th>ID</th>
<th>First Name</th>
<th>Second Name</th>
<th>Gender</th>
<th>Email</th>
<th>Image</th>
<th>Remove</th>
</thead>
<tbody>
<tr ng-repeat="item in deletedItems | orderBy:'id'">
<td>{{$index+1}}</td>
<td>{{item.id}} </td>
<td>{{item.first_name}}</td>
<td>{{item.last_name}}</td>
<td>{{item.gender}}</td>
<td>{{item.email}}</td>
<td><img src="{{item.photo}}" alt="{{item.first_name}} {{item.last_name}} photo"></td>
<td class=""> <span style="cursor:pointer" ng-click="removeRow($index)" title="Remove Record" class="glyphicon glyphicon-remove"></span></td>
</tr>
</tbody>
</table>
<table class="table bordered">
<thead>
<tr>
<th>Sr. No</th>
<th>ID</th>
<th>First Name</th>
<th>Second Name</th>
<th>Gender</th>
<th>Email</th>
<th>Image</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="data in TTNdata | filter:bindtext | orderBy:'id'">
<td>{{$index+1}}</td>
<td>{{data.id}} </td>
<td>{{data.first_name}}</td>
<td>{{data.last_name}}</td>
<td>{{data.gender}}</td>
<td>{{data.email}}</td>
<td><img src="{{data.photo}}" alt="{{data.first_name}} {{data.last_name}} photo"></td>
<td class=""> <span style="cursor:pointer" ng-click="removeRow($index)" title="Remove Record" class="glyphicon glyphicon-remove"></span></td>
</tr>
</tbody>
</table>
Data is printing in console but not in table, every time i click remove it will generate a blank row in deleted table
What I am doing wrong?
Code on github https://github.com/sahilpopli/learningAngular.git
slice returns array, so try $scope.deletedItems.push(deletedArray[0]);
Or try to concatenate the arrays by doing so: $scope.deletedItems = $scope.deletedItems.concat(deletedArray);
A possible thing that you may need to think is that if you going to have paged tables, removing the object from a list with that index could not be a good thing.
My solution to your problem would be this(using the id instead of index). This is just scratch demonstrating a possible way to achieve what is your desire.
Code
angular.module('App', [])
.controller('MyCtrl', ['$scope', function($scope) {
$scope.List = [{
Id: 1,
Name: 'Name1'
}, {
Id: 2,
Name: 'Name2'
}, {
Id: 3,
Name: 'Name3'
}];
$scope.newList = [];
var remove = function(itemId) {
var indexS = $scope.List.filter(function(item, index) {
return item.Id == itemId;
});
if (indexS.length == 1)
$scope.newList.push($scope.List.splice($scope.List.indexOf(indexS[0]), 1)[0])
};
$scope.removeMe = remove;
}]);
Markup
<body ng-app="App" ng-controller="MyCtrl">
<table>
<thead>
<th> Id </th>
<th> Name </th>
</thead>
<tbody>
<tr ng-repeat="item in List">
<td >{{item.Id}}</td>
<td >{{item.Name}}</td>
<td ng-click="removeMe(item.Id)">removeme</td>
</tr>
</tbody>
</table>
<table>
<thead>
<th> Id </th>
<th> Name </th>
</thead>
<tbody>
<tr ng-repeat="item in newList">
<td >{{item.Id}}</td>
<td >{{item.Name}}</td>
</tr>
</tbody>
</table>
Plunker
this is my code with angularjs:
<table ng-controller="SimulateController">
<thead>
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
<th>Total Price</th>
</tr>
</thead>
<tr ng-repeat="item in items">
<td>{{item.name}}</td>
<td><input ng-model="item.quantity" /></td>
<td>{{item.price}}</td>
<td>{{item.quantity * item.price}}</td>
</tr>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</tfoot>
And i need something like this, to obtain the sum of total price column:
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th>totalsum{{item.quantity * item.price}}</th>
</tr>
</tfoot>
How do i get this?, despite of looking for other topics, i couldnt find anything related to calculated expressions, thanks.
In your controller, define a function getTotal(items) that computes the total;
$scope.getTotal = function (items) {
// compute and return the total price
}
Then in the template:
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th>{{getTotal(items)}}</th> <!-- or {{getTotal(items) | currency}} -->
</tr>
</tfoot>
The function computing the total could be implemented as follows:
$scope.getTotal = function (items) {
var total = 0;
angular.forEach(items, function (item) {
if (item.quantity) {
total += item.quantity * item.price;
}
};
return total;
}
Ideally you could do that with a reduce but that's a out of topic.
I am trying to implement a collapsing row in my smarttable. This is a row that is only visible once the user wants to show some more detail. This is what it looks like now:
<table st-table="displayed" class="table table-striped">
<thead>
<tr>
<th st-ratio="20" st-sort="firstName">first name</th>
<th st-ratio="20" st-sort="lastName">last name</th>
<th st-ratio="10" st-sort="age">age</th>
<th st-ratio="30" st-sort="email">email</th>
<th st-ratio="20" st-sort="balance">balance</th>
</tr>
</thead>
<tbody>
<input type="checkbox" ng-model="show"/> {{show}}
<tr ng-repeat="row in displayed">
<td st-ratio="20">{{row.firstName}}</td>
<td st-ratio="20">{{row.lastName | uppercase}}</td>
<td st-ratio="10">{{row.age}}</td>
<td st-ratio="30">{{row.email}}</td>
<td st-ratio="20">{{row.balance | currency}}</td>
</tr>
<tr ng-show="show">
<td>hallo</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-center">
<div st-items-by-page="20" st-pagination=""></div>
</td>
</tr>
</tfoot>
</table>
Is there a way of displaying a collapsing detailrow for this table?
plunkr ref:http://plnkr.co/edit/8lSx2v?p=preview
<table st-table="displayed" class="table table-striped">
<thead>
<tr>
<th st-ratio="20">#</th>
<th st-ratio="20" st-sort="firstName">first name</th>
<th st-ratio="20" st-sort="lastName">last name</th>
<th st-ratio="10" st-sort="age">age</th>
<th st-ratio="30" st-sort="email">email</th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="row in displayed">
<td>
<button ng-if="row.expanded" ng-click="row.expanded = false" class="btn btn-xs btn-default glyphicon glyphicon-chevron-down"></button>
<button ng-if="!row.expanded" ng-click="row.expanded = true" class="btn btn-xs btn-default glyphicon glyphicon-chevron-right"></button>
</td>
<td st-ratio="20">{{row.firstName}}</td>
<td st-ratio="20">{{row.lastName | uppercase}}</td>
<td st-ratio="10">{{row.age}}</td>
<td st-ratio="30">{{row.email}}</td>
</tr>
<tr ng-if="row.expanded" ng-repeat-end="">
<td colspan="2">
<b>Balance<br /></b>
</td>
<td colspan="3" st-ratio="20">{{row.balance | currency}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-left">
<div st-items-by-page="5" st-pagination=""></div>
</td>
</tr>
</tfoot>
</table>
you can call a function with ng-change, and in there you expand the displayd array.
like I did in the plunker:
var limitVers = [];
for (var j = 0; j < 50; j++) {
limitVers.push(createRandomItem());
}
var addedItems = [];
for (var k = 0; k < 20; k++) {
addedItems.push(createRandomItem());
}
var expaVers = limitVers.concat(addedItems);
$scope.displayed = limitVers;
$scope.update = function(show){
show ? $scope.displayed = expaVers : $scope.displays = limitVers;
}