Buccaneer Buccaneer - 4 months ago 30
AngularJS Question

Angular pagination column sort across all pages client side

I'm trying to get this to work and seeing if there is an quick easy solution - right now I have a table that I'm doing paging and sorting through all on the client side. Currently on the load of the page I am setting the default sort by date, however there are 2 other columns that can be clicked and sorted. It is working but only on the page that it is currently viewed on, does not trickle down to the other pages. Here's my sort function and paging function. Appreciate any help!

$scope.sortBy = function(keyName){
if($scope.sortType === keyName){
$scope.sortReverse = !$scope.sortReverse;
} else{
$scope.sortReverse = false;
}
$scope.sortType = keyName;
console.log('Type', $scope.sortType, 'Reverse', $scope.sortReverse);
};

function setPage(page) {
if (page < 1 || page > vm.pager.totalPages) {
return;
}

// get pager object from service
vm.pager = PagerService.GetPager(vm.uploads.length, page);

// get current page of items
vm.uploads.sort(function(a,b){
return new Date(b.uploadDate).getTime()- new Date(a.uploadDate).getTime();
})

vm.items = vm.uploads.slice(vm.pager.startIndex, vm.pager.endIndex + 1);
}


Here is the html table code:

<div>
<table class="table">
<tr>
<th ng-click="sortBy('uploadDate')" >Upload Date
<span ng-show="sortType == 'uploadDate' && sortReverse" class="fa fa-caret-down"></span>
<span ng-show="sortType == 'uploadDate' && !sortReverse" class="fa fa-caret-up"></span>
</th>
<th>Product</th>
<th>Comments</th>
<th ng-click="sortBy('templateName')">Template
<span ng-show="sortType == 'templateName' && sortReverse" class="fa fa-caret-down"></span>
<span ng-show="sortType == 'templateName' && !sortReverse" class="fa fa-caret-up"></span>
</th>
<th>Last Updated By</th>
<th>Last Updated</th>
<th ng-click="sortBy(statusName)">Status
<span ng-show="sortType == 'statusName' && sortReverse" class="fa fa-caret-down"></span>
<span ng-show="sortType == 'statusName' && !sortReverse" class="fa fa-caret-up"></span>
</th>
<th>Actions</th>
</tr>
<tr ng-repeat="upload in vm.items | orderBy:sortType:sortReverse">
<td style="white-space: nowrap;">{{upload.uploadDate}}</td>
<td>{{upload.product}}</td>
<td style="white-space: nowrap;">{{upload.comments}}</td>
<td style="white-space: nowrap;">{{upload.templateName}}</td>
<td style="white-space: nowrap;">{{upload.lastUpdatedByUser}}</td>
<td style="white-space: nowrap;">{{upload.lastUpdateDate}}</td>
<td style="white-space: nowrap;">{{upload.status.statusName}}</td>
<td>
<button class="btn btn-primary btn-xs pull-left" style="margin-bottom: 5px; " ng-hide="upload.status.statusCd === 'NEW' || upload.status.statusCd === 'ERROR'" ng-click="vm.loadStagingPage(upload.dataLoadExecutionId, upload.product, upload.status)">View</button>
<span class="btn btn-primary btn-xs pull-left" style="margin-bottom: 5px; " type="button" ng-click="vm.cancelDataExecution(upload.dataLoadExecutionId)" ng-show="upload.inProgress || upload.status.statusCd === 'ERROR'">Remove</span>
</td>
</tr>
</table>
<div class="text-center">
<ul ng-if="vm.pager.pages.length" class="pagination">
<li ng-class="{disabled:vm.pager.currentPage === 1}">
<a ng-click="vm.setPage(1)">First</a>
</li>
<li ng-class="{disabled:vm.pager.currentPage === 1}">
<a ng-click="vm.setPage(vm.pager.currentPage - 1)">Previous</a>
</li>
<li ng-repeat="page in vm.pager.pages" ng-class="{active:vm.pager.currentPage === page}">
<a ng-click="vm.setPage(page)">{{page}}</a>
</li>
<li ng-class="{disabled:vm.pager.currentPage === vm.pager.totalPages}">
<a ng-click="vm.setPage(vm.pager.currentPage + 1)">Next</a>
</li>
<li ng-class="{disabled:vm.pager.currentPage === vm.pager.totalPages}">
<a ng-click="vm.setPage(vm.pager.totalPages)">Last</a>
</li>
</ul>
</div>
</div>

Answer

You must sort the collection based on $scope.sortType before splicing your current page.

It's also better if you return to page 1 when changing the $scope.sortType

$scope.sortBy = function(keyName){
    var changedSortType = $scope.sortType === keyName;
    $scope.sortType = keyName;
    if(changedSortType){
        $scope.sortReverse = !$scope.sortReverse;
    } else{
        $scope.sortReverse = false;
        setPage(1);
    }

    console.log('Type', $scope.sortType, 'Reverse', $scope.sortReverse);
};

function setPage(page) {
    if (page < 1 || page > vm.pager.totalPages) {
        return;
    }

    // get pager object from service
    vm.pager = PagerService.GetPager(vm.uploads.length, page);

    // get current page of items
    vm.uploads.sort(function(a,b){
        // here you should sort based on $scope.sortType
        var result;
        switch($scope.sortType) {
            case 'uploadDate':
                result = new Date(b.uploadDate).getTime()- new Date(a.uploadDate).getTime();
                break;
            case 'templateName':
                if(a.templateName < b.templateName) result = -1;
                if(a.templateName > b.templateName) result = 1;
                result = 0;
                break;
            // ...
        }
        return result;
    })

    vm.items = vm.uploads.slice(vm.pager.startIndex, vm.pager.endIndex + 1);
}
Comments