<!DOCTYPE html>
<html>
<head>
<link data-require="bootstrap-css@*" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="https://rawgit.com/msrikanth508/uiGridInlineEditPOC/master/Css/ui-grid.css" />
<script src="https://rawgit.com/msrikanth508/uiGridInlineEditPOC/master/Js/vendor/angular.js"></script>
<script src="https://rawgit.com/msrikanth508/uiGridInlineEditPOC/master/Js/vendor/ui-grid.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="app" class="container">
<div class="row col-lg-12" ng-controller="gridCtrl">
<div ui-grid="gridOptions" ui-grid-move-columns="" ui-grid-edit="" ui-grid-row-edit="" ui-grid-selection="" ui-grid-expandable="" class="grid" style="height:800px"></div>
</div>
</body>
</html>
/**
* Created by srikanth on 15-01-2016.
*/
var app = angular.module('app',
[
'ui.grid',
'ui.grid.pagination',
'ui.grid.selection',
'ui.grid.cellNav',
'ui.grid.expandable',
'ui.grid.edit',
'ui.grid.rowEdit',
'ui.grid.saveState',
'ui.grid.resizeColumns',
'ui.grid.pinning',
'ui.grid.moveColumns',
'ui.grid.exporter',
'ui.grid.infiniteScroll',
'ui.grid.importer',
'ui.grid.grouping'
]);
app.filter('genderFilter', function () {
var genderHash = {
'M': 'male',
'F': 'female'
};
return function (input) {
var result;
var match;
if (!input) {
return '';
} else if (result = genderHash[input]) {
return result;
} else if ((match = input.match(/(.+)( \([$\d,.]+\))/)) && (result = genderHash[match[1]])) {
return result + match[2];
} else {
return input;
}
};
});
app.filter('maritalFilter', function () {
var genderHash = {
'M': 'Married',
'S': 'Single'
};
return function (input) {
var result;
var match;
if (!input) {
return '';
} else if (result = genderHash[input]) {
return result;
} else if ((match = input.match(/(.+)( \([$\d,.]+\))/)) && (result = genderHash[match[1]])) {
return result + match[2];
} else {
return input;
}
};
})
app.controller('gridCtrl', ['$scope', '$http', '$log', '$timeout', 'uiGridConstants', '$q', '$interval',
function ($scope, $http, $log, $timeout, uiGridConstants, $q, $interval) {
$scope.gridOptions = {
enableRowSelection: true,
enableSelectAll: true,
selectionRowHeaderWidth: 35,
rowHeight: 35,
showGridFooter: true
};
$scope.convertDate = function (str) {
var date = new Date(str),
mnth = ("0" + (date.getMonth() + 1)).slice(-2),
day = ("0" + date.getDate()).slice(-2);
return [date.getFullYear(), mnth, day].join("/");
};
var expandableScope = {};
$scope.gridOptions = {
enableFiltering:true,
expandableRowTemplate: '<div style="padding:5px;"><div ui-grid="row.entity.subGridOptions[0]" ui-grid-edit ui-grid-row-edit ui-grid-selection style="height:340px;display:inline-block;"></div></div>',
expandableRowHeight: 350,
columnDefs: [
{
name: "",
field:"fake",
cellTemplate: '<div class="ui-grid-cell-contents" >' +
'<button value="Edit" ng-if="!row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.enterEditMode($event)">Delete</button>' +
'<button value="Edit" ng-if="!row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.enterEditMode($event)">Edit</button>' +
'<button value="Edit" ng-if="row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.saveEdit($event)">Update</button>' +
'<button value="Edit" ng-if="row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.cancelEdit($event)">Cancel</button>' +
'</div>',
enableCellEdit: false,
enableFiltering:false,
enableSorting: false,
showSortMenu : false,
enableColumnMenu: false,
},
{ name: 'employeeid', enableCellEdit: true, type: "number" },
{ name: 'managerid', enableCellEdit: true },
//{
// name: 'hiredate', enableCellEdit: true, type: "date", cellFilter: 'date:"yyyy/MM/dd"',
// cellTemplate: '<div class="ui-grid-cell-contents">{{grid.appScope.convertDate(row.entity[col.field])}}</div>'
//},
{
name: 'title', enableCellEdit: true,
cellTemplate: '<div class="ui-grid-cell-contents"><div ng-class="{\'viewr-dirty\' : row.inlineEdit.entity[col.field].isValueChanged }">{{row.entity[col.field]}}</div></div>'
},
// { name: 'birthdate', enableCellEdit: true, type: "date", cellFilter: 'date:"yyyy/MM/dd"' },
{
name: 'maritalstatus', enableCellEdit: true, cellFilter: "maritalFilter",
editableCellTemplate: 'ui-grid/dropdownEditor',
editDropdownValueLabel: 'maritalstatus',
editDropdownOptionsArray: [
{ id: 'M', maritalstatus: 'Married' },
{ id: 'S', maritalstatus: 'Single' }]
},
{
name: 'gender', enableCellEdit: true, cellFilter: 'genderFilter',
editableCellTemplate: 'ui-grid/dropdownEditor',
editDropdownValueLabel: 'gender',
editDropdownOptionsArray: [
{ id: 'M', gender: 'male' },
{ id: 'F', gender: 'female' }]
},
],
enableGridMenu: true,
virtualizationThreshold: 60,
expandableRowScope: {
subGridVariable: 'subGridScopeVariable'
}
}
//$scope.gridOptions.multiSelect = true;
$http.get('https://rawgit.com/msrikanth508/uiGridInlineEditPOC/master/data/employeeData.json')
.success(function (data) {
$scope.gridOptions.data = data.slice(0, 55);; //[data[0], data[1]];
});
$scope.info = {};
$scope.gridOptions.onRegisterApi = function (gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
var msg = 'row selected ' + row.isSelected;
$log.log(msg);
});
gridApi.selection.on.rowSelectionChangedBatch($scope, function (rows) {
var msg = 'rows changed ' + rows.length;
$log.log(msg);
});
gridApi.edit.on.afterCellEdit($scope, function (rowEntity, colDef, newValue, oldValue) {
var selectedRows = $scope.gridApi.selection.getSelectedRows();
if (newValue != oldValue) {
rowEntity.state = "Changed";
//Get column
var rowCol = $scope.gridApi.cellNav.getFocusedCell().col.colDef.name;
angular.forEach(selectedRows, function (item) {
item[rowCol] = rowEntity[rowCol];// $scope.convertDate(rowEntity[rowCol]);
item.state = "Changed";
item.isDirty = false;
item.isError = false;
});
}
});
gridApi.rowEdit.on.saveRow($scope, function (rowEntity) {
// create a fake promise - normally you'd use the promise returned by $http or $resource
//Get all selected rows
var selectedRows = $scope.gridApi.selection.getSelectedRows();
//var rowCol = $scope.gridApi.cellNav.getFocusedCell().col.colDef.name;
var promise = $q.defer();
$scope.gridApi.rowEdit.setSavePromise(rowEntity, promise.promise);
$interval(function () {
if (rowEntity.gender === 'male') {
promise.reject();
} else {
promise.resolve();
}
}, 3000, 1);
})
gridApi.expandable.on.rowExpandedStateChanged($scope, function (row) {
if (row.isExpanded) {
row.entity.subGridOptions =[{
virtualizationThreshold: 60,
columnDefs: [{
name: "",
field:"fake",
cellTemplate: '<div class="ui-grid-cell-contents" >' +
'<button value="Edit" ng-if="!row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.enterEditMode($event)">Delete</button>' +
'<button value="Edit" ng-if="!row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.enterEditMode($event)">Edit</button>' +
'<button value="Edit" ng-if="row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.saveEdit($event)">Update</button>' +
'<button value="Edit" ng-if="row.inlineEdit.isEditModeOn" ng-click="row.inlineEdit.cancelEdit($event)">Cancel</button>' +
'</div>',
enableCellEdit: false,
enableFiltering:false,
enableSorting: false,
showSortMenu : false,
enableColumnMenu: false,
},
{ name: 'firstname' },
{ name: 'middlename' },
{ name: 'lastname' },
// { name: 'emailaddress' }
],
onRegisterApi: function (gridApi) {
$scope.text = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
console.log(row);
});
gridApi.rowEdit.on.saveRow($scope, function (rowEntity) {
// create a fake promise - normally you'd use the promise returned by $http or $resource
//Get all selected rows
var selectedRows = $scope.text.selection.getSelectedRows();
//var rowCol = $scope.gridApi.cellNav.getFocusedCell().col.colDef.name;
var promise = $q.defer();
$scope.text.rowEdit.setSavePromise(rowEntity, promise.promise);
$interval(function () {
if (rowEntity.gender === 'male') {
promise.reject();
} else {
promise.resolve();
}
}, 3000, 1);
})
}
}],
$http.get('https://rawgit.com/msrikanth508/uiGridInlineEditPOC/master/data/employeeContact.json')
.success(function (data) {
row.entity.subGridOptions[0].data = data.slice(0, 45);
});
}
});
};
}]);
angular.module('ui.grid').factory('InlineEdit', ['$interval', '$rootScope', 'uiGridRowEditService',
function ($interval, $rootScope, uiGridRowEditService) {
function inlineEdit(entity, index, grid) {
this.grid = grid;
this.index = index;
this.entity = {};
this.isEditModeOn = false;
this.init(entity);
}
inlineEdit.prototype = {
init: function (rawEntity) {
var self = this;
for (var prop in rawEntity) {
self.entity[prop] = {
value: rawEntity[prop],
isValueChanged: false,
isSave: false,
isCancel: false,
isEdit: false
}
}
},
enterEditMode: function (event) {
event && event.stopPropagation();
var self = this;
self.isEditModeOn = true;
// cancel all rows which are in edit mode
self.grid.rows.forEach(function (row) {
if (row.inlineEdit && row.inlineEdit.isEditModeOn && row.uid !== self.grid.rows[self.index].uid) {
row.inlineEdit.cancelEdit();
}
});
// Reset all the values
for (var prop in self.entity) {
self.entity[prop].isSave = false;
self.entity[prop].isCancel = false;
self.entity[prop].isEdit = true;
}
},
saveEdit: function (event) {
event && event.stopPropagation();
var self = this;
self.isEditModeOn = false;
for (var prop in self.entity) {
self.entity[prop].isSave = true;
self.entity[prop].isEdit = false;
}
uiGridRowEditService.saveRow(self.grid, self.grid.rows[self.index])();
},
cancelEdit: function (event) {
event && event.stopPropagation();
var self = this;
self.isEditModeOn = false;
for (var prop in self.entity) {
self.entity[prop].isCancel = true;
self.entity[prop].isEdit = false;
}
}
}
return inlineEdit;
}]);
/* Styles go here */