Marking modified cell/row $dirty in ui-grid 3.0 - angularjs

I have a plunker that is ALMOST just like it is supposed to be. I have to add one requirement to it and I can't find it in the docs or on google.
The grid is set (to be like Excel) where you can begin to edit and the tab key will move from row to row. I need SOME WAY to mark a cell as $dirty if a change was made.
The requirement is an update button to save the ENTIRE grid if there were any changes (again, he wants it just like Excel).
Here's the plunker.
The issue: double-click an editable cell (name, status, M, T, W, H, F) and the tab key will cycle through the entire grid. If a cell value is changed, I need a way to mark it as dirty!
CODE:
(index.html)
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="lodash.js#*" data-semver="3.10.0" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.js"></script>
<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>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" />
<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">
<strong>Data Length:</strong>
{{ gridOptions.data.length | number }}
<br />
<strong>Last Cell Edited:</strong>
{{msg.lastCellEdited}}
<br />
<div ui-grid="gridOpts" ui-grid-edit="" ui-grid-cellnav="" class="grid"></div>
</div>
<script src="app.js"></script>
</body>
</html>
(app.js)
var app = angular.module('app', ['ngTouch', 'ui.grid', 'ui.grid.edit', 'ui.grid.cellNav']);
app.controller('MainCtrl', ['$scope', '$http', function($scope, $http) {
$scope.$scope = $scope;
$scope.pending_view = true;
$scope.gridOpts = {
enableCellEditOnFocus: true,
enableGridMenu: true
};
var dataset = [{
vote_pending: false,
has_comment: false,
is_stale: false,
is_watched: false,
disbursement_issue: false,
name: "Jon",
status: 1,
M: 9,
T: 9,
W: 9,
H: 9,
F: 4
}, {
vote_pending: true,
has_comment: true,
is_stale: true,
is_watched: true,
disbursement_issue: true,
name: "Robbie",
status: 1,
M: 8,
T: 8,
W: 8,
H: 8,
F: 8
}, {
vote_pending: false,
has_comment: false,
is_stale: true,
is_watched: true,
disbursement_issue: false,
name: "Brad",
status: 1,
M: 8,
T: 8,
W: 8,
H: 8,
F: 8
}, {
vote_pending: false,
has_comment: true,
is_stale: false,
is_watched: false,
disbursement_issue: false,
name: "Paul",
status: 1,
M: 8,
T: 8,
W: 8,
H: 8,
F: 8
}, {
vote_pending: false,
has_comment: true,
is_stale: false,
is_watched: true,
disbursement_issue: false,
name: "Billie",
status: 2,
M: 8,
T: 4,
W: 4,
H: 4,
F: 0
}];
$scope.getTotal=function(a, b, c, d, e) {
return a+b+c+d+e;
};
$scope.gridweek = true;
var sByName = _.sortBy(dataset, 'name');
var sPending = _.sortByAll(dataset, ['is_watched', 'vote_pending', 'has_comment', 'disbursement_issue', 'is_stale']).reverse();
$scope.gridOpts.data = sPending;
$scope.pendingSort = function() {
if($scope.gridOpts.data === sByName) {
$scope.gridOpts.data = sPending;
} else if($scope.gridOpts.data === sPending) {
$scope.gridOpts.data = sByName;
}
};
$scope.gridOpts.columnDefs = [
{
name: 'id',
enableCellEdit: false,
enableColumnMenu: false,
headerCellTemplate: 'pending.hdr.html',
cellTemplate: 'pending.icons.html',
width: '15%'
},
{
name: 'name',
enableCellEdit: true,
displayName: 'Name',
cellClass: 'text-left cBlue',
headerCellClass: 'text-center bGreen',
enableColumnMenu: false,
width: '12%'
},
{
name: 'status',
enableCellEdit: true,
displayName: 'Status',
editableCellTemplate: 'ui-grid/dropdownEditor',
enableColumnMenu: false,
cellClass: 'text-left cBlue',
cellFilter: 'mapStatus',
headerCellClass: 'text-center bGreen',
editDropdownValueLabel: 'status',
editDropdownOptionsArray: [
{
id: 1,
status: 'FT'
},
{
id: 2,
status: 'PT'
}
],
visible: $scope.gridweek,
width: '14%'
},
{
name: 'M',
enableCellEdit: true,
displayName: 'M',
enableColumnMenu: false,
type: 'number',
cellFilter: 'number:1',
cellClass: 'text-right cBlue',
headerCellClass: 'text-center bGreen',
width: '8%'
},
{
name: 'T',
enableCellEdit: true,
displayName: 'T',
enableColumnMenu: false,
type: 'number',
cellFilter: 'number:1',
cellClass: 'text-right cBlue',
headerCellClass: 'text-center bGreen',
width: '8%'
},
{
name: 'W',
enableCellEdit: true,
displayName: 'W',
enableColumnMenu: false,
type: 'number',
cellFilter: 'number:1',
cellClass: 'text-right cBlue',
headerCellClass: 'text-center bGreen',
width: '8%'
},
{
name: 'H',
enableCellEdit: true,
displayName: 'H',
enableColumnMenu: false,
type: 'number',
cellFilter: 'number:1',
cellClass: 'text-right cBlue',
headerCellClass: 'text-center bGreen',
width: '8%'
},
{
name: 'F',
enableCellEdit: true,
displayName: 'F',
enableColumnMenu: false,
type: 'number',
cellFilter: 'number:1',
cellClass: 'text-right cBlue',
headerCellClass: 'text-center bGreen',
width: '8%'
},
{
field: 'total',
enableCellEdit: false,
displayName: 'Total',
enableColumnMenu: false,
type: 'number',
cellFilter: 'number:1',
cellClass: 'text-right',
headerCellClass: 'text-center bGreen',
cellTemplate: 'total.tmpl.html',
width: '10%'
}
];
$scope.msg = {};
$scope.gridOpts.onRegisterApi = function(gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.edit.on.afterCellEdit($scope, function(rowEntity, colDef, newValue, oldValue) {
$scope.msg.lastCellEdited = 'edited row id:' + rowEntity.id + ' Column:' + colDef.name + ' newValue:' + newValue + ' oldValue:' + oldValue;
$scope.$apply();
});
};
}])
.filter('mapStatus', function() {
var statusHash = {
1: 'Full Time',
2: 'Part Time'
};
return function(input) {
if (!input) {
return '';
} else {
return statusHash[input];
}
};
});

