Possible scope issue with filtered variable - angularjs

I am trying to do something similar to what this question is doing, getting the length and totals of my filtered results.
HTML:
<div ng-app="app" ng-controller="controller">
<div class="col-md-4 ">Filter: <input class="form-control" ng-model="dataFilter" placeholder="filter" /></div>
<div class="col-md-4 ">Total: {{filtered.length}}</div>
<table class="table table-hover" ts-wrapper>
<thead>
<tr>
<th ts-criteria="policy.policy_number | parseInt">
Policy
</th>
<th ts-criteria="sales_rep.name">
Sales Rep
</th>
<th ts-criteria="policy.customer.full_name">
Customer
</th>
<th ts-criteria="type">
Type
</th>
<th ts-criteria="change_amt | parseFloat">
Change Amount
</th>
<th ts-criteria="effective_date | date">
Effective Date {{filtered.length}}
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="transaction in filtered = (data | filter: dataFilter )" ts-repeat>
<td>{{transaction.policy.policy_number}}{{pizza}}</td>
<td>{{transaction.sales_rep.name}}</td>
<td>{{transaction.policy.customer.full_name}}</td>
<td>{{transaction.transaction_type}}</td>
<td>${{transaction.change_amt | number:currency}}</td>
<td>{{transaction.effective_date | date}}</td>
</tr>
</tbody>
</table>
</div>
The JS really has nothing specific to this. In the above example {{filtered}} displays the filtered results as expected only when within the table (in the <th> in this case). When I try to get the length up above in the div, it returns nothing.
Is some kind of isolated scope being created here? My code appears to match the example the SO question had that I linked above so how come they can access that variable in other elements and I cannot?

Related

How to check the rows of ng-repeat values in angular js

How to access the rows of ng-repeat of array of arrays?
in jsp:
I have one json array object which have content of table.
and another array object table header.
so below I used to implement it. But I have one situation that if col1 data is Y then I need to display one check box. How to check that..
<body ng-app="myApp" ng-controller="mainCtrl">
<div class="table-container">
<table st-table="rowCollection" class="table table-striped">
<thead>
<tr>
<th lr-drag-src="headers" lr-drop-target="headers" ng-repeat="col in columns" st-sort="{{col}}">{{col}}</th>
</tr>
<tr>
<th>
<input st-search="firstName" placeholder="search for firstname" class="input-sm form-control" type="search"/>
</th>
<th colspan="4">
<input st-search placeholder="global search" class="input-sm form-control" type="search"/>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rowCollection">
<td ng-repeat="col in columns**>{{row[col]}}</**td>
</tr>
</tbody>
</table>
</div>
<div ng-show="isLoading" class="loading-indicator"></div>
</body>
Single array:
')" id = "checkExport" value = "{{result.TX_ID}}">
{{result.TX_ID}}
{{result.value2}}
You can use rowCollection[1].columns with foreach to find if some value in columns contains Y. But the better way just use ng-show="col === Y" as attribute to your checkbox. Or ng-hide if you need to hide it.

Why cannot I add new list in a table in angularJS 1.x?

