Reputation: 5084
I have a ui-grid that I am trying to use to process bulk actions. Items should be removed from the grid once the action is completed. The problem is that the splice only works for every other record. The rest of the code works as expected, but not the splice. Every other record remains on the grid until I F5 to refresh the page (the backend functions actually delete the rows from the database - I was using splice to get a quicker view of the correct data without having to refresh the grid data once the database procedures complete).
Here is my controller code:
$scope.gridOptions = {
columnDefs: [
{
field: 'dteDateReleaseRequestedByCompany', displayName: 'Requested Date'
},
{
field: 'vchCompanyName', displayName: 'Company Name',
cellTemplate: '<div style="text-decoration:underline;color:blue;text-align:left;cursor:pointer" ng-click="grid.appScope.rowClick(row)">{{COL_FIELD}}</div>'
},
{
field: 'CompanyID', width: 110, displayName: 'Company ID', visible:false
},
{ field: 'vchOprCity', displayName: 'City' },
{ field: 'vchOprStateVchID', displayName: 'State' },
{
field: 'dteExpiresWithGracePeriod', displayName: 'Subscription', headerCellClass: 'center',
cellTemplate: '<div style="text-align:center"><span ng-bind-html="row.entity[col.field] | getSubscription | trustedhtml"></span></div>'
},
{
field: 'Action', displayName: 'Release Action',
cellTemplate: '<div class="btn-group" ng-init="row.entity.Action=0"><input ng-model="row.entity.Action" type="radio" value="0" style="width:20px"> None <input ng-model="row.entity.Action" type="radio" value="1" style="width:20px"> Accept <input ng-model="row.entity.Action" type="radio" value="2" style="width:20px"> Decline</div>'
},
],
showGridFooter: false,
//enableFiltering: true,
enableSorting: false,
paginationPageSizes: [20, 40, 60],
paginationPageSize: 20,
enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
enableGridMenu: true,
exporterCsvFilename: 'PendingReleases.csv',
exporterPdfDefaultStyle: { fontSize: 9 },
exporterPdfTableStyle: { margin: [10, 10, 10, 10] },
exporterPdfTableHeaderStyle: { fontSize: 10, bold: true, italics: true, color: 'red' },
exporterPdfHeader: { text: "Pending Release Requests", style: 'headerStyle' },
exporterPdfFooter: function (currentPage, pageCount) {
return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' };
},
exporterPdfCustomFormatter: function (docDefinition) {
docDefinition.styles.headerStyle = { fontSize: 22, bold: true, alignment: 'center' };
docDefinition.styles.footerStyle = { fontSize: 10, bold: true, alignment: 'center' };
return docDefinition;
},
exporterPdfOrientation: 'landscape',
exporterPdfPageSize: 'LETTER',
exporterPdfMaxGridWidth: 500,
exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
}
};
$scope.process = function () {
for (i = 0; i < $scope.gridOptions.data.length; i++)
{
var id = $scope.gridApi.grid.renderContainers.body.visibleRowCache[i].entity.CompanyID;
var action = $scope.gridApi.grid.renderContainers.body.visibleRowCache[i].entity.Action;
var index = i;
if(action ==1)
{
$scope.gridOptions.data.splice(index, 1);
accept(id, index);
}
if(action == 2)
{
$scope.gridOptions.data.splice(index, 1);
decline(id, index);
}
}
};
function accept(id, index) {
contractorService.acceptRelease(id);
};
function decline(id, index) {
contractorService.declineRelease(id);
};
Here is my HTML:
@{
ViewBag.Title = "ManagePendingReleases";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/app/Contractor/ContractorCtrl.js"></script>
<script src="~/Scripts/app/Contractor/contractorService.js"></script>
<style>
.ui-grid-header-cell {
position: relative;
box-sizing: border-box;
color: black;
background-color: #cfe7f1;
border-right: 1px solid;
border-color: #cfe7f1;
display: table-cell;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
width: 0;
}
</style>
<div ng-app="myModule" ng-controller="ContractorCtrl">
<div class="panel panel-primary">
<div class="panel-heading" >Manage Pending Releases</div>
<div class="panel-body" style="padding:0px">
<div ui-grid="gridOptions" class="grid" ng-style="{height: (gridOptions.data.length*30)+32+'px'}" ui-grid-exporter ui-grid-auto-resize></div>
</div>
</div>
<div class="pull-right">
<button type="button" class="btn btn-primary" ng-click="process()">Process Actions</button>
</div>
</div>
Here is what my grid looks like:
When the Process Actions button is clicked, it is supposed to iterate through the rows and find which Action should happen on each record in the database. When I step through the code it looks like the splice works for each record, but every other one remains on the grid. Can anyone tell why I am getting this behavior?
Any assistance is greatly appreciated!
Upvotes: 0
Views: 1749
Reputation: 5681
You are using the length
of array in for
loop on which you are doing splice
which in turn is reducing also you are using index
to remove item, but splice
is reducing the array, so index
also needs to change.
So the closest plausible answer is, use delete
instead of splice as delete
doesn't change the index
.
delete $scope.gridOptions.data[index]
Instead of
$scope.gridOptions.data.splice(index, 1);
Upvotes: 1
Reputation: 2687
Look this example. Notice how is excluded. The object of the index is obtained through a indexOf
var app = angular.module('app', ['ngTouch', 'ui.grid']);
app.controller('MainCtrl', ['$scope', '$log', function($scope, $log) {
$scope.deleteRow = function(row) {
var index = $scope.gridOptions.data.indexOf(row.entity);
$scope.gridOptions.data.splice(index, 1);
};
$scope.gridOptions = {};
$scope.gridOptions.columnDefs = [{
name: 'firstName'
}, {
name: 'lastName'
}, {
name: 'Delete',
cellTemplate: '<button class="btn primary" ng-click="grid.appScope.deleteRow(row)">Delete</button>'
}];
$scope.gridOptions.data = [{
"firstName": "Cox",
"lastName": "Carney",
"company": "Enormo",
"employed": true
}, {
"firstName": "Lorraine",
"lastName": "Wise",
"company": "Comveyer",
"employed": false
}, {
"firstName": "Nancy",
"lastName": "Waters",
"company": "Fuelton",
"employed": false
}];
}]);
<!doctype html>
<html ng-app="app">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-touch.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-animate.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
<script src="http://ui-grid.info/release/ui-grid.js"></script>
<link rel="stylesheet" href="http://ui-grid.info/release/ui-grid.css" type="text/css">
<link rel="stylesheet" href="main.css" type="text/css">
</head>
<body>
<div ng-controller="MainCtrl">
<div ui-grid="gridOptions" class="grid"></div>
</div>
<script src="app.js"></script>
</body>
</html>
Upvotes: 0