I am using AngularJS to show data from database, i have implement a Client Side Pagination and Filtering on it but when it load huge data my App becomng crash.
so, i wonder to change it to server side pagination by limit the data until 10 item / page, it's done but when i'm do filtering data, it's only search to displayed item on page. This is my code so far
var app = angular.module('peradmin', ['ngRoute', 'ngAnimate']);
var baseUrl = 'http://localhost/peradmin/';
var currentUrl = window.location.pathname.split('/');
app.filter('startFrom', function() {
return function(input, start) {
if (input) {
start = +start;
return input.slice(start);
}
return [];
}
});
app.controller('CustomerController', function($scope, $http, filterFilter) {
$scope.customer = [];
$scope.filtered = [];
$scope.pageSize = 10;
$scope.currentPage = 0;
$scope.getCustomerData = function(currentPage) {
$http({
method: 'POST',
url: baseUrl + 'customer/getcustomer',
data: { limit: $scope.pageSize, offset: currentPage },
headers: { 'Content-Type': 'application/json' }
}).then(function(response) {
$scope.customer = response.data.customer;
$scope.totalData = response.data.total;
$scope.pageNumber = Math.ceil($scope.totalData / $scope.pageSize);
})
}
$scope.filterData = function() {
$scope.currentPage = 0;
$scope.pageNumber = Math.ceil($scope.filtered.length / $scope.pageSize);
};
$scope.$watchCollection('customer', function() {
if ($scope.results == undefined) return;
$scope.currentPage = 0;
$scope.pageNumber = Math.ceil($scope.totalData / $scope.pageSize);
})
// Next & Previous Button
$scope.paging = function(type) {
if (type == 0 && $scope.currentPage > 0) {
--$scope.currentPage;
} else if (type == 1 && $scope.currentPage < $scope.pageNumber - 1) {
++$scope.currentPage;
}
$scope.getCustomerData($scope.pageSize * $scope.currentPage);
}
// Back to First Page
$scope.firstPage = function() {
$scope.currentPage = 0;
$scope.getCustomerData($scope.pageSize * $scope.currentPage);
}
// Go to Last Page
$scope.lastPage = function() {
$scope.currentPage = $scope.pageNumber - 1;
$scope.getCustomerData($scope.pageSize * $scope.currentPage + 1);
}
// call data when page is loaded
$scope.getCustomerData($scope.currentPage);
});
And this is my view :
<div class="well" id="formsearch">
<form id="search-form" class="form-inline float-lg-right" action="" method="POST">
<input type="text" class="form-control" placeholder="Name" name="name" id="name" ng-model="filter.NAME" ng-change="filterData()">
<input type="text" class="form-control" placeholder="Email" name="email" id="email" ng-model="filter.EMAIL" ng-change="filterData()">
</form>
</div>
<div class="box">
<div class="box-body table-responsive" ng-controller="CustomerController">
<label>Page {{ currentPage + 1 }} from {{ pageNumber }} | Total: {{ totalData }} Data</label>
<br><br>
<table class="table table-hover table-bordered table-striped" width="100%">
<thead>
<tr>
<th style="text-align:center;width:20%;">Email</th>
<th style="text-align:center;width:25%;">Name</th>
<th style="text-align:center;width:10%;">Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="val in $parent.filtered = (customer | filter:{NAMA:filter.NAME,EMAIL:filter.EMAIL})">
<td>{{ val.EMAIL }}</td>
<td>{{ val.NAME }}</td>
<td style="text-align:center;">{{ val.CUST_TYPE == "B" ? "Business": "Personal"}}</td>
</tr>
</tbody>
</table>
<ul class="pagination" ng-if="totalData > 0">
<li><a href="#" ng-click="firstPage()">First Page</a></li>
<li><a href="#" ng-click="paging(0)">Previous</a></li>
<li><a href="#" ng-click="paging(1)">Next</a></li>
<li><a href="#" ng-click="lastPage()">Last Pager</a></li>
</ul>
<div class="alert alert-danger" ng-if="totalData == 0"><center>Data Is Not Found</center></div>
</div>
</div>
how to make it filter to whole data on database?
Thanks
I think it should be:
$http({
method: 'POST',
url: baseUrl + 'customer/getcustomer',
data: {
limit: $scope.pageSize,
offset: currentPage,
filter: {
name: $scope.filter.NAME,
email: $scope.filter.EMAIL
}
},
headers: { 'Content-Type': 'application/json' }
})
Then on server side, wtih these 2 filter properties, you can perform database side filtration
Also, you need button to apply filters or throttle on your change handler:
$scope.filterData = function() {
$scope.currentPage = 0;
$scope.pageNumber = Math.ceil($scope.filtered.length / $scope.pageSize);
$scope.getCustomerData($scope.currentPage);
};
To perform throttle you can try ng-model-options='{ debounce: 1000 }'
:
<input type="text" ng-model-options='{ debounce: 1000 }' class="form-control" placeholder="Name" name="name" id="name" ng-model="filter.NAME" ng-change="filterData()">
<input type="text" ng-model-options='{ debounce: 1000 }' class="form-control" placeholder="Email" name="email" id="email" ng-model="filter.EMAIL" ng-change="filterData()">