I have example code below where I am supposed to create a list of items.
<div ng-hide="listTrigger">
<!--FIRST TABLE-->
<table class="table table-bordered table-striped">
<thead>
<tr>
<th sortable="code" class="sortable">
Product Name
</th>
<th sortable="placed" class="sortable">
Qty
</th>
<th class="st-sort-disable th-dropdown">
Price
</th>
<th sortable='total.value' class="sortable">
Split
</th>
<th>
</th>
</tr>
</thead>
<tbody>
<tr grid-item>
<td width="40%">
<select class="form-control" ng-model="prod.uid">
<option selected disabled>Select Product</option>
<option ng-repeat="product in products | orderBy : 'name'" ng-value="product.uid" >{{product.name}}</option>
</select>
</td>
<td width="20%">
<input type="number" min="0" ng-model="prod.qty" class="form-control">
</td>
<td width="20%">
<input type="number" min="0" ng-model="prod.price" class="form-control">
</td>
<td width="10%">
<input type="number" min="1" max="100" ng-model="prod.split" class="form-control">
</td>
<td width="10%"><button ng-click="addNewProduct(prod.id)" class="form-control">Add</button></td>
</tr>
</tbody>
</table>
<!--SECOND TABLE-->
<table ng-show="newProducts.length!=0" class="table">
<thead>
<tr>
<th >
Product Name
</th>
<th >
Qty
</th>
<th >
Price
</th>
<th >
Split
</th>
<th>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="newProduct in newProducts">
<td width="60%" ng-bind="newProduct.uid"></td>
<td width="10%" ng-bind="newProduct.qty"></td>
<td width="10%"ng-bind="newProduct.price"></td>
<td width="10%" ng-bind="newProduct.split"></td>
<td width="10%"><button ng-show="newProducts.length!=0" ng-click="removeProduct(newProduct.uid)">X</button></td>
</tr>
</tbody>
</table>
Output
but whatever i type in the textbox of first table is coming just like that in second table. It is supposed to come list by list
In JS I am getting all details from input fields and settinf to an object prod and then pushing it in to an array newProducts.
Later in the table I am using ng-repeat to repeat items in newProducts array. The top table and bottom table are connected in no other way and I cannot figure out why values are chaging in bottom table when they are changed in input fields. Also while trying to add it one more time, it throws an error.
jquery.js:4409 Error: [ngRepeat:dupes] http://errors.angularjs.org/1.4.3/ngRepeat/dupes?p0=newProduct%20in%20newPr…0a-42d3-949e-3e8e59ac2be9%22%2C%22%24%24hashKey%22%3A%22object%3A359%22%7D
Here is the JS to add new item
//function to add new product while creating
$scope.addNewProduct= function(id){
$scope.newProducts.push($scope.prod);
console.log("product array-"+JSON.stringify( $scope.newProducts));
}
I tried console.log to log newProducts array in console, it is getting updated with new array , but not showing up in second table. Please help!
use angular copy.
angular $scopes are two way binded.. the changes u make in first table will be reflected in second table as you are pushing $scope.prod which is two way binded.
Using $scope can be very tricky. I'm not the best in Angular but i have no idea
$scope.newProducts.push($scope.prod);
if you are using here the $scope of the function or the $scope of the Controller.
Put in at the very top of your Controller "var vm=$scope", and in your html use "Controller as vm".
So if you are then there, we can see if the problem still exists.
Angular variables are reference type. So you can use angular.copy() to overcome from this issue. Below the code.
$scope.addNewProduct= function(id){
var products = angular.copy($scope.prod);
$scope.newProducts.push(products);
console.log("product array-"+JSON.stringify( $scope.newProducts));
}
Hope it will help you thanks.

Angualarjs smart table search particular columns

i have used this documentation smart table
<form>
<label for="predicate">selected predicate:</label>
<select class="form-control" id="predicate" ng-model="selectedPredicate" ng-options="predicate for predicate in predicates"></select>
</form>
<table st-table="rowCollection" class="table table-striped">
<thead>
<tr>
<th st-sort="firstName">first name</th>
<th st-sort="lastName">last name</th>
<th st-sort="birthDate">birth date</th>
<th st-sort="balance">balance</th>
<th>email</th>
</tr>
<tr>
<th>
<input st-search="{{firstName}},{{lastName}}" placeholder="search for firstname" class="input-sm form-control" type="search"/>
</th>
<th colspan="3">
<input st-search placeholder="global search" class="input-sm form-control" type="search"/>
</th>
<th>
<input st-search="{{selectedPredicate}}" placeholder="bound predicate" class="input-sm form-control" type="search"/>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rowCollection">
<td>{{row.firstName | uppercase}}</td>
<td>{{row.lastName}}</td>
<td>{{row.birthDate | date}}</td>
<td>{{row.balance | currency}}</td>
<td><a ng-href="mailto:{{row.email}}">email</a></td>
</tr>
</tbody>
</table>
i have used st-search search for particular column . it is working fine but two column not working. can you help me? i need search two column only
There is apparently no way to achieve this directly with the built smart-table.
You can use a directive like suggested here :
AngularJS smart-table search within multiple columns
I have another idea for others who have the same problem:
If your data rowCollection is not too big,
in the javascript in the init() of the page do something like:
self.rowCollection.forEach(function (element) {
element.NameForFilter = element.firstName+ ' ' + element.lastName;
});
and then in the input of the th:
st-search=NameForFilter

Export only filtered data into csv in angular smart table

