Skip to content

Commit

Permalink
Merge pull request #48 from InteractiveIntelligence/macos-boolean-edi…
Browse files Browse the repository at this point in the history
…t-fix

fix(edit): fix boolean edit issue on Firefox and Safari on macOS
  • Loading branch information
jasonmobley authored Oct 26, 2016
2 parents 0c0a7da + ea125fe commit 13e06e2
Showing 1 changed file with 89 additions and 25 deletions.
114 changes: 89 additions & 25 deletions src/features/edit/js/gridEdit.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,8 @@
*/

module.directive('uiGridCell',
['$compile', '$injector', '$timeout', 'uiGridConstants', 'uiGridEditConstants', 'gridUtil', '$parse', 'uiGridEditService', '$rootScope',
function ($compile, $injector, $timeout, uiGridConstants, uiGridEditConstants, gridUtil, $parse, uiGridEditService, $rootScope) {
['$compile', '$injector', '$timeout', 'uiGridConstants', 'uiGridEditConstants', 'gridUtil', '$parse', 'uiGridEditService', '$rootScope', '$q',
function ($compile, $injector, $timeout, uiGridConstants, uiGridEditConstants, gridUtil, $parse, uiGridEditService, $rootScope, $q) {
var touchstartTimeout = 500;
if ($injector.has('uiGridCellNavService')) {
var uiGridCellNavService = $injector.get('uiGridCellNavService');
Expand Down Expand Up @@ -652,6 +652,40 @@
* </pre>
*
*/
/**
* @ngdoc service
* @name editDropdownOptionsFunction
* @methodOf ui.grid.edit.api:ColumnDef
* @description a function returning an array of values in the format
* [ {id: xxx, value: xxx} ], which will be used to populate
* the edit dropdown. This can be used when the dropdown values are dependent on
* the backing row entity with some kind of algorithm.
* If this property is set then both editDropdownOptionsArray and
* editDropdownRowEntityOptionsArrayPath will be ignored.
* @param {object} rowEntity the options.data element that the returned array refers to
* @param {object} colDef the column that implements this dropdown
* @returns {object} an array of values in the format
* [ {id: xxx, value: xxx} ] used to populate the edit dropdown
* @example
* <pre>
* $scope.gridOptions = {
* columnDefs: [
* {name: 'status', editableCellTemplate: 'ui-grid/dropdownEditor',
* editDropdownOptionsFunction: function(rowEntity, colDef) {
* if (rowEntity.foo === 'bar') {
* return [{id: 'bar1', value: 'BAR 1'},
* {id: 'bar2', value: 'BAR 2'},
* {id: 'bar3', value: 'BAR 3'}];
* } else {
* return [{id: 'foo1', value: 'FOO 1'},
* {id: 'foo2', value: 'FOO 2'}];
* }
* },
* editDropdownIdLabel: 'code', editDropdownValueLabel: 'status' }
* ],
* </pre>
*
*/
/**
* @ngdoc property
* @name editDropdownValueLabel
Expand Down Expand Up @@ -698,20 +732,18 @@
return;
}

var modelField = $scope.row.getQualifiedColField($scope.col);
if ($scope.col.colDef.editModelField) {
modelField = gridUtil.preEval('row.entity.' + $scope.col.colDef.editModelField);
}

cellModel = $parse(modelField);

cellModel = $parse($scope.row.getQualifiedColField($scope.col));
//get original value from the cell
origCellValue = cellModel($scope);

html = $scope.col.editableCellTemplate;

if ($scope.col.colDef.editModelField) {
html = html.replace(uiGridConstants.MODEL_COL_FIELD, gridUtil.preEval('row.entity.' + $scope.col.colDef.editModelField));
}
else {
html = html.replace(uiGridConstants.MODEL_COL_FIELD, $scope.row.getQualifiedColField($scope.col));
}

html = html.replace(uiGridConstants.MODEL_COL_FIELD, modelField);
html = html.replace(uiGridConstants.COL_FIELD, 'grid.getCellValue(row, col)');

var optionFilter = $scope.col.colDef.editDropdownFilter ? '|' + $scope.col.colDef.editDropdownFilter : '';
Expand All @@ -731,12 +763,24 @@
}
html = html.replace('INPUT_TYPE', inputType);

var editDropdownRowEntityOptionsArrayPath = $scope.col.colDef.editDropdownRowEntityOptionsArrayPath;
if (editDropdownRowEntityOptionsArrayPath) {
$scope.editDropdownOptionsArray = resolveObjectFromPath($scope.row.entity, editDropdownRowEntityOptionsArrayPath);
}
else {
$scope.editDropdownOptionsArray = $scope.col.colDef.editDropdownOptionsArray;
// In order to fill dropdown options we use:
// - A function/promise or
// - An array inside of row entity if no function exists or
// - A single array for the whole column if none of the previous exists.
var editDropdownOptionsFunction = $scope.col.colDef.editDropdownOptionsFunction;
if (editDropdownOptionsFunction) {
$q.when(editDropdownOptionsFunction($scope.row.entity, $scope.col.colDef))
.then(function(result) {
$scope.editDropdownOptionsArray = result;
});
} else {
var editDropdownRowEntityOptionsArrayPath = $scope.col.colDef.editDropdownRowEntityOptionsArrayPath;
if (editDropdownRowEntityOptionsArrayPath) {
$scope.editDropdownOptionsArray = resolveObjectFromPath($scope.row.entity, editDropdownRowEntityOptionsArrayPath);
}
else {
$scope.editDropdownOptionsArray = $scope.col.colDef.editDropdownOptionsArray;
}
}
$scope.editDropdownIdLabel = $scope.col.colDef.editDropdownIdLabel ? $scope.col.colDef.editDropdownIdLabel : 'id';
$scope.editDropdownValueLabel = $scope.col.colDef.editDropdownValueLabel ? $scope.col.colDef.editDropdownValueLabel : 'value';
Expand All @@ -760,6 +804,9 @@

//stop editing when grid is scrolled
var deregOnGridScroll = $scope.col.grid.api.core.on.scrollBegin($scope, function () {
if ($scope.grid.disableScrolling) {
return;
}
endEdit();
$scope.grid.api.edit.raise.afterCellEdit($scope.row.entity, $scope.col.colDef, cellModel($scope), origCellValue);
deregOnGridScroll();
Expand Down Expand Up @@ -807,7 +854,10 @@
var gridCellContentsEl = angular.element($elm.children()[0]);
//remove edit element
editCellScope.$destroy();
angular.element($elm.children()[1]).remove();
var children = $elm.children();
for (var i = 1; i < children.length; i++) {
angular.element(children[i]).remove();
}
gridCellContentsEl.removeClass('ui-grid-cell-contents-hidden');
inEdit = false;
registerBeginEditEvents();
Expand Down Expand Up @@ -886,7 +936,7 @@
$timeout(function () {
$elm[0].focus();
//only select text if it is not being replaced below in the cellNav viewPortKeyPress
if ($scope.col.colDef.enableCellEditOnFocus || !(uiGridCtrl && uiGridCtrl.grid.api.cellNav)) {
if ($elm[0].select && ($scope.col.colDef.enableCellEditOnFocus || !(uiGridCtrl && uiGridCtrl.grid.api.cellNav))) {
$elm[0].select();
}
else {
Expand All @@ -909,16 +959,27 @@
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.$setViewValue(String.fromCharCode( typeof evt.which === 'number' ? evt.which : evt.keyCode), evt);
ngModel.$render();
}
viewPortKeyDownUnregister();
});
}

$elm.on('blur', function (evt) {
$scope.stopEdit(evt);
// macOS will blur the checkbox when clicked in Safari and Firefox,
// to get around this, we disable the blur handler on mousedown,
// and then focus the checkbox and re-enable the blur handler after $timeout
$elm.on('mousedown', function(evt) {
if ($elm[0].type === 'checkbox') {
$elm.off('blur', $scope.stopEdit);
$timeout(function() {
$elm.focus();
$elm.on('blur', $scope.stopEdit);
});
}
});

$elm.on('blur', $scope.stopEdit);
});


Expand Down Expand Up @@ -1065,8 +1126,8 @@
*
*/
module.directive('uiGridEditDropdown',
['uiGridConstants', 'uiGridEditConstants',
function (uiGridConstants, uiGridEditConstants) {
['uiGridConstants', 'uiGridEditConstants', '$timeout',
function (uiGridConstants, uiGridEditConstants, $timeout) {
return {
require: ['?^uiGrid', '?^uiGridRenderContainer'],
scope: true,
Expand All @@ -1081,7 +1142,10 @@

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

$elm[0].style.width = ($elm[0].parentElement.offsetWidth - 1) + 'px';
$elm.on('blur', function (evt) {
$scope.stopEdit(evt);
Expand Down

0 comments on commit 13e06e2

Please sign in to comment.