Sum total of a column with a calculated expression inside Angularjs - angularjs

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.

Related

Get Total of NgFor item Angular

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;
}

Is it possible to add each value of ngFor as one value?

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>

AngularJS - Summing filtered rows in table

Based in this example I need to sum the ages of the filtered users. It means, if I have three names filtered, the filter in the controller must to sum only these the ages.
html
<div data-ng-app="app" data-ng-controller="controller">
<input type="text" data-ng-model="parameter" placeholder="search">
<p/>
<table border="1">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Age</th>
</tr>
<thead>
<tbody>
<tr data-ng-repeat="user in users | filter: parameter">
<td>{{$index+1}}</td>
<td>{{user.name}}</td>
<td>{{user.age}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">Total ages</td>
<td>{{users | sumByKey: 'age'}}</td>
</tr>
</tfoot>
</table>
</div>
angularjs
var app = angular.module("app", []);
app.filter('sumByKey', function() {
return function(data, key) {
if (typeof(data) === 'undefined' || typeof(key) === 'undefined') {
return 0;
}
var sum = 0;
for (var i = data.length - 1; i >= 0; i--) {
sum += parseInt(data[i][key]);
}
return sum;
};
});
Any idea?
You could store the filtered data in a filteredList and pass it for the calculation,
<tbody>
<tr data-ng-repeat="user in (filteredList = (users | filter: parameter))">
<td>{{$index+1}}</td>
<td>{{user.name}}</td>
<td>{{user.age}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">Total ages</td>
<td>{{filteredList | sumByKey: 'age' }}</td>
</tr>
</tfoot>
DEMO

How to clone and print data in angular

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

Get total td values with Angular JS

I'm trying to add total price with using Angular JS.
<table>
<tr>
<th>Price</th>
</tr>
<tr>
<td>10</td>
</tr>
<tr>
<td>20</td>
</tr>
<tr>
<td>30</td>
</tr>
<tr>
<td>40</td>
</tr>
<tr>
<td>50</td>
</tr>
<tr>
<td>Total Price</td>
</tr>
</table>
This is a possible way of achieving what you asked for using ng-init:
<table ng-init="items.total = {}">
<tr>
<td>name</td>
<td>numberofyears</td>
<td>amount</td>
<td>intrest</td>
</tr>
<tr ng-repeat="item in items">
<td>{{item.name}}</td>
<td ng-init="items.total.numberofyears = items.total.numberofyears + item.numberofyears">{{item.numberofyears}}</td>
<td ng-init="items.total.amount = items.total.amount + item.amount">{{item.amount}}</td>
<td ng-init="items.total.interest = items.total.interest + item.interest">{{item.interest}}%</td>
</tr>
<tr>
<td>Total</td>
<td>{{items.total.numberofyears}}</td>
<td>{{items.total.amount}}</td>
<td>{{items.total.interest}}%</td>
</tr>
</table>
Do something like this:
HTML:
<table>
<tr ng-repeat = "price in prices">
<td ng-bind="price.price"><td>
</tr>
<tr>
<td ng-bind="calculateTotal()"><td>
</tr>
</table>
JS:
$scope.prices = [{
"price": "5"
}, {
"price": "10"
}, {
"price": "13"
}];
$scope.calculateTotal = function() {
var total = 0;
for (i = 0; i < $scope.prices.length; i++) {
total += +$scope.prices[i].price; // (+) sign before variable is used to convert string values to number
}
return total;
};

Resources