We have implemented a report table using angular smart table.When user applied search criteria using st-search , we need to export all items into csv.We have used ng-csv directive for exporting. When use st-table array collection, the only first page data is getting.That mean total 7 records after filtering and first page showing 5 items, only this data(5 items) is exported.How can export all filtered data?
<table class="table table-striped" st-table="displayed">
<thead>
<tr>
<th st-sort="firstName">first name</th>
<th st-sort="lastName">last name</th>
<th st-sort="birthDate">birth date</th>
<th st-sort="balance">balance</th>
<th >email</th>
</tr>
<tr>
<th>
<input st-search="firstName" placeholder="search for firstname" class="input-sm form-control" type="search"/>
</th>
<th colspan="4">
<input st-search placeholder="global search" class="input-sm form-control" type="search"/>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in displayed">
<td>{{row.firstName | uppercase}}</td>
<td>{{row.lastName}}</td>
<td>{{row.birthDate | date}}</td>
<td>{{row.balance | currency}}</td>
<td><a ng-href="mailto:{{row.email}}">email</a></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-center">
<div st-pagination="" st-items-by-page="5" st-displayed-pages="10"></div>
</td>
</tr>
</tfoot>
You can have access to the filtered collection through the table controller api. So you just need to create a directive which requires the stTable controller:
.directive('stExport',function(){
return {
require:'^stTable',
link:function(scope, element, attr,ctrl){
element.bind('click',function(){
alert(ctrl.getFilteredCollection().length);
})
};
}
have a look at that running example

How to increase ng-repeat performance using Smart-Table?

I have a problem of performance and i don't find the solution.
Context: I need to display a lot of data ( 500 lines, 8 columns ) in a table. To displayed this data i chosed to use Smart-table because it offers good functionality but the problem is that i have a lot of data and the time of displaying data is very long ( 5 - 9 second, this depend of device performance ).
Important thing: I need to display all data so i don't want pagination method, limit filter.
So this code is working :
<ion-scroll class="scrollVertical" direction="xy" overflow-scroll="true" >
<table st-table="tableaux" class="table table-striped">
<thead>
<tr>
<th ng-repeat="column in ColumnTable">{{column.Label}}</th>
</tr>
<tr>
<th ng-repeat="column in ColumnTable">
<input st-search="{{column.Id}}" placeholder="" class="input-sm form-control" type="search" ng-model="inputRempli"/>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in tableaux">
<td ng-repeat="column in ColumnTable" ng-init="colonne = column.Id">{{row[colonne]}}</td>
</tr>
</tbody>
</table>
</ion-scroll>
I read that Ionic made a directive (collection-repeat) wich allows an app to show huge lists of items much more performantly than ng-repeat. So i tried to remake my solution with collection-repeat but that doesn't work...
Code collection-repeat solution:
<ion-scroll class="scrollVertical">
<table st-table="tableaux" class="table table-striped">
<thead>
<tr>
<th ng-repeat="column in ColumnTable">{{column.Label}}</th>
</tr>
<tr>
<th ng-repeat="column in ColumnTable">
<input st-search="{{column.Id}}" placeholder="" class="input-sm form-control" type="search" ng-model="inputRempli"/>
</th>
</tr>
</thead>
<tbody>
<tr collection-repeat="row in tableaux" item-width="200px" item-height="100px">
<td collection-repeat="column in ColumnTable" ng-init="colonne = column.Id" item-width="100px" item-height="100px">{{row[colonne]}}</td>
</tr>
</tbody>
</table>
</ion-scroll>
Error: Maximum call stack size exceeded
Questions: Is there any angularjs or ionic solution to increase performance of smart-table with a lot of data ?
What's wrong with my collection-repeat ?
What version of Ionic are u using? If you are using version 1.0 beta 14 or higher use bind once (native in Angular 1.3)
It would like like this.
<ion-scroll class="scrollVertical" direction="xy" overflow-scroll="true" >
<table st-table="tableaux" class="table table-striped">
<thead>
<tr>
<th ng-repeat="column in ::ColumnTable">{{::column.Label}}</th>
</tr>
<tr>
<th ng-repeat="column in ::ColumnTable">
<input st-search="{{::column.Id}}" placeholder="" class="input-sm form-control" type="search" ng-model="inputRempli"/>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in ::tableaux">
<td ng-repeat="column in ::ColumnTable" ng-init="colonne = column.Id">{{::row[colonne]}}</td>
</tr>
</tbody>
</table>
</ion-scroll>
How are you loading your datas ?
If you are doing a $scope.ColumnTable.push(newData); then this is not a proper way to do it.
What I do is :
create a service that load a Temporary Table : let's call it myService.setTable().
Inform your controller with an event : This service sends an event $rootScope.$broadCast("myService.setTable-refresh")
Catch the event into your controller & update table : $scope.$on('myService.setTable-refresh,function(){ $scope.myWorkingTable =myService.getTable();});
Update your HTML to work with myWorkingTable
Moreover, you shall define an unique key into your ng-repeat for performance optimisation used by track by to prevent rebuilding already created content.
See explanation here : http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-angularjs-1-2.htm

Resources