I create a dirty flag on scope:
$scope.dirty = false;
and I update the function what monitors editions:
gridApi.edit.on.afterCellEdit($scope, function(rowEntity, colDef, newValue, oldValue) {
$scope.$apply(function(scope) {
scope.dirty = true;
});
});
please see on plunkr: http://plnkr.co/edit/bSTXqp7wzLDL74rN3PII?p=preview

Try to adding a thin layer on top of the dataset to track record dirty status.
var records = [];
angular.forEach(dataset, function (rawdata) {
var record = {};
//Track changed attrs,
//keys are the changed properties and
//values are an array of values [origValue, newValue].
record.changedAttrs = {};
//record dirty status
Object.defineProperty(record, 'isDirty', {
get: function () {
return Object.getOwnPropertyNames(record.changedAttrs).length > 0;
}
});
angular.forEach(rawdata, function (value, key) {
Object.defineProperty(record, key, {
get: function () {
return rawdata[key];
},
set: function (value) {
var origValue = record.changedAttrs[key] ?
record.changedAttrs[key][0] : rawdata[key];
if(value !== origValue) {
record.changedAttrs[key] = [origValue, value];
} else {
delete record.changedAttrs[key];
}
rawdata[key] = value;
}
})
});
records.push(record);
});
Here is the plunker. Providing a custom row template and an extra line of css, the row bg color will change to yellow when the row is dirty.
rowTemplate: '<div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.uid" ' +
'ui-grid-one-bind-id-grid="rowRenderIndex + \'-\' + col.uid + \'-cell\'" ' +
'class="ui-grid-cell" ng-class="{ \'ui-grid-row-header-cell\': col.isRowHeader , \'row-dirty\': row.entity.isDirty}" ' +
'role="{{col.isRowHeader ? \'rowheader\' : \'gridcell\'}}" ui-grid-cell></div>'
css
.ui-grid-cell.row-dirty {
background-color: yellow !important;
}

