Skip to content

Commit d17fb5a

Browse files
committed
Start editing on keydown when using cellNav and edit together. update docs.
1 parent 1538c9f commit d17fb5a

File tree

3 files changed

+171
-94
lines changed

3 files changed

+171
-94
lines changed

misc/tutorial/6a_editableOnFocus.ngdoc

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
@name Tutorial: Edit On Focus
33
@description
44

5-
Combinine ui.grid.edit with ui.grid.cellNav, you can enable editing when the cell gets focus.
5+
Combine ui.grid.edit with ui.grid.cellNav, you can enable editing when the cell gets focus.
66
grid.options.enableCellEditOnFocus must be set to true.
7+
<br/>
8+
See api docs for default navigation keys and how you can override.
9+
710

811
@example
912
<example module="app">

src/js/edit/gridEdit.js

+135-91
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
(function () {
22
'use strict';
3+
4+
/**
5+
* @ngdoc overview
6+
* @name ui.grid.edit
7+
* @description
8+
*
9+
* # ui.grid.edit
10+
* This module provides cell editing capability to ui.grid. The goal was to emulate keying data in a spreadsheet via
11+
* a keyboard.
12+
* <br/>
13+
* <br/>
14+
* To really get the full spreadsheet-like data entry, the ui.grid.cellNav module should be used. This will allow the
15+
* user to key data and then tab, arrow, or enter to the cells beside or below.
16+
*
17+
* <div doc-module-components="ui.grid.edit"></div>
18+
*/
19+
320
var module = angular.module('ui.grid.edit', ['ui.grid', 'ui.grid.util']);
421

522
/**
@@ -25,10 +42,38 @@
2542
*
2643
* @description Services for editing features
2744
*/
28-
module.service('uiGridEditService', ['$log', '$q', '$templateCache',
29-
function ($log, $q, $templateCache) {
45+
module.service('uiGridEditService', ['$log', '$q', '$templateCache', 'uiGridConstants',
46+
function ($log, $q, $templateCache, uiGridConstants) {
3047

3148
var service = {
49+
50+
/**
51+
* @ngdoc service
52+
* @name isStartEditKey
53+
* @methodOf ui.grid.edit.service:uiGridEditService
54+
* @description Determines if a keypress should start editing. Decorate this service to override with your
55+
* own key events. See service decorator in angular docs.
56+
* @parm {Event} evt keydown event
57+
* @returns {boolean} true if an edit should start
58+
*/
59+
isStartEditKey: function (evt) {
60+
if (evt.keyCode === uiGridConstants.keymap.LEFT ||
61+
(evt.keyCode === uiGridConstants.keymap.TAB && evt.shiftKey) ||
62+
63+
evt.keyCode === uiGridConstants.keymap.RIGHT ||
64+
evt.keyCode === uiGridConstants.keymap.TAB ||
65+
66+
evt.keyCode === uiGridConstants.keymap.UP ||
67+
(evt.keyCode === uiGridConstants.keymap.ENTER && evt.shiftKey) ||
68+
69+
evt.keyCode === uiGridConstants.keymap.DOWN ||
70+
evt.keyCode === uiGridConstants.keymap.ENTER) {
71+
return false;
72+
73+
}
74+
return true;
75+
},
76+
3277
/**
3378
* @ngdoc service
3479
* @name editColumnBuilder
@@ -150,114 +195,112 @@
150195
* - uiGridConstants.events.GRID_SCROLL
151196
*
152197
*/
153-
module.directive('uiGridCell', ['$compile', 'uiGridConstants', 'uiGridEditConstants', '$log', '$parse',
154-
function ($compile, uiGridConstants, uiGridEditConstants, $log, $parse) {
155-
return {
156-
priority: -100, // run after default uiGridCell directive
157-
restrict: 'A',
158-
scope: false,
159-
link: function ($scope, $elm, $attrs) {
160-
if (!$scope.col.colDef.enableCellEdit) {
161-
return;
162-
}
198+
module.directive('uiGridCell',
199+
['$compile', 'uiGridConstants', 'uiGridEditConstants', '$log', '$parse', 'uiGridEditService',
200+
function ($compile, uiGridConstants, uiGridEditConstants, $log, $parse, uiGridEditService) {
201+
return {
202+
priority: -100, // run after default uiGridCell directive
203+
restrict: 'A',
204+
scope: false,
205+
link: function ($scope, $elm, $attrs) {
206+
if (!$scope.col.colDef.enableCellEdit) {
207+
return;
208+
}
163209

164-
var html;
165-
var origCellValue;
166-
var inEdit = false;
167-
var cellModel;
210+
var html;
211+
var origCellValue;
212+
var inEdit = false;
213+
var cellModel;
168214

169-
registerBeginEditEvents();
215+
registerBeginEditEvents();
170216

171-
function registerBeginEditEvents() {
172-
$elm.on('dblclick', function () {
173-
beginEdit();
174-
});
175-
$elm.on('keydown', function (evt) {
176-
switch (evt.keyCode) {
177-
case uiGridConstants.keymap.F2:
217+
function registerBeginEditEvents() {
218+
$elm.on('dblclick', function () {
219+
beginEdit();
220+
});
221+
$elm.on('keydown', function (evt) {
222+
if (uiGridEditService.isStartEditKey(evt)) {
223+
beginEdit();
224+
}
225+
});
226+
if ($scope.col.enableCellEditOnFocus) {
227+
$elm.find('div').on('focus', function (evt) {
178228
evt.stopPropagation();
179229
beginEdit();
180-
break;
230+
});
181231
}
182-
});
183-
if ($scope.col.enableCellEditOnFocus) {
184-
$elm.find('div').on('focus', function (evt) {
185-
evt.stopPropagation();
186-
beginEdit();
187-
});
188232
}
189-
}
190233

191-
function cancelBeginEditEvents() {
192-
$elm.off('dblclick');
193-
$elm.off('keydown');
194-
if ($scope.col.enableCellEditOnFocus) {
195-
$elm.find('div').off('focus');
196-
}
197-
}
198-
199-
function beginEdit() {
200-
cellModel = $parse($scope.row.getQualifiedColField($scope.col));
201-
//get original value from the cell
202-
origCellValue = cellModel($scope);
203-
204-
html = $scope.col.editableCellTemplate;
205-
html = html.replace(uiGridEditConstants.EDITABLE_CELL_DIRECTIVE, $scope.col.editableCellDirective);
206-
207-
var cellElement;
208-
$scope.$apply(function () {
209-
inEdit = true;
210-
cancelBeginEditEvents();
211-
cellElement = $compile(html)($scope.$new());
212-
angular.element($elm.children()[0]).addClass('ui-grid-cell-contents-hidden');
213-
$elm.append(cellElement);
234+
function cancelBeginEditEvents() {
235+
$elm.off('dblclick');
236+
$elm.off('keydown');
237+
if ($scope.col.enableCellEditOnFocus) {
238+
$elm.find('div').off('focus');
214239
}
215-
);
240+
}
216241

217-
//stop editing when grid is scrolled
218-
var deregOnGridScroll = $scope.$on(uiGridConstants.events.GRID_SCROLL, function () {
219-
endEdit();
220-
deregOnGridScroll();
221-
});
242+
function beginEdit() {
243+
cellModel = $parse($scope.row.getQualifiedColField($scope.col));
244+
//get original value from the cell
245+
origCellValue = cellModel($scope);
246+
247+
html = $scope.col.editableCellTemplate;
248+
html = html.replace(uiGridEditConstants.EDITABLE_CELL_DIRECTIVE, $scope.col.editableCellDirective);
249+
250+
var cellElement;
251+
$scope.$apply(function () {
252+
inEdit = true;
253+
cancelBeginEditEvents();
254+
cellElement = $compile(html)($scope.$new());
255+
angular.element($elm.children()[0]).addClass('ui-grid-cell-contents-hidden');
256+
$elm.append(cellElement);
257+
}
258+
);
259+
260+
//stop editing when grid is scrolled
261+
var deregOnGridScroll = $scope.$on(uiGridConstants.events.GRID_SCROLL, function () {
262+
endEdit();
263+
deregOnGridScroll();
264+
});
222265

223-
//end editing
224-
var deregOnEndCellEdit = $scope.$on(uiGridEditConstants.events.END_CELL_EDIT, function () {
225-
endEdit();
226-
deregOnEndCellEdit();
227-
});
266+
//end editing
267+
var deregOnEndCellEdit = $scope.$on(uiGridEditConstants.events.END_CELL_EDIT, function () {
268+
endEdit();
269+
deregOnEndCellEdit();
270+
});
228271

229-
//cancel editing
230-
var deregOnCancelCellEdit = $scope.$on(uiGridEditConstants.events.CANCEL_CELL_EDIT, function () {
231-
cancelEdit();
232-
deregOnCancelCellEdit();
233-
});
272+
//cancel editing
273+
var deregOnCancelCellEdit = $scope.$on(uiGridEditConstants.events.CANCEL_CELL_EDIT, function () {
274+
cancelEdit();
275+
deregOnCancelCellEdit();
276+
});
234277

235-
$scope.$broadcast(uiGridEditConstants.events.BEGIN_CELL_EDIT);
236-
}
278+
$scope.$broadcast(uiGridEditConstants.events.BEGIN_CELL_EDIT);
279+
}
237280

238-
function endEdit() {
239-
if (!inEdit) {
240-
return;
281+
function endEdit() {
282+
if (!inEdit) {
283+
return;
284+
}
285+
angular.element($elm.children()[1]).remove();
286+
angular.element($elm.children()[0]).removeClass('ui-grid-cell-contents-hidden');
287+
inEdit = false;
288+
registerBeginEditEvents();
241289
}
242-
angular.element($elm.children()[1]).remove();
243-
angular.element($elm.children()[0]).removeClass('ui-grid-cell-contents-hidden');
244-
inEdit = false;
245-
registerBeginEditEvents();
246-
}
247290

248-
function cancelEdit() {
249-
if (!inEdit) {
250-
return;
291+
function cancelEdit() {
292+
if (!inEdit) {
293+
return;
294+
}
295+
cellModel.assign($scope, origCellValue);
296+
$scope.$apply();
297+
298+
endEdit();
251299
}
252-
cellModel.assign($scope, origCellValue);
253-
$scope.$apply();
254300

255-
endEdit();
256301
}
257-
258-
}
259-
};
260-
}]);
302+
};
303+
}]);
261304

262305
/**
263306
* @ngdoc directive
@@ -296,6 +339,7 @@
296339
//set focus at start of edit
297340
$scope.$on(uiGridEditConstants.events.BEGIN_CELL_EDIT, function () {
298341
inputElm[0].focus();
342+
inputElm[0].select();
299343
inputElm.on('blur', function (evt) {
300344
$scope.stopEdit();
301345
});

test/unit/edit/uiGridCell.spec.js

+32-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ describe('ui.grid.edit GridCellDirective', function () {
44
var element;
55
var uiGridConstants;
66
var recompile;
7+
var $timeout;
78

89
beforeEach(module('ui.grid.edit'));
910

10-
beforeEach(inject(function ($rootScope, $compile, $controller, _gridUtil_, $templateCache, gridClassFactory, uiGridEditService, _uiGridConstants_) {
11+
beforeEach(inject(function ($rootScope, $compile, $controller, _gridUtil_, $templateCache, gridClassFactory,
12+
uiGridEditService, _uiGridConstants_, _$timeout_) {
1113
gridUtil = _gridUtil_;
1214
uiGridConstants = _uiGridConstants_;
15+
$timeout = _$timeout_;
1316

1417
$templateCache.put('ui-grid/uiGridCell', '<div class="ui-grid-cell-contents">{{COL_FIELD CUSTOM_FILTERS}}</div>');
1518
$templateCache.put('ui-grid/edit/editableCell', '<div editable_cell_directive></div>');
@@ -37,6 +40,34 @@ describe('ui.grid.edit GridCellDirective', function () {
3740
};
3841
}));
3942

43+
describe('ui.grid.edit uiGridCell start editing', function () {
44+
var displayHtml;
45+
beforeEach(function () {
46+
element = angular.element('<div ui-grid-cell/>');
47+
recompile();
48+
49+
displayHtml = element.html();
50+
expect(element.text()).toBe('val');
51+
});
52+
53+
it('startEdit on "a"', function () {
54+
//stop edit
55+
var event = jQuery.Event("keydown");
56+
event.keyCode = 65;
57+
element.trigger(event);
58+
expect(element.find('input')).toBeDefined();
59+
});
60+
61+
it('not start edit on tab', function () {
62+
//stop edit
63+
var event = jQuery.Event("keydown");
64+
event.keyCode = uiGridConstants.keymap.TAB;
65+
element.trigger(event);
66+
expect(element.html()).toEqual(displayHtml);
67+
});
68+
69+
});
70+
4071
describe('ui.grid.edit uiGridCell and uiGridTextEditor full workflow', function () {
4172
var displayHtml;
4273
beforeEach(function () {
@@ -51,7 +82,6 @@ describe('ui.grid.edit GridCellDirective', function () {
5182
expect(element.find('input').val()).toBe('val');
5283
});
5384

54-
5585
it('should stop editing on enter', function () {
5686
//stop edit
5787
var event = jQuery.Event("keydown");

0 commit comments

Comments
 (0)