Get real width of element child in directive angular - angularjs

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>

Related

How to Sum From Multi object

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>

Angularjs search filter doesnot search in all the pages

The search filter only finds the records from the current page. And I want it to search from all the pages. I have used $scope.watch but I guess I am lacking knowledge in that. How shall I do it? Greatly appreciate the help. Thanks.
HTML:
<md-input-container flex>
<label>Search Participant</label>
<input ng-model="search" type="text" style="cursor: pointer;"/>
</md-input-container>
<div class="search-container">
<md-table-container>
<form class="epForm">
<table md-table md-row-select multiple >
<thead md-head>
<tr md-row>
<th md-column><span><!-- <input type="checkbox" ng-model="selectedAll" ng-click="checkAll()"/> -->Select</span>
</th>
<th md-column><span>Endpoint Name</span></th>
<th md-column><span>Endpoint Aliase</span></th>
<th md-column><span>Endpoint Protocol</span></th>
</tr>
</thead>
<tbody md-body>
<tr md-row ng-click="" md-select-id="name" ng-repeat="endpoint in endpoints | startFrom:currentPage*pageSize | limitTo:pageSize | filter: search ">
<td md-cell><input type="checkbox" ng-model="endpoint.Selected" ng-change="endpointsSelected(endpoint)"/></td>
<td md-cell>{{endpoint.partName}}</td>
<td md-cell>{{endpoint.partSignalId}}</td>
<td md-cell>{{endpoint.partSignalType}}</td>
</tr>
<tr>
<button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1"
style="background: transparent;border: aliceblue;">
<img src="./images/previous.jpg"/>
</button>
{{currentPage+1}}/{{numberOfPages()}}
<button ng-disabled="currentPage >= endpoints.length/pageSize - 1" ng-click="currentPage=currentPage+1"
style="background: transparent;border: aliceblue;">
<img src="./images/next.jpg"/>
</button>
</tr>
</tbody>
</table>
</form>
</md-table-container>
</div>
JS:
$scope.currentPage = 0;
$scope.pageSize = 10;
$scope.$watch('search', function (v) {
$scope.currentPage = 0;
$scope.numberOfPages();
//$scope.pages = $scope.range();
}, true);
LoadingShow();
PinnacaService.getEndpointList(
$rootScope.admin.session_key,
$rootScope.room,
function(data, status){
$scope.endpoints = data;
$scope.numberOfPages=function(){
return Math.ceil($scope.endpoints.length/$scope.pageSize);
}
LoadingHide();
},
function(data, status){
if(status == 403){ //session timeout
alert($scope.$parent.lang.session_timeout);
$scope.$parent.logout();
}
$scope.msg_error = true;
$scope.msg_error_status = status;
$scope.msg_error_text = data;
LoadingHide();
});
myApp.filter('startFrom', function() {
return function(input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
Modify following code
<tr md-row ng-click="" md-select-id="name" ng-repeat="endpoint in endpoints | startFrom:currentPage*pageSize | limitTo:pageSize | filter: search ">
With
<tr md-row ng-click="" md-select-id="name" ng-repeat="endpoint in endpoints | filter: search | startFrom:currentPage*pageSize | limitTo:pageSize ">

Angularjs: Check to push and unchecked to splice id from array

I have a table fetched from php script. given below code work perfectly when i tick the box it push ids successfully but while splice it didn't work well.
it splice array too when i tick and untick only single row. but when i select multiple rows it push again and again even when i untick. please check the code.
$scope.exampleArray = [];
$scope.pushInArray = function(id) {
// get the input value
/* var inputVal = id;*/
var index = $scope.exampleArray.indexOf(id);
if( index ){
$scope.exampleArray.push(id);
}else { $scope.exampleArray.splice(index, 1); }
$scope.deleteBulk = function(){
if(confirm("Are you sure you want to delete " + $scope.exampleArray.length + " record(s))?")){
$http.post('http://localhost/angular-code-crud/index.php/user/bulk_delete_user',
{'id':$scope.exampleArray}).success(function(){
$scope.displayUsers();
});
}
};
};
<table class="table table-striped table-hover table-condensed">
<thead>
<tr>
<th></th>
<th ng-click="sort('name')">Name
<span class="glyphicon sort-icon" ng-show="sortKey=='name'" ng-class="{'glyphicon-chevron-up':reverse,'glyphicon-chevron-down':!reverse}"></span></th>
<th ng-click="sort('gender')">Gender<span class="glyphicon sort-icon" ng-show="sortKey=='gender'" ng-class="{' glyphicon glyphicon-chevron-up':reverse,' glyphicon glyphicon-chevron-down':!reverse}"></span>
<th ng-click="sort('email')">Email<span class="glyphicon sort-icon" ng-show="sortKey=='email'" ng-class="{' glyphicon glyphicon-chevron-up':reverse,' glyphicon glyphicon-chevron-down':!reverse}"></span></th>
<th>Address</th>
<th>Phone</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<!-- <tr ng-repeat="user in users | filter:searchUser | orderBy:sortKey:reverse | filter:paginate"> -->
<tr ng-repeat="user in users|orderBy:sortKey:reverse|filter:searchUser " >
<td><!-- <input type="checkbox" ng-click="deleteBulk(user.id)" ng-true-value="{{user.id}}" ng-checked="master" checklist-model="user.id" checklist-value="{{user.id}}">{{ user.id }} -->
<div class="checkbox">
<label>
<input type="checkbox" name="arrExample" ng-model="arrInput" ng-change='pushInArray(user.id)' >
</label>
</div>
</td>
<td>{{ user.name }}</td>
<td>{{ user.gender }}</td>
<td>{{ user.email }}</td>
<td>{{ user.address }}</td>
<td>{{ user.phone }}</td>
<td>
<button class="btn btn-primary" ng-click="updateData(user.id, user.name, user.gender, user.email, user.address, user.phone)">Edit <i class="material-icons">mode_edit</i></button>
<button class="btn btn-danger" ng-click="deleteData(user.id)">Delete <i class="material-icons">delete</i></button>
</td>
</tr>
</tbody>
</table>
sorry for bad English.
Nevermind i found where was bug.
$scope.exampleArray = [];
$scope.pushInArray = function(id) {
// get the input value
/* var inputVal = id;*/
//$scope.exampleArray.push(id);
var index = $scope.exampleArray.indexOf(id);
console.log(index);
if(index === -1 ){ //this is where i have bug. match the condition with -1
$scope.exampleArray.push(id);
} else { $scope.exampleArray.splice(index, 1);}
$scope.deleteBulk = function(){
if(confirm("Are you sure you want to delete " + $scope.exampleArray.length + " record(s))?")){
$http.post('http://localhost/angular-code-crud/index.php/user/bulk_delete_user',
{'id':$scope.exampleArray}).success(function(){
$scope.displayUsers();
});
}
};
};
Hope this helps
JS :
$scope.pushInArray = function(data) {
var index = $scope.exampleArray.indexOf(data.id);
if(data.checked) {
if( index === -1 ) {
$scope.exampleArray.push(data.id);
}
} else {
$scope.exampleArray.splice(index, 1);
}
}
HTML : change input type="checkbox" line to below
<input type="checkbox" name="arrExample" ng-model="user.checked" ng-change='pushInArray(user)' >
change condition index
$scope.pushInArray = function (id) {
var index = $scope.exampleArray.indexOf(id);
if (index <= -1) {
$scope.exampleArray.push(id);
} else
$scope.exampleArray.splice(index, 1);
};
};

Creating dynamic invoice with angularjs

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

How to pass data into directives into ng-repeat table

Now I have some directives which are used in some place, in one place I need to load the data to init them( if there are no data, keep it blank). Here is the template of one of the directives:
<div class="col-lg-12" style='z-index: 99998;'>
<span class="col-lg-12 col-md-12 right-inner-addon typeAhead">
<i class="glyphicon glyphicon-search" ng-show="isBillToEmpty"></i> <i ng-click="cleanBillTo()"
class="glyphicon glyphicon-close" ng-show="!isBillToEmpty" ></i></a> <input class="data "
id="billTo" ng-model="billTo"
typeahead=" billTos.ID as billTos.VALUE for billTos in getBillTos($viewValue)"
typeahead-input-formatter="formatBillToText($model)" type="text">
</span>
</div>
<div class="col-lg-12">
<span class="col-md-12"> <label id="labelBillTo" for="billTo">{{billToLabel}}</label>
</span>
</div>
DirectiveJS:
function($scope, BillToService) {
$scope.billTos = {};
$scope.billTo = '';
$scope.billToLabel = 'Bill To'
$scope.isBillToEmpty = true;
$scope.formatBillToText = function(model) {
for (var i = 0; i < $scope.billTos.length; i++) {
if (model === $scope.billTos[i].ID) {
return $scope.billTos[i].VALUE;
}
}
}
$scope.$watch('billTo', function() {
$scope.billToID = $scope.billTo;
if($scope.billTo.length > 0){
$scope.isBillToEmpty = false;
}else{
$scope.isBillToEmpty = true;
}
});
$scope.cleanBillTo = function() {
$scope.billTo = "";
$scope.billToID = "";
};
$scope.billTos = [{'ID':$scope.billToID,'VALUE':$scope.initialBillToText}];
$scope.billTo = $scope.billToID;
$scope.getBillTos = function(billToText) {
var promise = BillToService.getBillTos(billToText,
$scope.user.expenServerID);
promise.then(function(billTosInformation) {
$scope.billTos = billTosInformation;
});
$scope.billTos = BillToService.getBillTos(billToText,
$scope.user.expenServerID);
return $scope.billTos;
};
} ]).directive('smartBillTo', function() {
return {
restrict : 'E',
controller : "BillToCtrl",
templateUrl : 'components/directives/billTo/bill-to.html'
}
<table id='AllocationTable' ng-controller='maincontroller' class="table table-hover">
<thead>
<tr>
<th class="text-left">
<input type="checkbox" ng-model="selectedAll" ng-click="checkAll()" />
</th>
<th class="text-center">Charge To Dept
</th>
<th class="text-center">Sub Account
</th>
<th class="text-center">Activity
</th>
<th class="text-center">Category
</th>
<th class="text-center">Bill To
</th>
<th class="text-center">Expense Item
</th>
<th class="text-center">Percentage
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat='data in datalist'>*How can I pass data to <smart-billTo>*
<td class="text-left">
<input type="checkbox" ng-model=''/>
</td>
<td class="text-center"><smart-department ></smart-department></td>
<td class="text-center"><input type='text' ng-model=''/></td>
<td class="text-center"><input type='text' ng-model=''/></td>
<td class="text-center"><input type='text' ng-model=''/></td>
<td class="text-center"><smart-bill-to></smart-bill-to></td>
<td class="text-center"><smart-item ></smart-item></td>
<td class="text-center"><input type='text' ng-model=''/></td>
</tr>
</tbody>
</table>
In the maincontroller I get data from service to init the directive value:
$scope.datalist = Someservice.getdata();
How can I pass data into directives to init the input value (such as bill-to).

Resources