In addition to merlins answer.
His css style didn't work for me. What I did is:
.ui-grid-row-dirty div {
background-color: yellow !important;
}
which will set every cells (within the row) bg color to yellow.

Related

AngularJs, display function result in ui-grid

I am trying to sum two columns in a function then display their result in the ui grid. any ideas about how to do this, then save the ui grid content in the database?
see the picture
so in my case : a and b are binded from the database, while I want angularjs to calculate their sum and add it in the column "Quantite reelle".
this is my grid code $scope.gridOptions = {
showGridFooter: true,
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
gridApi.core.on.renderingComplete($scope, function () {
$timeout(function () {
var gridBodyElem = document.getElementById(gridApi.grid.id + '-grid-container');
gridApi.grid.element.on('mouseup', handleGridClick);
});
});
}
};
$scope.gridOptions.columnDefs = [
{ name: 'Num', enableHiding: false, enableColumnMenu: false, enableCellEdit: false, width: '5%' },
{ name: 'CodeArticle', enableHiding: false, enableColumnMenu: false, displayName: 'Code Article ', width: '10%' },
{ name: 'Ref', enableHiding: false, enableColumnMenu: false, displayName: 'Référence ', width: '10%' },
{ name: 'Designation', enableHiding: false, enableColumnMenu: false, displayName: 'Désignation ', width: '30%' },
{ name: 'Stock', enableHiding: false, enableColumnMenu: false, displayName: "Qté théorique (a)", width: '13%' },
{ name: "ajust", enableHiding: false, enableColumnMenu: false, displayName: "Ajustement (b)", width: '12%' },
{ name: "sum", enableHiding: false, enableColumnMenu: false, displayName: "Quantité Réelle(a+b)", width: '14%' },
{ name: "motif", enableHiding: false, enableColumnMenu: false, displayName: "Motif", width: '20%' }
];
`
thank you guys.
You need to set column field property to expression.
$scope.gridOptions.columnDefs = [
{ name: "sum", enableHiding: false, enableColumnMenu: false, field:'CalculateSum(a,b)', displayName: "Quantité Réelle(a+b)", width: '14%' }
];
Here a & b are respective column names.
You can try this:
$scope.gridApi.grid.columns[column a].getAggregationValue() +
$scope.gridApi.grid.columns[column b].getAggregationValue()
$scope.gridOptions.columnDefs = [
{ name: 'Num', enableHiding: false, enableColumnMenu: false, enableCellEdit: false, width: '5%' },
{ name: 'CodeArticle', enableHiding: false,field:'CodeArticle', enableColumnMenu: false, displayName: 'Code Article ', width: '10%' },
{ name: 'Ref', enableHiding: false,enableColumnMenu: false, displayName: 'Référence ', width: '10%' },
{ name: 'Designation', enableHiding: false, enableColumnMenu: false, displayName: 'Désignation ', width: '30%' },
{ name: 'Stock', enableHiding: false,field:'Stock', enableColumnMenu: false, displayName: "Qté théorique (a)", width: '13%' },
{ name: "ajust", enableHiding: false, field: 'ajust', enableColumnMenu: false, displayName: "Ajustement (b)", width: '12%' },
{ name: "sum", enableHiding: false, enableColumnMenu: false, field: 'CalculateSum(ajust,Stock)', displayName: "Quantité Réelle(a+b)", width: '14%' },
{ name: "motif", enableHiding: false, enableColumnMenu: false, displayName: "Motif", width: '20%' }
];
$scope.CalculateSum = function (ajust, Stock) {
return ajust + Stock;
};
Following Tutorial: 323 More Binding examples I created a Plunker, using a filter calculateSum to calculate the sum of both fields.
angular.module('app', ['ngAnimate', 'ngTouch', 'ui.grid'])
.controller('MainCtrl', MainCtrl)
.filter('calculateSum', function () {
return function (input, a, b) {
return input[a]+input[b];
};
});;
MainCtrl.$inject = ['$http', 'uiGridConstants'];
function MainCtrl($http, uiGridConstants) {
var vm = this;
vm.gridOptions = {
enableFiltering: true,
onRegisterApi: function(gridApi){
vm.gridApi = gridApi;
},
columnDefs: [
{ field: 'name'},
{ field: 'num1'},
{ field: 'num2'},
{ name: 'sum', field: uiGridConstants.ENTITY_BINDING, cellFilter: 'calculateSum:"num1":"num2"' }
]
};
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500_complex.json')
.then(function(response) {
response.data.forEach(function(row){
row.num1 = row.age;
row.num2 = row.age*2;
});
vm.gridOptions.data = response.data;
});
}

How to add confirm box for ui-grid check box?

How to add confirm box for ui-grid check box ?
The defaultYn value, tried to add a confirm message before making a server call.
vm.gridOptions1 = {
enableColumnResizing: true,
enableAutoResizing: false,
enableHorizontalScrollbar : 1,
enableRowSelection: true,
enableRowHeaderSelection: false,
appScopeProvider: vm.myAppScopeProvider,
// rowTemplate: "<div ng-dblclick=\"grid.appScope.openOtherPavacce(row)\" ng-repeat=\"(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name\" class=\"ui-grid-cell\" ng-class=\"{ 'ui-grid-row-header-cell': col.isRowHeader }\" ui-grid-cell></div>",
columnDefs: [
{field: 'jobVaccinationPK.screeningTypeMast.screeningType', displayName: 'Screening type',type: 'text',width: '27%', enableCellEdit: false},
{field: 'jobVaccinationPK.jobCategoryTypeMast.jobCategoryName', displayName: 'Job Category',width: '27%', enableCellEdit: false},
{field: 'jobVaccinationPK.vaccinationMast.vaccinationName', displayName: 'Vaccination', width: '27%', enableCellEdit: false},
{field: 'defaultYn', displayName: 'DefaultYn',width: '10%' , cellTemplate: '<input type="checkbox" ng-model="row.entity.defaultYn" ng-really-message="Are you sure ?" ng-really-click="grid.appScope.updateRow(row)" ng-true-value="\'Y\'" ng-false-value="\'N\'">'},
{
//field:'',
name: 'Action',
cellTemplate: '<button class="btn btn-primary-joli" ng-click="grid.appScope.deleteRow(row)">Delete</button>',width: '9%'
}
],
onRegisterApi: function(gridApi) {
vm.gridApi = gridApi;
var cellTemplate='<div style= \"height:100px \" class=\"ui-grid-row-header-cell ui-grid-expandable-buttons-cell\"><div class=\"ui-grid-cell-contents\"><i ng-class=\"{ \'glyphicon glyphicon-calendar \' : row.entity.visitMasts[0].orderses.length !== 0 }\" ng-click=\"grid.appScope.showPopup(row)\" style=\"color: rgb(212, 106, 64)\";></i></div></div>'; //
vm.gridApi.core.addRowHeaderColumn( { name: 'rowHeaderCol', displayName: '', width: 30, cellTemplate: cellTemplate , headerTooltip: 'Click icon to see details'} );
vm.gridOptions1.multiSelect = false;
vm.gridOptions1.modifierKeysToMultiSelect = false;
vm.gridOptions1.noUnselect = true;
}
};

newRawData.forEach is not a function in ui-grid

I search for this error but not able to fix it.Am new to angular.Dont know exactly whats going wrong.
Html:
<div class="row gridContainer" ng-controller="tripsGridController">
<div ui-i18n="{{::selectedLanguageName}}">
<div ui-grid="gridOptionsTrips" ui-grid-selection ui-grid-resize-columns ui-grid-move-columns ></div>
</div>
</div>
Angular code:
$scope.gridOptionsTrips = {};
$scope.gridDataSourceTrips = [];
var ROW_HEIGHT = 30;
// to show data on Grid
$scope.gridOptionsTrips = {
enableRowSelection: true,
enableRowHeaderSelection: true,
enableSorting: true,
multiSelect: false,
rowHeight: ROW_HEIGHT,
virtualizationThreshold: 10,
fastWatch: false,
enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
data: 'gridDataSourceTrips',
appScopeProvider: $scope,
showColumnMenu: true,
enableSelectAll: false,
noUnselect: true,
enableCellSelection: true,
rowTemplate: '<div ng-click=\"grid.appScope.onTripsGridRowClick(row)\" ng-repeat=\"(colRenderIndex, col) in colContainer.renderedColumns track by col.uid\" class=\"ui-grid-cell\" ng-class=\"{ \'ui-grid-row-header-cell\': col.isRowHeader }\" ui-grid-cell></div>'
};
$scope.onTripsGridRowClick = function (row) {
$scope.gridApi.selection.selectRow(row.entity);
};
$scope.gridColDefsTrips = function () {
var idTemplate = '<div></div>';
var sTemplate = '<div></div>';
var speedTemplate = '<div></div>';
var directionTemplate = '<div></div>';
var timeTemplate = '<div></div>';
var kmCounterTemplate = '<div></div>';
var driverNameTemplate = '<div></div>';
return [
{ name: "CARDRIVER", displayName: "CARDRIVER", field: 'UserId', cellTemplate: idTemplate, enableColumnMenu: false, headerCellFilter: 'translate', width: 150, showInColumnFilter: true },
{ name: 'STARTEND', displayName: 'STARTEND', field: 'Departure.DateTime', cellTemplate: idTemplate, width: 70, enableColumnMenu: false, headerCellFilter: 'translate', showInColumnFilter: true },
{ name: 'STARTEND', displayName: 'STARTEND', field: 'Destination.DateTime',cellTemplate: idTemplate, enableColumnMenu: false, headerCellFilter: 'translate', width: 80, showInColumnFilter: true },
{ name: 'TRIPLENGTH', displayName: 'TRIPLENGTH', field: 'Distance', cellTemplate: idTemplate, enableColumnMenu: false, headerCellFilter: 'translate', width: 150, showInColumnFilter: true }
];
};
$scope.gridDataSourceTrips = tripsDetailsService.GetAllTripsByWeek('2014-01-10', '2014-01-14', 1, 20);
$scope.gridOptionsTrips.columnDefs = $scope.gridColDefsTrips();

Using NgMask in a AngularGrid table dynamically

I'd like to use NgMask in an angularGrid table to edit fields, but I don't know how.
The information from table cames from PHP and fields change depending on the search.
How could I implement it?
Link to NgMask: http://candreoliveira.github.io/bower_components/angular-mask/examples/index.html#/
The angularGrid code with a example:
var module = angular.module("example", ["angularGrid"]);
module.controller("exampleCtrl", function($scope, $timeout) {
var columnDefs = [
{displayName: "Default String", field: "defaultString", width: 150, editable: true, volatile: true, cellRenderer: cellRenderer, newValueHandler: numberNewValueHandler},
{displayName: "Upper Case Only", field: "upperCaseOnly", width: 150, volatile: true, editable: true, cellRenderer: cellRenderer, newValueHandler: numberNewValueHandler},
{displayName: "Number", field: 'number', width: 150, volatile: true, editable: true, cellRenderer: cellRenderer, newValueHandler: numberNewValueHandler},
{displayName: "Custom With Angular", field: "setAngular", width: 175, editable: true, volatile: true, cellRenderer: cellRenderer, newValueHandler: numberNewValueHandler},
{displayName: "Custom No Angular", field: "setNoAngular", width: 175, cellRenderer: cellRendererLink, cellTemplate: '{{row.entity[col.field]}}'
}];
var data = [
{ID:111, defaultString: 'APPLE', upperCaseOnly: 'APPLE', number: 11, setAngular: 'AAA', setNoAngular: 'AAA'},
{ID:222, defaultString: 'ORANGE', upperCaseOnly: 'ORANGE', number: 22, setAngular: 'BBB', setNoAngular: 'BBB'},
{ID:333, defaultString: 'BANANA', upperCaseOnly: 'BANANA', number: 33, setAngular: 'CCC', setNoAngular: 'CCC'},
{ID:444, defaultString: 'PEAR', upperCaseOnly: 'PEAR', number: 44, setAngular: 'DDD', setNoAngular: 'DDD'}
];
$scope.gridOptions = {
columnDefs: columnDefs,
rowData: data,
enableCellEditOnFocus: true,
enableSorting: true,
enableFilter: true,
};
});
I dont want to use ui-grid or something, just angularGrid and some mask.
You could dynamically create the columnsDef and specify in the editableCellTemplate your required mask.
The code works like this:
Get the data from server
Create fields from data keys
Extend the keys with the mappingObj.
Set mappedData to the scope, so ngGrid updates.
You could probably also add a validation property to your data and use this to create the column definition.
The uppercase mask is not working properly. I don't know what's wrong. If you enter some uppercase chars and then quickly a lowercase char it will be possible to enter.
Please have a look at the demo below or in this plunkr.
// main.js
var app = angular.module('myApp', ['ngGrid', 'ngMask']);
app.controller('MyCtrl', function($scope, $http) {
/*$scope.myData = [{name: "Moroni", age: 50, personalId: '123-234-445'},
{name: "Tiancum", age: 43, personalId: '223-234-445'},
{name: "Jacob", age: 27,personalId: '323-234-445'},
{name: "Nephi", age: 29, personalId: '423-234-445'},
{name: "Enos", age: 34, personalId: '523-234-445'}];
*/
$scope.myData = [];
$scope.colDef = [];
/*
var columnDef = [{ field: 'name', displayName: 'First Name', width: 90 },
{ field: 'age', width:50, cellClass: 'ageCell', headerClass: 'ageHeader',
editableCellTemplate: '<input type="number" ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" />' },
{ field: 'personalId', displayName: 'ID', width: 150, editableCellTemplate: '<input ng-model="COL_FIELD" ng-input="COL_FIELD" mask="255-255-255"/>'}];
*/
$http.jsonp('http://www.mocky.io/v2/559304993c82b23c10eea6a6?callback=JSON_CALLBACK').then(function(response){
//'http://www.mocky.io/v2/5592fc513c82b22510eea699?callback=JSON_CALLBACK').then(function (response){
//$scope.colDef=response.data;//["ColumnName":data.something]
var data = response.data,
keys = [],
curKeys = '',
mappedData,
mappingObject = {
/*
name: {
displayName: 'First Name',
width: 90
},*/
age: {
width: 50,
cellClass: 'ageCell',
headerClass: 'ageHeader',
editableCellTemplate: '<input type="number" ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" />'
},
personalId: {
displayName: 'ID',
width: 150,
editableCellTemplate: '<input ng-model="COL_FIELD" ng-input="COL_FIELD" mask="255-255-255"/>'
},
upperCaseOnly: {
displayName: 'uper case only property',
width: 100,
editableCellTemplate: '<input ng-model="COL_FIELD" ng-input="COL_FIELD" mask="A" repeat="10" limit="false" restrict="reject"/>'
}
};
$scope.myData = data;
data.forEach(function(row, index) {
curKeys = Object.keys(row);
console.log(curKeys);
curKeys.forEach(function(key) {
if (keys.indexOf(key) == -1)
keys.push(key);
});
});
mappedData = keys.map(function(key){
return angular.extend({field: key}, mappingObject[key]);
});
console.log(mappedData);
$scope.colDef = mappedData;
});
$scope.filter = {filterText:''};
$scope.gridOptions = {
data: 'myData',
enableFiltering: true,
filterOptions: $scope.filter,
showFilter: true,
enableCellEditOnFocus: true, //enables the editor on a single click, if you use enableCellEdit: true you would have to doubleclick
columnDefs: 'colDef'//columnDef
};
$scope.showRowCount = function() {
console.log($scope.gridOptions.ngGrid.filteredRows.length);
}
});
/*style.css*/
.gridStyle {
border: 1px solid rgb(212,212,212);
width: 400px;
height: 300px
}
<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
<link rel="stylesheet" type="text/css" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular.js"></script>
<script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/candreoliveira/ngMask/master/dist/ngMask.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body ng-controller="MyCtrl">
<input ng-model="filter.filterText"/>
<div class="gridStyle" ng-grid="gridOptions"></div>
currently visible items: {{gridOptions.ngGrid.filteredRows.length}}
</body>
</html>

Force edit mode for individual rows ui grid 3.0

I have a need to have more than 1 cell editable at a time. I have an edit button per row from a columnDef I added. I would like the edit button to allow as many columns as I want editable based on a condition.
When I set a condition like below, this only checks if this condition is met when I double click the cell.
$scope.gridOptions.cellEditableCondition: function(scope){
scope.row.entity.name = "Jay"
}
Is there any way to invoke the grids 'Edit Mode' on an entire row for all cells that meet the condition?
If you Want to apply condition only on some columns of your grid below is the example:
columnDefs: [
// default
{ field: 'FileName', displayName: 'FileName', enableCellEdit: false, cellTooltip: true },
{ field: 'RootFilePath', displayName: 'RelativePath', cellTooltip: true, enableCellEdit: false },
{ name: 'File Properties', enableFiltering: false, cellTemplate: '<center><div>' + 'View' + '</div></center>' },
{ field: 'IsEditable', displayName: 'Editable/NonEditable', headerTooltip: true, enableCellEdit: false },
{ field: 'HttpPath', displayName: 'HttpPath', enableCellEdit: true, cellTooltip: true },
{ name: 'Generate HttpPath', cellTemplate: '<center><input type="checkbox" ng-model="row.entity.ToGenerateHttpPath", ng-checked="row.entity.ToGenerateHttpPath", ng-click="grid.appScope.generateHttpPath(row.entity.ToGenerateHttpPath,row.entity.HttpPath)"></center>', enableFiltering: false, headerTooltip: true, enableCellEdit: false },
{field: 'TopLevelSchemaComments', displayName: 'Top Level\n Comments', headerTooltip: true, enableFiltering: true, cellTooltip: true,
cellEditableCondition: function ($scope) {
// put your enable-edit code here, using values from $scope.row.entity and/or $scope.col.colDef as you desire
return $scope.row.entity.IsEditable; // in this example, we'll only allow editable rows to be edited
},
},
{ name: 'Remove', enableFiltering: false, cellTemplate: '<div><center><button ng-disabled ="!(row.entity.IsEditable)" class="fa fa-trash-o" ng-click="grid.appScope.Remove(row.entity.XsdSchemaID,row.entity.XbrlLinkbaseID)"></button></center></div>', enableCellEdit: false }, ]
if you want the enitre grid's all the column to follow the same condition then place the condition only in gridOptions before columnDefs. Below is the Example:
$scope.gridOptions1 = {
enableFiltering: true,
data: [],
showGridFooter: true,
enableGridMenu: true,
enableColumnResizing: true,
cellEditableCondition: function ($scope) {
// put your enable-edit code here, using values from $scope.row.entity and/or $scope.col.colDef as you desire
return $scope.row.entity.IsEditable; // in this example, we'll only allow editable rows to be edited
},
columnResize: true,
columnDefs: [
// default
{ field: 'FileName', displayName: 'FileName', cellTooltip: true },
{ field: 'RootFilePath', displayName: 'RelativePath', cellTooltip:true},
{ name: 'File Properties', enableFiltering: false, cellTemplate: '<center><div>' + 'View' + '</div></center>' },
{ field: 'IsEditable', displayName: 'Editable/NonEditable', headerTooltip: true},
{ field: 'HttpPath', displayName: 'HttpPath', cellTooltip: true },
{ name: 'Generate HttpPath', cellTemplate: '<center><input type="checkbox" ng-model="row.entity.ToGenerateHttpPath", ng-checked="row.entity.ToGenerateHttpPath", ng-click="grid.appScope.generateHttpPath(row.entity.ToGenerateHttpPath,row.entity.HttpPath)"></center>', enableFiltering: false, headerTooltip: true, enableCellEdit: false },
{field: 'TopLevelSchemaComments', displayName: 'Top Level\n Comments', headerTooltip: true, enableFiltering: true, cellTooltip: true},
{ name: 'Remove', enableFiltering: false, cellTemplate: '<div><center><button ng-disabled ="!(row.entity.IsEditable)" class="fa fa-trash-o" ng-click="grid.appScope.Remove(row.entity.XsdSchemaID,row.entity.XbrlLinkbaseID)"></button></center></div>', enableCellEdit: false }, ]
}
I've been working on a similar issue, which differs mainly in that rows are editable based on a flag in the data (rather than a stand-alone button as you have). You can see it in action here; here's the code in case that link breaks.
index.html:
<!DOCTYPE html>
<html ng-app="rowLockDemo">
<head>
<meta charset="utf-8" />
<title>Angular UI-Grid row-lock/cell-edit demo</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
<script src="http://ui-grid.info/release/ui-grid-unstable.js"></script>
<link rel="stylesheet" href="http://ui-grid.info/release/ui-grid-unstable.css" type="text/css">
</head>
<body>
<div ng-controller="MainCtrl">
<div ui-grid="gridOptions" ui-grid-edit ui-grid-cellNav class="grid"></div>
<strong ng-show="msg.lastCellEdited">Last Edit:</strong> {{msg.lastCellEdited}}
</div>
<script src="app.js"></script>
</body>
</html>
app.js:
var app = angular.module('rowLockDemo', ['ui.grid', 'ui.grid.edit', 'ui.grid.cellNav']);
app.controller('MainCtrl', function($scope, $http) {
$scope.msg = {};
$scope.gridOptions = {
enableCellEdit: false, // set all columns to non-editable unless otherwise specified; cellEditableCondition won't override that
enableCellEditOnFocus: true, // set any editable column to allow edit on focus
cellEditableCondition: function($scope) {
// put your enable-edit code here, using values from $scope.row.entity and/or $scope.col.colDef as you desire
return $scope.row.entity.isActive; // in this example, we'll only allow active rows to be edited
}
};
$scope.gridOptions.columnDefs = [
{name: 'isActive', displayName: 'Edit Status', enableColumnMenu: false, cellTemplate: 'cellTemplate_lock.html'}, // displays isActive status as a button and allow toggling it
{name: 'name', enableCellEdit: true}, // editing is enabled for this column, but will be overridden per row by cellEditableCondition
{name: 'company', enableCellEdit: true} // same for this column
];
$scope.gridOptions.onRegisterApi = function(gridApi) {
$scope.gridApi = gridApi;
gridApi.edit.on.afterCellEdit($scope, function(rowEntity, colDef, newValue, oldValue) {
$scope.msg.lastCellEdited = 'ID: ' + rowEntity.id + ', Column: ' + colDef.name + ', New Value: ' + newValue + ', Old Value: ' + oldValue;
$scope.$apply();
});
};
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500_complex.json').success(function(data) {
$scope.gridOptions.data = data;
});
})
cellTemplate_lock.html:
<!--
Button shows current state (locked/unlocked); clicking it toggles the state.
Initial button state is set by retrieved read-only grid data; lock state is not persisted.
-->
<button ng-click="row.entity.isActive = !row.entity.isActive" ng-model="row.entity.isActive" style="{{row.entity.isActive ? 'background-color: lightgreen' : ''}}">
{{ row.entity.isActive ? 'Unlocked' : 'Locked' }}
</button>

Resources