Skip to content

Commit

Permalink
fix(edit): fix lost focus and cell scrolling into view on edit
Browse files Browse the repository at this point in the history
  • Loading branch information
swalters committed Jun 26, 2015
1 parent 3253caf commit e9a6d4e
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 22 deletions.
33 changes: 30 additions & 3 deletions src/features/cellnav/js/cellnav.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,20 @@
* @param {object} event keydown event
* @param {object} rowCol current rowCol position
*/
viewPortKeyDown: function (event, rowCol) {}
viewPortKeyDown: function (event, rowCol) {},

/**
* @ngdoc event
* @name viewPortKeyPress
* @eventOf ui.grid.cellNav.api:PublicApi
* @description is raised when the viewPort receives a keyPress event. Cells never get focus in uiGrid
* due to the difficulties of setting focus on a cell that is not visible in the viewport. Use this
* event whenever you need a keypress event on a cell
* <br/>
* @param {object} event keypress event
* @param {object} rowCol current rowCol position
*/
viewPortKeyPress: function (event, rowCol) {}
}
},
methods: {
Expand Down Expand Up @@ -775,15 +788,29 @@
});
};



var viewPortKeyDownWasRaisedForRowCol = null;
// Bind to keydown events in the render container
focuser.on('keydown', function (evt) {
evt.uiGridTargetRenderContainerId = containerId;
var rowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
var result = uiGridCtrl.cellNav.handleKeyDown(evt);
if (result === null) {
uiGridCtrl.grid.api.cellNav.raise.viewPortKeyDown(evt, rowCol);
viewPortKeyDownWasRaisedForRowCol = rowCol;
}
});
//Bind to keypress events in the render container
//keypress events are needed by edit function so the key press
//that initiated an edit is not lost
//must fire the event in a timeout so the editor can
//initialize and subscribe to the event on another event loop
focuser.on('keypress', function (evt) {
if (viewPortKeyDownWasRaisedForRowCol) {
$timeout(function () {
uiGridCtrl.grid.api.cellNav.raise.viewPortKeyPress(evt, viewPortKeyDownWasRaisedForRowCol);
},4);

viewPortKeyDownWasRaisedForRowCol = null;
}
});

Expand Down
58 changes: 44 additions & 14 deletions src/features/edit/js/gridEdit.js
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@
if (rowCol.row === $scope.row && rowCol.col === $scope.col && !$scope.col.colDef.enableCellEditOnFocus) {
//important to do this before scrollToIfNecessary
beginEditKeyDown(evt);
uiGridCtrl.grid.api.core.scrollToIfNecessary(rowCol.row, rowCol.col);
// uiGridCtrl.grid.api.core.scrollToIfNecessary(rowCol.row, rowCol.col);
}

});
Expand Down Expand Up @@ -582,6 +582,14 @@
}


function beginEdit(triggerEvent) {
//we need to scroll the cell into focus before invoking the editor
$scope.grid.api.core.scrollToIfNecessary($scope.row, $scope.col)
.then(function () {
beginEditAfterScroll(triggerEvent);
});
}

