Please help me, I'm using 2 JSON feed, need to display array value in one table then add sum row for each column, but I don't know how to call Expense Table and sum it.
Income JSON Table:
nominal_income
Expense JSON Table:
nominal_expense
If you have any example please let me know :D
My HTML:
<table ng-controller="incomeCtrl">
<tr>
<td>Income</td>
<td>Expense</td>
</tr>
<tr ng-repeat="item in incomes" ng-init="$last ? runEvent(item) : null">
<td class="text-left">{{item.nominal_income}}</td>
<td class="text-left">{{item.nominal_expense}}</td> // how to call this?
</tr>
<tr>
<td class="text-left" >{{ income_total | number:2 }}</td>
<td class="text-left" >{{ expense_total | number:2 }}</td> //how to sum this ?
</tr>
</table>
JS Controller:
$scope.runEvent = function(item) {
var income_total = 0;
angular.forEach(item, function(item) {
income_total = income_total -(- incomes.nominal_income)
;})
$scope.income_total = income_total;}
Use a custom function and call the function with key parameter
angular.module("test",[]).controller("testc",function($scope) {
$scope.incomes=[{nominal_income:20,nominal_expense:75.5},{nominal_income:30.00,nominal_expense:14.50},{nominal_income:49.99,nominal_expense:10}]
$scope.average = function(array, key) {
var value= 0,
average;
for (var i = 0; i < array.length; i++) {
value+= array[i][key];
}
return value;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="testc">
<table >
<tr>
<td>Income</td>
<td>Expense</td>
</tr>
<tr ng-repeat="item in incomes" ng-init="$last ? runEvent(item) : null">
<td class="text-left">{{item.nominal_income}}</td>
<td class="text-left">{{item.nominal_expense}}</td>
</tr>
<tr>
<td style="color:green" class="text-left" >{{average(incomes,"nominal_income") | number:2 }}
</td>
<td style="color:green" class="text-left" >{{average(incomes,"nominal_expense") | number:2 }}
</td>
</tr>
</table>
</div>
Update: How to join IncomeCtrl and ExpenseCtrl
You can call another controller inside a controller as nested controller. Or you can pass the data from one controller to another controller by using $routScope or $Cookies or $service or $BroadCase etc
<table ng-controller="incomeCtrl">
<tr>
<td>Income</td>
<td>Expense</td>
</tr>
<tr ng-repeat="item in incomes" ng-init="$last ? runEvent(item) : null">
<td class="text-left">{{item.nominal_income}}</td>
<td ng-controller="ExpenseCtrl" class="text-left">{{expenses[$index].nominal_expense}}</td> // may you need $$parent.$index
</tr>
<tr>
<td style="color:green" class="text-left" >{{average(incomes,"nominal_income") | number:2 }}
</td>
<td ng-controller="ExpenseCtrl" style="color:green" class="text-left" >{{average(expenses,"nominal_expense") | number:2 }}
</td>
</tr>
</table>
You can pass a type / column as a parameter to be reduced to get the sum. Here is an example:
var app = angular.module('myApp', []);
app.controller('incomeCtrl', function($scope, incomeService) { // incomeService injected here as a serivce
var inc = incomeService.get_income();
var exp = incomeService.get_expense();
$scope.incomes = [];
/* works if `inc` and `exp` have the same length, merge with caution! */
for (var i = 0; i < inc.length; i++) {
$scope.incomes.push({
"nominal_income": inc[i],
"nominal_expense": exp[i]
})
}
$scope.sum = function(type) {
return $scope.incomes.reduce((x, y) => {
return x + y[type];
}, 0);
}
});
app.factory('incomeService', function() {
var service = {};
var data = {
"income": [2.01, 3.23, 6.56],
"expense": [1.12, 2.34, 5.67]
}
service.get_income = function() {
return data.income;
}
service.get_expense = function() {
return data.expense;
}
service.set_income = function(array) { // populated in incomeCtrl
data.income = array;
}
service.set_expense = function(array) { // populated in expenseCtrl
data.expense = array;
}
return service;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp" ng-controller="incomeCtrl">
<table>
<tr>
<td>Income</td>
<td>Expense</td>
</tr>
<tr ng-repeat="item in incomes">
<td class="text-left">{{item.nominal_income}}</td>
<td class="text-left">{{item.nominal_expense}}</td>
</tr>
<tr style="color:red;">
<td class="text-left">{{sum('nominal_income') | number:2}}</td>
<td class="text-left">{{sum('nominal_expense') | number:2}}</td>
</tr>
</table>
</div>
Related
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
Can someone advise why the following is not working.
Controller:
(function () {
'use strict';
angular
.module("shop")
.controller("CartSummaryController", CartSummaryController);
function CartSummaryController($scope, cart) {
$scope.cartData = cart.getProducts();
console.log($scope.cartData);
$scope.total = function () {
var total = 0;
for (var i = 0; i < $scope.cartData.length; i++) {
total += ($scope.cartData[i].price * $scope.cartData[i].count);
}
return total;
}
$scope.remove = function (id) {
cart.removeProduct(id);
}
}
})();
Html:
Your Cart
<div ng-show="cartData.length == 0">
There are no products in your shopping cart.
</div>
<div ng-hide="cartData.length == 0">
<table class="table">
<thead>
<tr>
<th>Quantity</th>
<th>Item</th>
<th class="text-right">Price</th>
<th class="text-right">Subtotal</th>
</tr>
</thead>
</table>
<tbody>
<tr ng-repeat="item in cartData">
<td>{{item.count}}</td>
<td>{{item.name}}</td>
<td>{{item.price | currency}}</td>
<td>blah</td>
</tr>
</tbody>
</div>
Object printed to console:
Object
count
:
1
id
:
"1"
name
:
"item #1"
price
:
"100.00"
Furthermore, is there a way to debug the ng-repeat?
The label </table> should go after the label </tbody>
<!--customers view-->
<div class="container">
<div class="row">
<div class="col-md-12">
<table class="table table-responsive table-striped">
<tr>
<th ng-click="doSort('name')">Name</th>
<th ng-click="doSort('city')">City</th>
<th ng-click="doSort('order')">OrderTotal</th>
<th ng-click="doSort('joined')">Join</th>
<th>Orders</th>
<th>Delete</th>
</tr>
<tr ng-repeat="cust in customers |filter:customerFilter | orderBy:sortBy:reverse" class="repeat-animation">
<td>{{ cust.name | uppercase }}</td>
<td>{{ cust.city }}</td>
<td>{{ cust.orderTotal | currency: 'AED ' }}</td>
<td>{{ cust.joined | date}}</td>
<td>View Orders</td>
<td class="center"><span class="glyphicon glyphicon-remove delete" ng-click="remove(cust.id)"></span></td>
</tr>
</table>
</div>
</div>
</div>
/*------------Customer Controller-------------------*/
myApp.controller('CustomersController', ['$scope', 'customersFactory', 'appSettings', function($scope, customersFactory, appSettings) {
var customers = [];
$scope.sortBy = 'name';
$scope.reverse = false;
$scope.appSettings = appSettings;
function init() {
$scope.customers = customersFactory.getCustomers();
}
init();
$scope.doSort = function(propName) {
$scope.sortBy = propName;
$scope.reverse = !$scope.reverse;
}
$scope.remove = function(customer) {
customersFactory.remove(customer);
};
}]);
/* factory remove method*/
factory.remove = function(item) {
factory.customers = _.reject(factory.customers, function(element) {
return element.id === item.id;
});
};
return factory;
I am making table which display the customers and their order and I want to delete the particular orders with the help of underscore reject method, but it is not deleting. My angular version is 1.5. Can anyone suggest the solution?
I try to create a dynamic invoice, i have quantity and price column, and then i get total Value Of Products, so when i change value of quantity, price and total value should be changed, i find a way to change price but total value does not work:
<div class="container" ng-controller="OrderController" ng-init="quantity=1">
<div id="order-detail-content" class=" row">
<table id="cart_summary">
<thead>
<tr>
<th>Total</th>
<th> </th>
<th>Qty</th>
<th>Unit price</th>
<th>Availability</th>
<th>Description</th>
<th>Product</th>
</tr>
</thead>
<tfoot>
<tr class="cart_total_price">
<td colspan="2" class="price" id="total_product">{{totalValueOfProducts}}</td>
<td colspan="3" class="text-right">Total</td>
<td rowspan="4" colspan="3" id="cart_voucher" class="cart_voucher"></td>
</tr>
</tfoot>
<tbody>
<tr ng-repeat="order in Orders track by $index" >
<td class="cart_total" data-title="Total">
<span class="price" id="total_product_price_3_13_0">
{{order.Price * quantity}}
</span>
</td>
<td >
<input size="2" ng-model="quantity" type="text" value="1" name="quantity_3_13_0_0">
</td>
<td>
<ul class="price text-right" id="product_price_3_13_0">
<li ng-model="order.Price" class="price"> {{order.Price}}</li>
</ul>
</td>
<td class="cart_description">
<p style="color:black" class="product-name">{{order.ProductName}}</p>
<hr />
<small style="color:black" class="cart_ref">{{order.ProductDescription}}</small>
</td>
<td class="cart_product">
<img ng-src="" alt="Printed Dress" width="98" height="98">
</td>
</tr>
</tbody>
</table>
</div> <!-- end order-detail-content -->
and in controller i define $watch on quantity :
<script>
app.controller('OrderController', function ($scope, $http) {
$scope.Orders = {};
$scope.GetOrders = function () {
$http.get('/Order/GetAllOrders').success(function (response) {
$scope.Orders = response;
//debugger;
GetTotalValueOfProducts(response);
});
}
$scope.GetOrders();
GetTotalValueOfProducts = function (response) {
//debugger;
$scope.totalValueOfProducts = 0;
for (var i = 0; i < response.length; i++) {
$scope.totalValueOfProducts += response[i].Price * $scope.quantity;
}
}
$scope.$watch('quantity', function () {
debugger;
$scope.GetOrders();
});
});
</script>
when i changed value of quantity, the value of totalValueOfProducts was not changed!why $watch did not work? what is the problem?
'quantity' needs to be in the $scope for the binding to take place
on a separate note, it would be better to move all data (orders, quantity etc) into a service, it would better adhere to angular's MVC paradigm
I tried get the width of child after the view updated.
My directive:
.directive("scrolltbody", function ($timeout) {
return {
scope: {
val: "="
},
link: function(scope, element, attrs) {
scope.$on("ajustarTabelaPedido", function() {
$timeout(function(){
compilar(element, attrs);
}, 10000);
});
}
}
function compilar (element, attrs){
var wTable = angular.element(element).width();
var th = angular.element(element).find("thead th");
var tr = angular.element(element).find("tbody tr").get(0);
var td = angular.element(tr).find("td");
angular.forEach(th, function (itemTh, indexTh){
var wElement = angular.element(itemTh).attr("widthscroll");
var wElementCalc = ((wElement * wTable) / 100);
/* w = 0 forever*/
var w = $(tr).find("td").eq(indexTh).outerWidth();
});
}
});
My controller:
.controller("PedidoController", function($scope, $pedido) {
/*
.
.
.
*/
$scope.buscar = function() {
$pedido.buscar().then(function(req) {
$scope.pedido = req;
/* This dispatch update for directive */
$scope.$broadcast("ajustarTabelaPedido");
});
};
/*
.
.
.
*/
});
HTML:
<table id="pedido" class="gridbox pedido" scrolltbody val="pedido" style="height: 350px;">
<thead data-spy="affix" data-offset-top="60" data-offset-bottom="200">
<tr>
<th>Imagem</th>
<th>Produto</th>
<th>
<span ng-click="ordem.coluna='produto.alavancagem';ordem.reverso=!ordem.reverso">Planejado</span>
<i ng-show="pedido.erroCaixaria" style="cursor: pointer;" class="fa fa-arrow-up fa-1 justify" title="Regularizar caixaria para mais." ng-click="corrigeCaixaria(pedido, 1)"></i>
<i ng-show="pedido.erroCaixaria" style="cursor: pointer;" class="fa fa-arrow-down fa-1 justify" title="Regularizar caixaria para menos." ng-click="corrigeCaixaria(pedido, 0)"></i>
</th>
<th>Preço Tabela</th>
<th>Caixaria</th>
<th>Preço Praticado</th>
<th>% Desconto</th>
<th>% Politica Desconto</th>
<th>Preço c/ Desconto</th>
<th>Bonificação</th>
<th>Preço Pedido</th>
</tr>
</thead>
<tbody class="body" id="pedido-produto">
<tr ng-repeat="p in pedido.item | orderBy:ordem.coluna:ordem.reverso | filter: itemFilter" >
<td><img src="<...>" alt="{{p.produto.produto.id | normalizarProdutoSku}}" style="max-height: 50px;" /></td>
<td><i class="fa fa-trash-o fa-1 justify icon-lixeira"></i> {{p.produto.produto.descricao}}</td>
<td>
<input ng-model="p.produto.alavancagem" />
</td>
<td>{{p.produto.precoTabelaView | currency}}</td>
<td>{{p.produto.gradeMinima}}</td>
<td>
<input ng-model="p.produto.precoPraticado"/>
</td>
<td><input ng-model="p.produto.percentualDesconto"/></td>
<td><input ng-model="limitePoliticaDesconto"/></td>
<td>R$ <input ng-model="p.produto.precoDesconto"/></td>
<td ng-class="{'celula-erro' : p.bonificacaoErro}">
<input ng-model="p.produto.bonificacao" />
</td>
<td>{{p.produto.precoDesconto * p.produto.alavancagem | currency}}</td>
</tr>
</tbody>
</table>
Whats the problem?
You don't have any tds in your table body (that's why the width is always 0), you need to add the cells in your view:
<tr ng-repeat="p in pedido.item | orderBy:ordem.coluna:ordem.reverso | filter: itemFilter" >
<td>{{ p.anyProperty1 }}</td>
<td>{{ p.anyProperty2 }}</td>
<td>STATIC VALUE</td>
</tr>