/**
* @ngdoc property
* @name editDropdownOptionsArray
Expand Down Expand Up @@ -666,7 +674,7 @@
* </pre>
*
*/
function beginEdit(triggerEvent) {
function beginEditAfterScroll(triggerEvent) {
// If we are already editing, then just skip this so we don't try editing twice...
if (inEdit) {
return;
Expand Down Expand Up @@ -738,16 +746,16 @@

//stop editing when grid is scrolled
var deregOnGridScroll = $scope.col.grid.api.core.on.scrollBegin($scope, function () {
endEdit(true);
endEdit();
$scope.grid.api.edit.raise.afterCellEdit($scope.row.entity, $scope.col.colDef, cellModel($scope), origCellValue);
deregOnGridScroll();
deregOnEndCellEdit();
deregOnCancelCellEdit();
});

//end editing
var deregOnEndCellEdit = $scope.$on(uiGridEditConstants.events.END_CELL_EDIT, function (evt, retainFocus) {
endEdit(retainFocus);
var deregOnEndCellEdit = $scope.$on(uiGridEditConstants.events.END_CELL_EDIT, function () {
endEdit();
$scope.grid.api.edit.raise.afterCellEdit($scope.row.entity, $scope.col.colDef, cellModel($scope), origCellValue);
deregOnEndCellEdit();
deregOnGridScroll();
Expand All @@ -766,7 +774,7 @@
$scope.grid.api.edit.raise.beginCellEdit($scope.row.entity, $scope.col.colDef, triggerEvent);
}

function endEdit(retainFocus) {
function endEdit() {
$scope.grid.disableScrolling = false;
if (!inEdit) {
return;
Expand All @@ -779,6 +787,11 @@
inEdit = false;
registerBeginEditEvents();
$scope.grid.api.core.notifyDataChange( uiGridConstants.dataChange.EDIT );
//sometimes the events can't keep up with the keyboard and grid focus is lost, so always focus
//back to grid here
if (uiGridCtrl && uiGridCtrl.grid.api.cellNav) {
uiGridCtrl.focus();
}
}

function cancelEdit() {
Expand All @@ -790,7 +803,7 @@
$scope.$apply();

$scope.grid.api.edit.raise.cancelCellEdit($scope.row.entity, $scope.col.colDef);
endEdit(true);
endEdit();
}

// resolves a string path against the given object
Expand Down Expand Up @@ -832,25 +845,42 @@
*
*/
module.directive('uiGridEditor',
['gridUtil', 'uiGridConstants', 'uiGridEditConstants','$timeout',
function (gridUtil, uiGridConstants, uiGridEditConstants, $timeout) {
['gridUtil', 'uiGridConstants', 'uiGridEditConstants','$timeout', 'uiGridEditService',
function (gridUtil, uiGridConstants, uiGridEditConstants, $timeout, uiGridEditService) {
return {
scope: true,
require: ['?^uiGrid', '?^uiGridRenderContainer'],
require: ['?^uiGrid', '?^uiGridRenderContainer', 'ngModel'],
compile: function () {
return {
pre: function ($scope, $elm, $attrs) {

},
post: function ($scope, $elm, $attrs, controllers) {
var uiGridCtrl, renderContainerCtrl;
var uiGridCtrl, renderContainerCtrl, ngModel;
if (controllers[0]) { uiGridCtrl = controllers[0]; }
if (controllers[1]) { renderContainerCtrl = controllers[1]; }
if (controllers[2]) { ngModel = controllers[2]; }

//set focus at start of edit
$scope.$on(uiGridEditConstants.events.BEGIN_CELL_EDIT, function () {
$elm[0].focus();
$elm[0].select();
$scope.$on(uiGridEditConstants.events.BEGIN_CELL_EDIT, function (evt,triggerEvent) {
$timeout(function () {
$elm[0].focus();
$elm[0].select();
});

//set the keystroke that started the edit event
//we must do this because the BeginEdit is done in a different event loop than the intitial
//keydown event
//fire this event for the keypress that is received
if (uiGridCtrl && uiGridCtrl.grid.api.cellNav) {
var viewPortKeyDownUnregister = uiGridCtrl.grid.api.cellNav.on.viewPortKeyPress($scope, function (evt, rowCol) {
if (uiGridEditService.isStartEditKey(evt)) {
ngModel.$setViewValue(String.fromCharCode(evt.keyCode), evt);
ngModel.$render();
}
viewPortKeyDownUnregister();
});
}

$elm.on('blur', function (evt) {
$scope.stopEdit(evt);
Expand Down
7 changes: 5 additions & 2 deletions src/features/edit/test/uiGridCell.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,11 @@ describe('ui.grid.edit GridCellDirective', function () {
expect(element.text()).toBe('val');
//invoke edit
element.dblclick();
expect(element.find('input')).toBeDefined();
expect(element.find('input').val()).toBe('val');
$timeout(function () {
expect(element.find('input')).toBeDefined();
expect(element.find('input').val()).toBe('val');
});
$timeout.flush();
});

it('should stop editing on enter', function () {
Expand Down
13 changes: 10 additions & 3 deletions src/features/edit/test/uiGridCellWithDropdown.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,11 @@ describe('ui.grid.edit GridCellDirective - with dropdown', function () {
element.dblclick();
expect(element.find('select')).toBeDefined();

// val is the selected option, which is option 0
expect(element.find('select').val()).toBe('0');
$timeout(function () {
// val is the selected option, which is option 0
expect(element.find('select').val()).toBe('0');
});
$timeout.flush();
});

it('should stop editing on enter', function () {
Expand All @@ -96,7 +99,11 @@ describe('ui.grid.edit GridCellDirective - with dropdown', function () {
element.find('select').trigger(event);

//back to beginning
expect(element.html()).toBe(displayHtml);
$timeout(function () {
expect(element.html()).toBe(displayHtml);
});
$timeout.flush();

});

it('should stop editing on esc', function () {
Expand Down

0 comments on commit e9a6d4e

Please sign in to comment.