@everymatrix/stage-mm-verification-report 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/chunk-A3NTIEMP.js +1 -0
- package/chunk-CAY35YP7.js +7 -0
- package/chunk-H3QHLLCN.js +1 -0
- package/chunk-KE4BCZO4.js +851 -0
- package/chunk-OHPEWN32.js +1198 -0
- package/chunk-WSQOM5HU.js +1 -0
- package/component-lib.js +1 -0
- package/index.html +12 -0
- package/main.js +3264 -0
- package/modules/angular/LICENSE.md +21 -0
- package/modules/angular/README.md +67 -0
- package/modules/angular/angular-csp.css +25 -0
- package/modules/angular/angular.js +36600 -0
- package/modules/angular/angular.min.js +352 -0
- package/modules/angular/angular.min.js.gzip +0 -0
- package/modules/angular/angular.min.js.map +8 -0
- package/modules/angular/bower.json +9 -0
- package/modules/angular/index.js +2 -0
- package/modules/angular/package.json +25 -0
- package/modules/angular-ui-grid/CHANGELOG.md +1973 -0
- package/modules/angular-ui-grid/README.md +59 -0
- package/modules/angular-ui-grid/css/ui-grid.cellnav.css +25 -0
- package/modules/angular-ui-grid/css/ui-grid.cellnav.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.core.css +866 -0
- package/modules/angular-ui-grid/css/ui-grid.core.min.css +5 -0
- package/modules/angular-ui-grid/css/ui-grid.edit.css +23 -0
- package/modules/angular-ui-grid/css/ui-grid.edit.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.empty-base-layer.css +6 -0
- package/modules/angular-ui-grid/css/ui-grid.empty-base-layer.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.expandable.css +16 -0
- package/modules/angular-ui-grid/css/ui-grid.expandable.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.exporter.css +0 -0
- package/modules/angular-ui-grid/css/ui-grid.exporter.min.css +0 -0
- package/modules/angular-ui-grid/css/ui-grid.grouping.css +3 -0
- package/modules/angular-ui-grid/css/ui-grid.grouping.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.importer.css +0 -0
- package/modules/angular-ui-grid/css/ui-grid.importer.min.css +0 -0
- package/modules/angular-ui-grid/css/ui-grid.move-columns.css +9 -0
- package/modules/angular-ui-grid/css/ui-grid.move-columns.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.pagination.css +299 -0
- package/modules/angular-ui-grid/css/ui-grid.pagination.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.pinning.css +67 -0
- package/modules/angular-ui-grid/css/ui-grid.pinning.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.resize-columns.css +38 -0
- package/modules/angular-ui-grid/css/ui-grid.resize-columns.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.row-edit.css +9 -0
- package/modules/angular-ui-grid/css/ui-grid.row-edit.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.selection.css +25 -0
- package/modules/angular-ui-grid/css/ui-grid.selection.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.tree-base.css +4 -0
- package/modules/angular-ui-grid/css/ui-grid.tree-base.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.tree-view.css +6 -0
- package/modules/angular-ui-grid/css/ui-grid.tree-view.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.validate.css +3 -0
- package/modules/angular-ui-grid/css/ui-grid.validate.min.css +1 -0
- package/modules/angular-ui-grid/fonts/ui-grid.eot +0 -0
- package/modules/angular-ui-grid/fonts/ui-grid.svg +56 -0
- package/modules/angular-ui-grid/fonts/ui-grid.ttf +0 -0
- package/modules/angular-ui-grid/fonts/ui-grid.woff +0 -0
- package/modules/angular-ui-grid/less/animation.less +85 -0
- package/modules/angular-ui-grid/less/body.less +84 -0
- package/modules/angular-ui-grid/less/cell.less +46 -0
- package/modules/angular-ui-grid/less/cellnav.less +29 -0
- package/modules/angular-ui-grid/less/core.less +11 -0
- package/modules/angular-ui-grid/less/edit.less +27 -0
- package/modules/angular-ui-grid/less/elements.less +156 -0
- package/modules/angular-ui-grid/less/emptyBaseLayer.less +8 -0
- package/modules/angular-ui-grid/less/expandable.less +29 -0
- package/modules/angular-ui-grid/less/exporter.less +4 -0
- package/modules/angular-ui-grid/less/footer.less +76 -0
- package/modules/angular-ui-grid/less/grid.less +86 -0
- package/modules/angular-ui-grid/less/grouping.less +5 -0
- package/modules/angular-ui-grid/less/header.less +250 -0
- package/modules/angular-ui-grid/less/icons.less +151 -0
- package/modules/angular-ui-grid/less/importer.less +4 -0
- package/modules/angular-ui-grid/less/main.less +2 -0
- package/modules/angular-ui-grid/less/menu.less +91 -0
- package/modules/angular-ui-grid/less/moveColumns.less +12 -0
- package/modules/angular-ui-grid/less/pagination.less +297 -0
- package/modules/angular-ui-grid/less/pinning.less +86 -0
- package/modules/angular-ui-grid/less/resizeColumns.less +53 -0
- package/modules/angular-ui-grid/less/rowEdit.less +19 -0
- package/modules/angular-ui-grid/less/rtl.less +67 -0
- package/modules/angular-ui-grid/less/selection.less +29 -0
- package/modules/angular-ui-grid/less/sorting.less +16 -0
- package/modules/angular-ui-grid/less/treeBase.less +6 -0
- package/modules/angular-ui-grid/less/treeView.less +8 -0
- package/modules/angular-ui-grid/less/validate.less +5 -0
- package/modules/angular-ui-grid/less/variables.less +90 -0
- package/modules/angular-ui-grid/package.json +144 -0
- package/modules/angular-ui-grid/ui-grid.auto-resize.js +69 -0
- package/modules/angular-ui-grid/ui-grid.auto-resize.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.cellnav.js +1181 -0
- package/modules/angular-ui-grid/ui-grid.cellnav.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.core.js +12737 -0
- package/modules/angular-ui-grid/ui-grid.core.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.css +3208 -0
- package/modules/angular-ui-grid/ui-grid.edit.js +1325 -0
- package/modules/angular-ui-grid/ui-grid.edit.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.empty-base-layer.js +178 -0
- package/modules/angular-ui-grid/ui-grid.empty-base-layer.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.expandable.js +651 -0
- package/modules/angular-ui-grid/ui-grid.expandable.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.exporter.js +1777 -0
- package/modules/angular-ui-grid/ui-grid.exporter.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.grouping.js +1291 -0
- package/modules/angular-ui-grid/ui-grid.grouping.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.importer.js +791 -0
- package/modules/angular-ui-grid/ui-grid.importer.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.infinite-scroll.js +552 -0
- package/modules/angular-ui-grid/ui-grid.infinite-scroll.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.js +30867 -0
- package/modules/angular-ui-grid/ui-grid.language.all.js +3214 -0
- package/modules/angular-ui-grid/ui-grid.language.all.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ar.js +118 -0
- package/modules/angular-ui-grid/ui-grid.language.ar.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.bg.js +115 -0
- package/modules/angular-ui-grid/ui-grid.language.bg.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.cs.js +96 -0
- package/modules/angular-ui-grid/ui-grid.language.cs.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.da.js +90 -0
- package/modules/angular-ui-grid/ui-grid.language.da.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.de.js +133 -0
- package/modules/angular-ui-grid/ui-grid.language.de.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.es-ct.js +133 -0
- package/modules/angular-ui-grid/ui-grid.language.es-ct.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.es.js +106 -0
- package/modules/angular-ui-grid/ui-grid.language.es.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.fa.js +93 -0
- package/modules/angular-ui-grid/ui-grid.language.fa.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.fi.js +76 -0
- package/modules/angular-ui-grid/ui-grid.language.fi.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.fr.js +128 -0
- package/modules/angular-ui-grid/ui-grid.language.fr.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.he.js +71 -0
- package/modules/angular-ui-grid/ui-grid.language.he.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.hy.js +76 -0
- package/modules/angular-ui-grid/ui-grid.language.hy.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.is.js +118 -0
- package/modules/angular-ui-grid/ui-grid.language.is.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.it.js +112 -0
- package/modules/angular-ui-grid/ui-grid.language.it.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ja.js +118 -0
- package/modules/angular-ui-grid/ui-grid.language.ja.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ko.js +77 -0
- package/modules/angular-ui-grid/ui-grid.language.ko.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.nl.js +91 -0
- package/modules/angular-ui-grid/ui-grid.language.nl.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.no.js +115 -0
- package/modules/angular-ui-grid/ui-grid.language.no.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.pl.js +126 -0
- package/modules/angular-ui-grid/ui-grid.language.pl.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.pt-br.js +133 -0
- package/modules/angular-ui-grid/ui-grid.language.pt-br.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.pt.js +133 -0
- package/modules/angular-ui-grid/ui-grid.language.pt.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ro.js +112 -0
- package/modules/angular-ui-grid/ui-grid.language.ro.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.rs-lat.js +126 -0
- package/modules/angular-ui-grid/ui-grid.language.rs-lat.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ru.js +115 -0
- package/modules/angular-ui-grid/ui-grid.language.ru.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.sk.js +127 -0
- package/modules/angular-ui-grid/ui-grid.language.sk.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.sv.js +126 -0
- package/modules/angular-ui-grid/ui-grid.language.sv.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ta.js +87 -0
- package/modules/angular-ui-grid/ui-grid.language.ta.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.tr.js +112 -0
- package/modules/angular-ui-grid/ui-grid.language.tr.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ua.js +112 -0
- package/modules/angular-ui-grid/ui-grid.language.ua.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.zh-cn.js +112 -0
- package/modules/angular-ui-grid/ui-grid.language.zh-cn.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.zh-tw.js +77 -0
- package/modules/angular-ui-grid/ui-grid.language.zh-tw.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.min.css +5 -0
- package/modules/angular-ui-grid/ui-grid.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.move-columns.js +582 -0
- package/modules/angular-ui-grid/ui-grid.move-columns.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.pagination.js +510 -0
- package/modules/angular-ui-grid/ui-grid.pagination.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.pinning.js +281 -0
- package/modules/angular-ui-grid/ui-grid.pinning.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.resize-columns.js +574 -0
- package/modules/angular-ui-grid/ui-grid.resize-columns.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.row-edit.js +717 -0
- package/modules/angular-ui-grid/ui-grid.row-edit.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.saveState.js +831 -0
- package/modules/angular-ui-grid/ui-grid.saveState.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.selection.js +1196 -0
- package/modules/angular-ui-grid/ui-grid.selection.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.tree-base.js +1743 -0
- package/modules/angular-ui-grid/ui-grid.tree-base.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.tree-view.js +218 -0
- package/modules/angular-ui-grid/ui-grid.tree-view.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.validate.js +589 -0
- package/modules/angular-ui-grid/ui-grid.validate.min.js +6 -0
- package/package.json +8 -0
- package/polyfills.js +2 -0
- package/styles.css +1 -0
|
@@ -0,0 +1,1181 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ui-grid - v4.12.7 - 2024-04-12
|
|
3
|
+
* http://ui-grid.info/
|
|
4
|
+
* Copyright (c) 2024 ; License: MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
(function () {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @ngdoc overview
|
|
12
|
+
* @name ui.grid.cellNav
|
|
13
|
+
*
|
|
14
|
+
* @description
|
|
15
|
+
|
|
16
|
+
#ui.grid.cellNav
|
|
17
|
+
|
|
18
|
+
<div class="alert alert-success" role="alert"><strong>Stable</strong> This feature is stable. There should no longer be breaking api changes without a deprecation warning.</div>
|
|
19
|
+
|
|
20
|
+
This module provides cell navigation functionality to UI-Grid.
|
|
21
|
+
*/
|
|
22
|
+
var module = angular.module('ui.grid.cellNav', ['ui.grid']);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @ngdoc object
|
|
26
|
+
* @name ui.grid.cellNav.constant:uiGridCellNavConstants
|
|
27
|
+
*
|
|
28
|
+
* @description constants available in cellNav
|
|
29
|
+
*/
|
|
30
|
+
module.constant('uiGridCellNavConstants', {
|
|
31
|
+
FEATURE_NAME: 'gridCellNav',
|
|
32
|
+
CELL_NAV_EVENT: 'cellNav',
|
|
33
|
+
direction: {LEFT: 0, RIGHT: 1, UP: 2, DOWN: 3, PG_UP: 4, PG_DOWN: 5},
|
|
34
|
+
EVENT_TYPE: {
|
|
35
|
+
KEYDOWN: 0,
|
|
36
|
+
CLICK: 1,
|
|
37
|
+
CLEAR: 2
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
module.factory('uiGridCellNavFactory', ['uiGridCellNavConstants', 'GridRowColumn',
|
|
43
|
+
function (uiGridCellNavConstants, GridRowColumn) {
|
|
44
|
+
/**
|
|
45
|
+
* @ngdoc object
|
|
46
|
+
* @name ui.grid.cellNav.object:CellNav
|
|
47
|
+
* @description returns a CellNav prototype function
|
|
48
|
+
* @param {object} rowContainer container for rows
|
|
49
|
+
* @param {object} colContainer parent column container
|
|
50
|
+
* @param {object} leftColContainer column container to the left of parent
|
|
51
|
+
* @param {object} rightColContainer column container to the right of parent
|
|
52
|
+
*/
|
|
53
|
+
var UiGridCellNav = function UiGridCellNav(rowContainer, colContainer, leftColContainer, rightColContainer) {
|
|
54
|
+
this.rows = rowContainer.visibleRowCache;
|
|
55
|
+
this.columns = colContainer.visibleColumnCache;
|
|
56
|
+
this.leftColumns = leftColContainer ? leftColContainer.visibleColumnCache : [];
|
|
57
|
+
this.rightColumns = rightColContainer ? rightColContainer.visibleColumnCache : [];
|
|
58
|
+
this.bodyContainer = rowContainer;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/** returns focusable columns of all containers */
|
|
62
|
+
UiGridCellNav.prototype.getFocusableCols = function () {
|
|
63
|
+
var allColumns = this.leftColumns.concat(this.columns, this.rightColumns);
|
|
64
|
+
|
|
65
|
+
return allColumns.filter(function (col) {
|
|
66
|
+
return col.colDef.allowCellFocus;
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @ngdoc object
|
|
72
|
+
* @name ui.grid.cellNav.api:GridRow
|
|
73
|
+
*
|
|
74
|
+
* @description GridRow settings for cellNav feature, these are available to be
|
|
75
|
+
* set only internally (for example, by other features)
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @ngdoc object
|
|
80
|
+
* @name allowCellFocus
|
|
81
|
+
* @propertyOf ui.grid.cellNav.api:GridRow
|
|
82
|
+
* @description Enable focus on a cell within this row. If set to false then no cells
|
|
83
|
+
* in this row can be focused - group header rows as an example would set this to false.
|
|
84
|
+
* <br/>Defaults to true
|
|
85
|
+
*/
|
|
86
|
+
/** returns focusable rows */
|
|
87
|
+
UiGridCellNav.prototype.getFocusableRows = function () {
|
|
88
|
+
return this.rows.filter(function(row) {
|
|
89
|
+
return row.allowCellFocus !== false;
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
UiGridCellNav.prototype.getNextRowCol = function (direction, curRow, curCol) {
|
|
94
|
+
switch (direction) {
|
|
95
|
+
case uiGridCellNavConstants.direction.LEFT:
|
|
96
|
+
return this.getRowColLeft(curRow, curCol);
|
|
97
|
+
case uiGridCellNavConstants.direction.RIGHT:
|
|
98
|
+
return this.getRowColRight(curRow, curCol);
|
|
99
|
+
case uiGridCellNavConstants.direction.UP:
|
|
100
|
+
return this.getRowColUp(curRow, curCol);
|
|
101
|
+
case uiGridCellNavConstants.direction.DOWN:
|
|
102
|
+
return this.getRowColDown(curRow, curCol);
|
|
103
|
+
case uiGridCellNavConstants.direction.PG_UP:
|
|
104
|
+
return this.getRowColPageUp(curRow, curCol);
|
|
105
|
+
case uiGridCellNavConstants.direction.PG_DOWN:
|
|
106
|
+
return this.getRowColPageDown(curRow, curCol);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
UiGridCellNav.prototype.initializeSelection = function () {
|
|
111
|
+
var focusableCols = this.getFocusableCols();
|
|
112
|
+
var focusableRows = this.getFocusableRows();
|
|
113
|
+
if (focusableCols.length === 0 || focusableRows.length === 0) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return new GridRowColumn(focusableRows[0], focusableCols[0]); // return same row
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
UiGridCellNav.prototype.getRowColLeft = function (curRow, curCol) {
|
|
121
|
+
var focusableCols = this.getFocusableCols();
|
|
122
|
+
var focusableRows = this.getFocusableRows();
|
|
123
|
+
var curColIndex = focusableCols.indexOf(curCol);
|
|
124
|
+
var curRowIndex = focusableRows.indexOf(curRow);
|
|
125
|
+
|
|
126
|
+
// could not find column in focusable Columns so set it to 1
|
|
127
|
+
if (curColIndex === -1) {
|
|
128
|
+
curColIndex = 1;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
var nextColIndex = curColIndex === 0 ? focusableCols.length - 1 : curColIndex - 1;
|
|
132
|
+
|
|
133
|
+
// get column to left
|
|
134
|
+
if (nextColIndex >= curColIndex) {
|
|
135
|
+
// On the first row
|
|
136
|
+
// if (curRowIndex === 0 && curColIndex === 0) {
|
|
137
|
+
// return null;
|
|
138
|
+
// }
|
|
139
|
+
if (curRowIndex === 0) {
|
|
140
|
+
return new GridRowColumn(curRow, focusableCols[nextColIndex]); // return same row
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// up one row and far right column
|
|
144
|
+
return new GridRowColumn(focusableRows[curRowIndex - 1], focusableCols[nextColIndex]);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
return new GridRowColumn(curRow, focusableCols[nextColIndex]);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
UiGridCellNav.prototype.getRowColRight = function (curRow, curCol) {
|
|
155
|
+
var focusableCols = this.getFocusableCols();
|
|
156
|
+
var focusableRows = this.getFocusableRows();
|
|
157
|
+
var curColIndex = focusableCols.indexOf(curCol);
|
|
158
|
+
var curRowIndex = focusableRows.indexOf(curRow);
|
|
159
|
+
|
|
160
|
+
// could not find column in focusable Columns so set it to 0
|
|
161
|
+
if (curColIndex === -1) {
|
|
162
|
+
curColIndex = 0;
|
|
163
|
+
}
|
|
164
|
+
var nextColIndex = curColIndex === focusableCols.length - 1 ? 0 : curColIndex + 1;
|
|
165
|
+
|
|
166
|
+
if (nextColIndex <= curColIndex) {
|
|
167
|
+
if (curRowIndex === focusableRows.length - 1) {
|
|
168
|
+
return new GridRowColumn(curRow, focusableCols[nextColIndex]); // return same row
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// down one row and far left column
|
|
172
|
+
return new GridRowColumn(focusableRows[curRowIndex + 1], focusableCols[nextColIndex]);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
return new GridRowColumn(curRow, focusableCols[nextColIndex]);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
UiGridCellNav.prototype.getRowColDown = function (curRow, curCol) {
|
|
181
|
+
var focusableCols = this.getFocusableCols();
|
|
182
|
+
var focusableRows = this.getFocusableRows();
|
|
183
|
+
var curColIndex = focusableCols.indexOf(curCol);
|
|
184
|
+
var curRowIndex = focusableRows.indexOf(curRow);
|
|
185
|
+
|
|
186
|
+
// could not find column in focusable Columns so set it to 0
|
|
187
|
+
if (curColIndex === -1) {
|
|
188
|
+
curColIndex = 0;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (curRowIndex === focusableRows.length - 1) {
|
|
192
|
+
return new GridRowColumn(curRow, focusableCols[curColIndex]); // return same row
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// down one row
|
|
196
|
+
return new GridRowColumn(focusableRows[curRowIndex + 1], focusableCols[curColIndex]);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
UiGridCellNav.prototype.getRowColPageDown = function (curRow, curCol) {
|
|
201
|
+
var focusableCols = this.getFocusableCols();
|
|
202
|
+
var focusableRows = this.getFocusableRows();
|
|
203
|
+
var curColIndex = focusableCols.indexOf(curCol);
|
|
204
|
+
var curRowIndex = focusableRows.indexOf(curRow);
|
|
205
|
+
|
|
206
|
+
// could not find column in focusable Columns so set it to 0
|
|
207
|
+
if (curColIndex === -1) {
|
|
208
|
+
curColIndex = 0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
var pageSize = this.bodyContainer.minRowsToRender();
|
|
212
|
+
if (curRowIndex >= focusableRows.length - pageSize) {
|
|
213
|
+
return new GridRowColumn(focusableRows[focusableRows.length - 1], focusableCols[curColIndex]); // return last row
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
// down one page
|
|
217
|
+
return new GridRowColumn(focusableRows[curRowIndex + pageSize], focusableCols[curColIndex]);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
UiGridCellNav.prototype.getRowColUp = function (curRow, curCol) {
|
|
222
|
+
var focusableCols = this.getFocusableCols();
|
|
223
|
+
var focusableRows = this.getFocusableRows();
|
|
224
|
+
var curColIndex = focusableCols.indexOf(curCol);
|
|
225
|
+
var curRowIndex = focusableRows.indexOf(curRow);
|
|
226
|
+
|
|
227
|
+
// could not find column in focusable Columns so set it to 0
|
|
228
|
+
if (curColIndex === -1) {
|
|
229
|
+
curColIndex = 0;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (curRowIndex === 0) {
|
|
233
|
+
return new GridRowColumn(curRow, focusableCols[curColIndex]); // return same row
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
// up one row
|
|
237
|
+
return new GridRowColumn(focusableRows[curRowIndex - 1], focusableCols[curColIndex]);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
UiGridCellNav.prototype.getRowColPageUp = function (curRow, curCol) {
|
|
242
|
+
var focusableCols = this.getFocusableCols();
|
|
243
|
+
var focusableRows = this.getFocusableRows();
|
|
244
|
+
var curColIndex = focusableCols.indexOf(curCol);
|
|
245
|
+
var curRowIndex = focusableRows.indexOf(curRow);
|
|
246
|
+
|
|
247
|
+
// could not find column in focusable Columns so set it to 0
|
|
248
|
+
if (curColIndex === -1) {
|
|
249
|
+
curColIndex = 0;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
var pageSize = this.bodyContainer.minRowsToRender();
|
|
253
|
+
if (curRowIndex - pageSize < 0) {
|
|
254
|
+
return new GridRowColumn(focusableRows[0], focusableCols[curColIndex]); // return first row
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
// up one page
|
|
258
|
+
return new GridRowColumn(focusableRows[curRowIndex - pageSize], focusableCols[curColIndex]);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
return UiGridCellNav;
|
|
262
|
+
}]);
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @ngdoc service
|
|
266
|
+
* @name ui.grid.cellNav.service:uiGridCellNavService
|
|
267
|
+
*
|
|
268
|
+
* @description Services for cell navigation features. If you don't like the key maps we use,
|
|
269
|
+
* or the direction cells navigation, override with a service decorator (see angular docs)
|
|
270
|
+
*/
|
|
271
|
+
module.service('uiGridCellNavService', ['uiGridConstants', 'uiGridCellNavConstants', '$q', 'uiGridCellNavFactory',
|
|
272
|
+
function (uiGridConstants, uiGridCellNavConstants, $q, UiGridCellNav) {
|
|
273
|
+
|
|
274
|
+
var service = {
|
|
275
|
+
|
|
276
|
+
initializeGrid: function (grid) {
|
|
277
|
+
grid.registerColumnBuilder(service.cellNavColumnBuilder);
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* @ngdoc object
|
|
282
|
+
* @name ui.grid.cellNav.Grid:cellNav
|
|
283
|
+
* @description cellNav properties added to grid class
|
|
284
|
+
*/
|
|
285
|
+
grid.cellNav = {};
|
|
286
|
+
grid.cellNav.lastRowCol = null;
|
|
287
|
+
grid.cellNav.focusedCells = [];
|
|
288
|
+
|
|
289
|
+
service.defaultGridOptions(grid.options);
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* @ngdoc object
|
|
293
|
+
* @name ui.grid.cellNav.api:PublicApi
|
|
294
|
+
*
|
|
295
|
+
* @description Public Api for cellNav feature
|
|
296
|
+
*/
|
|
297
|
+
var publicApi = {
|
|
298
|
+
events: {
|
|
299
|
+
cellNav: {
|
|
300
|
+
/**
|
|
301
|
+
* @ngdoc event
|
|
302
|
+
* @name navigate
|
|
303
|
+
* @eventOf ui.grid.cellNav.api:PublicApi
|
|
304
|
+
* @description raised when the active cell is changed
|
|
305
|
+
* <pre>
|
|
306
|
+
* gridApi.cellNav.on.navigate(scope,function(newRowcol, oldRowCol) {})
|
|
307
|
+
* </pre>
|
|
308
|
+
* @param {object} newRowCol new position
|
|
309
|
+
* @param {object} oldRowCol old position
|
|
310
|
+
*/
|
|
311
|
+
navigate: function (newRowCol, oldRowCol) {},
|
|
312
|
+
/**
|
|
313
|
+
* @ngdoc event
|
|
314
|
+
* @name viewPortKeyDown
|
|
315
|
+
* @eventOf ui.grid.cellNav.api:PublicApi
|
|
316
|
+
* @description is raised when the viewPort receives a keyDown event. Cells never get focus in uiGrid
|
|
317
|
+
* due to the difficulties of setting focus on a cell that is not visible in the viewport. Use this
|
|
318
|
+
* event whenever you need a keydown event on a cell
|
|
319
|
+
* <br/>
|
|
320
|
+
* @param {object} event keydown event
|
|
321
|
+
* @param {object} rowCol current rowCol position
|
|
322
|
+
*/
|
|
323
|
+
viewPortKeyDown: function (event, rowCol) {},
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* @ngdoc event
|
|
327
|
+
* @name viewPortKeyPress
|
|
328
|
+
* @eventOf ui.grid.cellNav.api:PublicApi
|
|
329
|
+
* @description is raised when the viewPort receives a keyPress event. Cells never get focus in uiGrid
|
|
330
|
+
* due to the difficulties of setting focus on a cell that is not visible in the viewport. Use this
|
|
331
|
+
* event whenever you need a keypress event on a cell
|
|
332
|
+
* <br/>
|
|
333
|
+
* @param {object} event keypress event
|
|
334
|
+
* @param {object} rowCol current rowCol position
|
|
335
|
+
*/
|
|
336
|
+
viewPortKeyPress: function (event, rowCol) {}
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
methods: {
|
|
340
|
+
cellNav: {
|
|
341
|
+
/**
|
|
342
|
+
* @ngdoc function
|
|
343
|
+
* @name scrollToFocus
|
|
344
|
+
* @methodOf ui.grid.cellNav.api:PublicApi
|
|
345
|
+
* @description brings the specified row and column into view, and sets focus
|
|
346
|
+
* to that cell
|
|
347
|
+
* @param {object} rowEntity gridOptions.data[] array instance to make visible and set focus
|
|
348
|
+
* @param {object} colDef to make visible and set focus
|
|
349
|
+
* @returns {promise} a promise that is resolved after any scrolling is finished
|
|
350
|
+
*/
|
|
351
|
+
scrollToFocus: function (rowEntity, colDef) {
|
|
352
|
+
return service.scrollToFocus(grid, rowEntity, colDef);
|
|
353
|
+
},
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* @ngdoc function
|
|
357
|
+
* @name getFocusedCell
|
|
358
|
+
* @methodOf ui.grid.cellNav.api:PublicApi
|
|
359
|
+
* @description returns the current (or last if Grid does not have focus) focused row and column
|
|
360
|
+
* <br> value is null if no selection has occurred
|
|
361
|
+
*/
|
|
362
|
+
getFocusedCell: function () {
|
|
363
|
+
return grid.cellNav.lastRowCol;
|
|
364
|
+
},
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* @ngdoc function
|
|
368
|
+
* @name getCurrentSelection
|
|
369
|
+
* @methodOf ui.grid.cellNav.api:PublicApi
|
|
370
|
+
* @description returns an array containing the current selection
|
|
371
|
+
* <br> array is empty if no selection has occurred
|
|
372
|
+
*/
|
|
373
|
+
getCurrentSelection: function () {
|
|
374
|
+
return grid.cellNav.focusedCells;
|
|
375
|
+
},
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* @ngdoc function
|
|
379
|
+
* @name rowColSelectIndex
|
|
380
|
+
* @methodOf ui.grid.cellNav.api:PublicApi
|
|
381
|
+
* @description returns the index in the order in which the GridRowColumn was selected, returns -1 if the GridRowColumn
|
|
382
|
+
* isn't selected
|
|
383
|
+
* @param {object} rowCol the rowCol to evaluate
|
|
384
|
+
*/
|
|
385
|
+
rowColSelectIndex: function (rowCol) {
|
|
386
|
+
// return gridUtil.arrayContainsObjectWithProperty(grid.cellNav.focusedCells, 'col.uid', rowCol.col.uid) &&
|
|
387
|
+
var index = -1;
|
|
388
|
+
for (var i = 0; i < grid.cellNav.focusedCells.length; i++) {
|
|
389
|
+
if (grid.cellNav.focusedCells[i].col.uid === rowCol.col.uid &&
|
|
390
|
+
grid.cellNav.focusedCells[i].row.uid === rowCol.row.uid) {
|
|
391
|
+
index = i;
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return index;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
grid.api.registerEventsFromObject(publicApi.events);
|
|
402
|
+
|
|
403
|
+
grid.api.registerMethodsFromObject(publicApi.methods);
|
|
404
|
+
},
|
|
405
|
+
|
|
406
|
+
defaultGridOptions: function (gridOptions) {
|
|
407
|
+
/**
|
|
408
|
+
* @ngdoc object
|
|
409
|
+
* @name ui.grid.cellNav.api:GridOptions
|
|
410
|
+
*
|
|
411
|
+
* @description GridOptions for cellNav feature, these are available to be
|
|
412
|
+
* set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
|
|
413
|
+
*/
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* @ngdoc object
|
|
417
|
+
* @name modifierKeysToMultiSelectCells
|
|
418
|
+
* @propertyOf ui.grid.cellNav.api:GridOptions
|
|
419
|
+
* @description Enable multiple cell selection only when using the ctrlKey or shiftKey.
|
|
420
|
+
* <br/>Defaults to false
|
|
421
|
+
*/
|
|
422
|
+
gridOptions.modifierKeysToMultiSelectCells = gridOptions.modifierKeysToMultiSelectCells === true;
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* @ngdoc array
|
|
426
|
+
* @name keyDownOverrides
|
|
427
|
+
* @propertyOf ui.grid.cellNav.api:GridOptions
|
|
428
|
+
* @description An array of event objects to override on keydown. If an event is overridden, the viewPortKeyDown event will
|
|
429
|
+
* be raised with the overridden events, allowing custom keydown behavior.
|
|
430
|
+
* <br/>Defaults to []
|
|
431
|
+
*/
|
|
432
|
+
gridOptions.keyDownOverrides = gridOptions.keyDownOverrides || [];
|
|
433
|
+
|
|
434
|
+
},
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* @ngdoc service
|
|
438
|
+
* @name decorateRenderContainers
|
|
439
|
+
* @methodOf ui.grid.cellNav.service:uiGridCellNavService
|
|
440
|
+
* @description decorates grid renderContainers with cellNav functions
|
|
441
|
+
*/
|
|
442
|
+
decorateRenderContainers: function (grid) {
|
|
443
|
+
|
|
444
|
+
var rightContainer = grid.hasRightContainer() ? grid.renderContainers.right : null;
|
|
445
|
+
var leftContainer = grid.hasLeftContainer() ? grid.renderContainers.left : null;
|
|
446
|
+
|
|
447
|
+
if (leftContainer !== null) {
|
|
448
|
+
grid.renderContainers.left.cellNav = new UiGridCellNav(grid.renderContainers.body, leftContainer, rightContainer, grid.renderContainers.body);
|
|
449
|
+
}
|
|
450
|
+
if (rightContainer !== null) {
|
|
451
|
+
grid.renderContainers.right.cellNav = new UiGridCellNav(grid.renderContainers.body, rightContainer, grid.renderContainers.body, leftContainer);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
grid.renderContainers.body.cellNav = new UiGridCellNav(grid.renderContainers.body, grid.renderContainers.body, leftContainer, rightContainer);
|
|
455
|
+
},
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* @ngdoc service
|
|
459
|
+
* @name getDirection
|
|
460
|
+
* @methodOf ui.grid.cellNav.service:uiGridCellNavService
|
|
461
|
+
* @description determines which direction to for a given keyDown event
|
|
462
|
+
* @returns {uiGridCellNavConstants.direction} direction
|
|
463
|
+
*/
|
|
464
|
+
getDirection: function (evt) {
|
|
465
|
+
if (evt.keyCode === uiGridConstants.keymap.LEFT ||
|
|
466
|
+
(evt.keyCode === uiGridConstants.keymap.TAB && evt.shiftKey)) {
|
|
467
|
+
return uiGridCellNavConstants.direction.LEFT;
|
|
468
|
+
}
|
|
469
|
+
if (evt.keyCode === uiGridConstants.keymap.RIGHT ||
|
|
470
|
+
evt.keyCode === uiGridConstants.keymap.TAB) {
|
|
471
|
+
return uiGridCellNavConstants.direction.RIGHT;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
if (evt.keyCode === uiGridConstants.keymap.UP ||
|
|
475
|
+
(evt.keyCode === uiGridConstants.keymap.ENTER && evt.shiftKey) ) {
|
|
476
|
+
return uiGridCellNavConstants.direction.UP;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (evt.keyCode === uiGridConstants.keymap.PG_UP) {
|
|
480
|
+
return uiGridCellNavConstants.direction.PG_UP;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if (evt.keyCode === uiGridConstants.keymap.DOWN ||
|
|
484
|
+
evt.keyCode === uiGridConstants.keymap.ENTER && !(evt.ctrlKey || evt.altKey)) {
|
|
485
|
+
return uiGridCellNavConstants.direction.DOWN;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (evt.keyCode === uiGridConstants.keymap.PG_DOWN) {
|
|
489
|
+
return uiGridCellNavConstants.direction.PG_DOWN;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
return null;
|
|
493
|
+
},
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* @ngdoc service
|
|
497
|
+
* @name cellNavColumnBuilder
|
|
498
|
+
* @methodOf ui.grid.cellNav.service:uiGridCellNavService
|
|
499
|
+
* @description columnBuilder function that adds cell navigation properties to grid column
|
|
500
|
+
* @returns {promise} promise that will load any needed templates when resolved
|
|
501
|
+
*/
|
|
502
|
+
cellNavColumnBuilder: function (colDef, col, gridOptions) {
|
|
503
|
+
var promises = [];
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* @ngdoc object
|
|
507
|
+
* @name ui.grid.cellNav.api:ColumnDef
|
|
508
|
+
*
|
|
509
|
+
* @description Column Definitions for cellNav feature, these are available to be
|
|
510
|
+
* set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
|
|
511
|
+
*/
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* @ngdoc object
|
|
515
|
+
* @name allowCellFocus
|
|
516
|
+
* @propertyOf ui.grid.cellNav.api:ColumnDef
|
|
517
|
+
* @description Enable focus on a cell within this column.
|
|
518
|
+
* <br/>Defaults to true
|
|
519
|
+
*/
|
|
520
|
+
colDef.allowCellFocus = colDef.allowCellFocus === undefined ? true : colDef.allowCellFocus;
|
|
521
|
+
|
|
522
|
+
return $q.all(promises);
|
|
523
|
+
},
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* @ngdoc method
|
|
527
|
+
* @methodOf ui.grid.cellNav.service:uiGridCellNavService
|
|
528
|
+
* @name scrollToFocus
|
|
529
|
+
* @description Scroll the grid such that the specified
|
|
530
|
+
* row and column is in view, and set focus to the cell in that row and column
|
|
531
|
+
* @param {Grid} grid the grid you'd like to act upon, usually available
|
|
532
|
+
* from gridApi.grid
|
|
533
|
+
* @param {object} rowEntity gridOptions.data[] array instance to make visible and set focus to
|
|
534
|
+
* @param {object} colDef to make visible and set focus to
|
|
535
|
+
* @returns {promise} a promise that is resolved after any scrolling is finished
|
|
536
|
+
*/
|
|
537
|
+
scrollToFocus: function (grid, rowEntity, colDef) {
|
|
538
|
+
var gridRow = null, gridCol = null;
|
|
539
|
+
|
|
540
|
+
if (typeof(rowEntity) !== 'undefined' && rowEntity !== null) {
|
|
541
|
+
gridRow = grid.getRow(rowEntity);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if (typeof(colDef) !== 'undefined' && colDef !== null) {
|
|
545
|
+
gridCol = grid.getColumn(colDef.name ? colDef.name : colDef.field);
|
|
546
|
+
}
|
|
547
|
+
return grid.api.core.scrollToIfNecessary(gridRow, gridCol).then(function () {
|
|
548
|
+
var rowCol = { row: gridRow, col: gridCol };
|
|
549
|
+
|
|
550
|
+
// Broadcast the navigation
|
|
551
|
+
if (gridRow !== null && gridCol !== null) {
|
|
552
|
+
grid.cellNav.broadcastCellNav(rowCol, null, null);
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
},
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* @ngdoc method
|
|
560
|
+
* @methodOf ui.grid.cellNav.service:uiGridCellNavService
|
|
561
|
+
* @name getLeftWidth
|
|
562
|
+
* @description Get the current drawn width of the columns in the
|
|
563
|
+
* grid up to the numbered column, and add an apportionment for the
|
|
564
|
+
* column that we're on. So if we are on column 0, we want to scroll
|
|
565
|
+
* 0% (i.e. exclude this column from calc). If we're on the last column
|
|
566
|
+
* we want to scroll to 100% (i.e. include this column in the calc). So
|
|
567
|
+
* we include (thisColIndex / totalNumberCols) % of this column width
|
|
568
|
+
* @param {Grid} grid the grid you'd like to act upon, usually available
|
|
569
|
+
* from gridApi.grid
|
|
570
|
+
* @param {GridColumn} upToCol the column to total up to and including
|
|
571
|
+
*/
|
|
572
|
+
getLeftWidth: function (grid, upToCol) {
|
|
573
|
+
var width = 0;
|
|
574
|
+
|
|
575
|
+
if (!upToCol) {
|
|
576
|
+
return width;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
var lastIndex = grid.renderContainers.body.visibleColumnCache.indexOf( upToCol );
|
|
580
|
+
|
|
581
|
+
// total column widths up-to but not including the passed in column
|
|
582
|
+
grid.renderContainers.body.visibleColumnCache.forEach( function( col, index ) {
|
|
583
|
+
if ( index < lastIndex ) {
|
|
584
|
+
width += col.drawnWidth;
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
// pro-rata the final column based on % of total columns.
|
|
589
|
+
var percentage = lastIndex === 0 ? 0 : (lastIndex + 1) / grid.renderContainers.body.visibleColumnCache.length;
|
|
590
|
+
width += upToCol.drawnWidth * percentage;
|
|
591
|
+
|
|
592
|
+
return width;
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
return service;
|
|
597
|
+
}]);
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* @ngdoc directive
|
|
601
|
+
* @name ui.grid.cellNav.directive:uiCellNav
|
|
602
|
+
* @element div
|
|
603
|
+
* @restrict EA
|
|
604
|
+
*
|
|
605
|
+
* @description Adds cell navigation features to the grid columns
|
|
606
|
+
*
|
|
607
|
+
* @example
|
|
608
|
+
<example module="app">
|
|
609
|
+
<file name="app.js">
|
|
610
|
+
var app = angular.module('app', ['ui.grid', 'ui.grid.cellNav']);
|
|
611
|
+
|
|
612
|
+
app.controller('MainCtrl', ['$scope', function ($scope) {
|
|
613
|
+
$scope.data = [
|
|
614
|
+
{ name: 'Bob', title: 'CEO' },
|
|
615
|
+
{ name: 'Frank', title: 'Lowly Developer' }
|
|
616
|
+
];
|
|
617
|
+
|
|
618
|
+
$scope.columnDefs = [
|
|
619
|
+
{name: 'name'},
|
|
620
|
+
{name: 'title'}
|
|
621
|
+
];
|
|
622
|
+
}]);
|
|
623
|
+
</file>
|
|
624
|
+
<file name="index.html">
|
|
625
|
+
<div ng-controller="MainCtrl">
|
|
626
|
+
<div ui-grid="{ data: data, columnDefs: columnDefs }" ui-grid-cellnav></div>
|
|
627
|
+
</div>
|
|
628
|
+
</file>
|
|
629
|
+
</example>
|
|
630
|
+
*/
|
|
631
|
+
module.directive('uiGridCellnav', ['uiGridCellNavService', 'uiGridCellNavConstants', 'uiGridConstants', 'GridRowColumn', '$compile', 'i18nService',
|
|
632
|
+
function (uiGridCellNavService, uiGridCellNavConstants, uiGridConstants, GridRowColumn, $compile, i18nService) {
|
|
633
|
+
return {
|
|
634
|
+
replace: true,
|
|
635
|
+
priority: -150,
|
|
636
|
+
require: '^uiGrid',
|
|
637
|
+
scope: false,
|
|
638
|
+
controller: function () {},
|
|
639
|
+
compile: function () {
|
|
640
|
+
return {
|
|
641
|
+
pre: function ($scope, $elm, $attrs, uiGridCtrl) {
|
|
642
|
+
var _scope = $scope;
|
|
643
|
+
|
|
644
|
+
var grid = uiGridCtrl.grid;
|
|
645
|
+
uiGridCellNavService.initializeGrid(grid);
|
|
646
|
+
|
|
647
|
+
uiGridCtrl.cellNav = {};
|
|
648
|
+
|
|
649
|
+
// Ensure that the object has all of the methods we expect it to
|
|
650
|
+
uiGridCtrl.cellNav.makeRowCol = function (obj) {
|
|
651
|
+
if (!(obj instanceof GridRowColumn)) {
|
|
652
|
+
obj = new GridRowColumn(obj.row, obj.col);
|
|
653
|
+
}
|
|
654
|
+
return obj;
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
uiGridCtrl.cellNav.getActiveCell = function () {
|
|
658
|
+
var elms = $elm[0].getElementsByClassName('ui-grid-cell-focus');
|
|
659
|
+
if (elms.length > 0) {
|
|
660
|
+
return elms[0];
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
return undefined;
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
uiGridCtrl.cellNav.broadcastCellNav = grid.cellNav.broadcastCellNav = function (newRowCol, modifierDown, originEvt) {
|
|
667
|
+
modifierDown = !(modifierDown === undefined || !modifierDown);
|
|
668
|
+
|
|
669
|
+
newRowCol = uiGridCtrl.cellNav.makeRowCol(newRowCol);
|
|
670
|
+
|
|
671
|
+
uiGridCtrl.cellNav.broadcastFocus(newRowCol, modifierDown, originEvt);
|
|
672
|
+
_scope.$broadcast(uiGridCellNavConstants.CELL_NAV_EVENT, newRowCol, modifierDown, originEvt);
|
|
673
|
+
};
|
|
674
|
+
|
|
675
|
+
uiGridCtrl.cellNav.clearFocus = grid.cellNav.clearFocus = function () {
|
|
676
|
+
grid.cellNav.focusedCells = [];
|
|
677
|
+
_scope.$broadcast(uiGridCellNavConstants.CELL_NAV_EVENT);
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
uiGridCtrl.cellNav.broadcastFocus = function (rowCol, modifierDown, originEvt) {
|
|
681
|
+
modifierDown = !(modifierDown === undefined || !modifierDown);
|
|
682
|
+
|
|
683
|
+
rowCol = uiGridCtrl.cellNav.makeRowCol(rowCol);
|
|
684
|
+
|
|
685
|
+
var row = rowCol.row,
|
|
686
|
+
col = rowCol.col;
|
|
687
|
+
|
|
688
|
+
var rowColSelectIndex = uiGridCtrl.grid.api.cellNav.rowColSelectIndex(rowCol);
|
|
689
|
+
|
|
690
|
+
if (grid.cellNav.lastRowCol === null || rowColSelectIndex === -1 || (grid.cellNav.lastRowCol.col === col && grid.cellNav.lastRowCol.row === row)) {
|
|
691
|
+
var newRowCol = new GridRowColumn(row, col);
|
|
692
|
+
|
|
693
|
+
if (grid.cellNav.lastRowCol === null || grid.cellNav.lastRowCol.row !== newRowCol.row || grid.cellNav.lastRowCol.col !== newRowCol.col || grid.options.enableCellEditOnFocus) {
|
|
694
|
+
grid.api.cellNav.raise.navigate(newRowCol, grid.cellNav.lastRowCol, originEvt);
|
|
695
|
+
grid.cellNav.lastRowCol = newRowCol;
|
|
696
|
+
}
|
|
697
|
+
if (uiGridCtrl.grid.options.modifierKeysToMultiSelectCells && modifierDown) {
|
|
698
|
+
grid.cellNav.focusedCells.push(rowCol);
|
|
699
|
+
} else {
|
|
700
|
+
grid.cellNav.focusedCells = [rowCol];
|
|
701
|
+
}
|
|
702
|
+
} else if (grid.options.modifierKeysToMultiSelectCells && modifierDown &&
|
|
703
|
+
rowColSelectIndex >= 0) {
|
|
704
|
+
|
|
705
|
+
grid.cellNav.focusedCells.splice(rowColSelectIndex, 1);
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
|
|
709
|
+
uiGridCtrl.cellNav.handleKeyDown = function (evt) {
|
|
710
|
+
var direction = uiGridCellNavService.getDirection(evt);
|
|
711
|
+
if (direction === null) {
|
|
712
|
+
return null;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
var containerId = 'body';
|
|
716
|
+
if (evt.uiGridTargetRenderContainerId) {
|
|
717
|
+
containerId = evt.uiGridTargetRenderContainerId;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// Get the last-focused row+col combo
|
|
721
|
+
var lastRowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
|
|
722
|
+
if (lastRowCol) {
|
|
723
|
+
// Figure out which new row+combo we're navigating to
|
|
724
|
+
var rowCol = uiGridCtrl.grid.renderContainers[containerId].cellNav.getNextRowCol(direction, lastRowCol.row, lastRowCol.col);
|
|
725
|
+
var focusableCols = uiGridCtrl.grid.renderContainers[containerId].cellNav.getFocusableCols();
|
|
726
|
+
var rowColSelectIndex = uiGridCtrl.grid.api.cellNav.rowColSelectIndex(rowCol);
|
|
727
|
+
// Shift+tab on top-left cell should exit cellnav on render container
|
|
728
|
+
if (
|
|
729
|
+
// Navigating left
|
|
730
|
+
direction === uiGridCellNavConstants.direction.LEFT &&
|
|
731
|
+
// New col is last col (i.e. wrap around)
|
|
732
|
+
rowCol.col === focusableCols[focusableCols.length - 1] &&
|
|
733
|
+
// Staying on same row, which means we're at first row
|
|
734
|
+
rowCol.row === lastRowCol.row &&
|
|
735
|
+
evt.keyCode === uiGridConstants.keymap.TAB &&
|
|
736
|
+
evt.shiftKey
|
|
737
|
+
) {
|
|
738
|
+
grid.cellNav.focusedCells.splice(rowColSelectIndex, 1);
|
|
739
|
+
uiGridCtrl.cellNav.clearFocus();
|
|
740
|
+
return true;
|
|
741
|
+
}
|
|
742
|
+
// Tab on bottom-right cell should exit cellnav on render container
|
|
743
|
+
else if (
|
|
744
|
+
direction === uiGridCellNavConstants.direction.RIGHT &&
|
|
745
|
+
// New col is first col (i.e. wrap around)
|
|
746
|
+
rowCol.col === focusableCols[0] &&
|
|
747
|
+
// Staying on same row, which means we're at first row
|
|
748
|
+
rowCol.row === lastRowCol.row &&
|
|
749
|
+
evt.keyCode === uiGridConstants.keymap.TAB &&
|
|
750
|
+
!evt.shiftKey
|
|
751
|
+
) {
|
|
752
|
+
grid.cellNav.focusedCells.splice(rowColSelectIndex, 1);
|
|
753
|
+
uiGridCtrl.cellNav.clearFocus();
|
|
754
|
+
return true;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// Scroll to the new cell, if it's not completely visible within the render container's viewport
|
|
758
|
+
grid.scrollToIfNecessary(rowCol.row, rowCol.col).then(function () {
|
|
759
|
+
uiGridCtrl.cellNav.broadcastCellNav(rowCol, null, evt);
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
evt.stopPropagation();
|
|
764
|
+
evt.preventDefault();
|
|
765
|
+
|
|
766
|
+
return false;
|
|
767
|
+
}
|
|
768
|
+
};
|
|
769
|
+
},
|
|
770
|
+
post: function ($scope, $elm, $attrs, uiGridCtrl) {
|
|
771
|
+
var grid = uiGridCtrl.grid;
|
|
772
|
+
var usesAria = true;
|
|
773
|
+
|
|
774
|
+
// Detect whether we are using ngAria
|
|
775
|
+
// (if ngAria module is not used then the stuff inside addAriaLiveRegion
|
|
776
|
+
// is not used and provides extra fluff)
|
|
777
|
+
try {
|
|
778
|
+
angular.module('ngAria');
|
|
779
|
+
}
|
|
780
|
+
catch (err) {
|
|
781
|
+
usesAria = false;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
function addAriaLiveRegion() {
|
|
785
|
+
// Thanks to google docs for the inspiration behind how to do this
|
|
786
|
+
// XXX: Why is this entire mess nessasary?
|
|
787
|
+
// Because browsers take a lot of coercing to get them to read out live regions
|
|
788
|
+
// http://www.paciellogroup.com/blog/2012/06/html5-accessibility-chops-aria-rolealert-browser-support/
|
|
789
|
+
var ariaNotifierDomElt = '<div ' +
|
|
790
|
+
'id="' + grid.id +'-aria-speakable" ' +
|
|
791
|
+
'class="ui-grid-a11y-ariascreenreader-speakable ui-grid-offscreen" ' +
|
|
792
|
+
'aria-live="assertive" ' +
|
|
793
|
+
'role="alert" ' +
|
|
794
|
+
'aria-atomic="true" ' +
|
|
795
|
+
'aria-hidden="false" ' +
|
|
796
|
+
'aria-relevant="additions" ' +
|
|
797
|
+
'>' +
|
|
798
|
+
' ' +
|
|
799
|
+
'</div>';
|
|
800
|
+
|
|
801
|
+
var ariaNotifier = $compile(ariaNotifierDomElt)($scope);
|
|
802
|
+
$elm.prepend(ariaNotifier);
|
|
803
|
+
$scope.$on(uiGridCellNavConstants.CELL_NAV_EVENT, function (evt, rowCol, modifierDown, originEvt) {
|
|
804
|
+
/*
|
|
805
|
+
* If the cell nav event was because of a focus event then we don't want to
|
|
806
|
+
* change the notifier text.
|
|
807
|
+
* Reasoning: Voice Over fires a focus events when moving arround the grid.
|
|
808
|
+
* If the screen reader is handing the grid nav properly then we don't need to
|
|
809
|
+
* use the alert to notify the user of the movement.
|
|
810
|
+
* In all other cases we do want a notification event.
|
|
811
|
+
*/
|
|
812
|
+
if (originEvt && originEvt.type === 'focus') {return;}
|
|
813
|
+
|
|
814
|
+
function setNotifyText(text) {
|
|
815
|
+
if (text === ariaNotifier.text().trim()) {return;}
|
|
816
|
+
ariaNotifier[0].style.clip = 'rect(0px,0px,0px,0px)';
|
|
817
|
+
/*
|
|
818
|
+
* This is how google docs handles clearing the div. Seems to work better than setting the text of the div to ''
|
|
819
|
+
*/
|
|
820
|
+
ariaNotifier[0].innerHTML = "";
|
|
821
|
+
ariaNotifier[0].style.visibility = 'hidden';
|
|
822
|
+
ariaNotifier[0].style.visibility = 'visible';
|
|
823
|
+
if (text !== '') {
|
|
824
|
+
ariaNotifier[0].style.clip = 'auto';
|
|
825
|
+
/*
|
|
826
|
+
* The space after the text is something that google docs does.
|
|
827
|
+
*/
|
|
828
|
+
ariaNotifier[0].appendChild(document.createTextNode(text + " "));
|
|
829
|
+
ariaNotifier[0].style.visibility = 'hidden';
|
|
830
|
+
ariaNotifier[0].style.visibility = 'visible';
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
function getAppendedColumnHeaderText(col) {
|
|
835
|
+
return ', ' + i18nService.getSafeText('headerCell.aria.column') + ' ' + col.displayName;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
function getCellDisplayValue(currentRowColumn) {
|
|
839
|
+
var prefix = '';
|
|
840
|
+
|
|
841
|
+
if (currentRowColumn.col.field === 'selectionRowHeaderCol') {
|
|
842
|
+
// This is the case when the 'selection' feature is used in the grid and the user has moved
|
|
843
|
+
// to or inside of the left grid container which holds the checkboxes for selecting rows.
|
|
844
|
+
// This is necessary for Accessibility. Without this a screen reader cannot determine if the row
|
|
845
|
+
// is or is not currently selected.
|
|
846
|
+
prefix = (currentRowColumn.row.isSelected ? i18nService.getSafeText('search.aria.selected') : i18nService.getSafeText('search.aria.notSelected')) + ', ';
|
|
847
|
+
}
|
|
848
|
+
return prefix + grid.getCellDisplayValue(currentRowColumn.row, currentRowColumn.col);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
var values = [];
|
|
852
|
+
var currentSelection = grid.api.cellNav.getCurrentSelection();
|
|
853
|
+
for (var i = 0; i < currentSelection.length; i++) {
|
|
854
|
+
var cellDisplayValue = getCellDisplayValue(currentSelection[i]) + getAppendedColumnHeaderText(currentSelection[i].col);
|
|
855
|
+
values.push(cellDisplayValue);
|
|
856
|
+
}
|
|
857
|
+
setNotifyText(values.toString());
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
// Only add the ngAria stuff it will be used
|
|
861
|
+
if (usesAria) {
|
|
862
|
+
addAriaLiveRegion();
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
};
|
|
868
|
+
}]);
|
|
869
|
+
|
|
870
|
+
module.directive('uiGridRenderContainer', ['$timeout', 'gridUtil', 'uiGridCellNavService', '$compile','uiGridCellNavConstants',
|
|
871
|
+
function ($timeout, gridUtil, uiGridCellNavService, $compile, uiGridCellNavConstants) {
|
|
872
|
+
return {
|
|
873
|
+
replace: true,
|
|
874
|
+
priority: -99999, // this needs to run very last
|
|
875
|
+
require: ['^uiGrid', 'uiGridRenderContainer', '?^uiGridCellnav'],
|
|
876
|
+
scope: false,
|
|
877
|
+
compile: function () {
|
|
878
|
+
return {
|
|
879
|
+
post: function ($scope, $elm, $attrs, controllers) {
|
|
880
|
+
var uiGridCtrl = controllers[0],
|
|
881
|
+
renderContainerCtrl = controllers[1],
|
|
882
|
+
uiGridCellnavCtrl = controllers[2];
|
|
883
|
+
|
|
884
|
+
// Skip attaching cell-nav specific logic if the directive is not attached above us
|
|
885
|
+
if (!uiGridCtrl.grid.api.cellNav) { return; }
|
|
886
|
+
|
|
887
|
+
var containerId = renderContainerCtrl.containerId;
|
|
888
|
+
|
|
889
|
+
var grid = uiGridCtrl.grid;
|
|
890
|
+
|
|
891
|
+
// run each time a render container is created
|
|
892
|
+
uiGridCellNavService.decorateRenderContainers(grid);
|
|
893
|
+
|
|
894
|
+
// focusser only created for body
|
|
895
|
+
if (containerId !== 'body') {
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
if (uiGridCtrl.grid.options.modifierKeysToMultiSelectCells) {
|
|
900
|
+
$elm.attr('aria-multiselectable', true);
|
|
901
|
+
}
|
|
902
|
+
else {
|
|
903
|
+
$elm.attr('aria-multiselectable', false);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// add an element with no dimensions that can be used to set focus and capture keystrokes
|
|
907
|
+
var focuser = $compile('<div class="ui-grid-focuser" role="region" aria-live="assertive" aria-atomic="false" tabindex="0" aria-controls="' + grid.id +'-aria-speakable '+ grid.id + '-grid-container' +'" aria-owns="' + grid.id + '-grid-container' + '"></div>')($scope);
|
|
908
|
+
$elm.append(focuser);
|
|
909
|
+
|
|
910
|
+
focuser.on('focus', function (evt) {
|
|
911
|
+
evt.uiGridTargetRenderContainerId = containerId;
|
|
912
|
+
var rowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
|
|
913
|
+
if (rowCol === null) {
|
|
914
|
+
rowCol = uiGridCtrl.grid.renderContainers[containerId].cellNav.getNextRowCol(uiGridCellNavConstants.direction.DOWN, null, null);
|
|
915
|
+
if (rowCol.row && rowCol.col) {
|
|
916
|
+
uiGridCtrl.cellNav.broadcastCellNav(rowCol);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
});
|
|
920
|
+
|
|
921
|
+
uiGridCellnavCtrl.setAriaActivedescendant = function(id) {
|
|
922
|
+
$elm.attr('aria-activedescendant', id);
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
uiGridCellnavCtrl.removeAriaActivedescendant = function(id) {
|
|
926
|
+
if ($elm.attr('aria-activedescendant') === id) {
|
|
927
|
+
$elm.attr('aria-activedescendant', '');
|
|
928
|
+
}
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
uiGridCtrl.focus = function () {
|
|
933
|
+
gridUtil.focus.byElement(focuser[0]);
|
|
934
|
+
// allow for first time grid focus
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
var viewPortKeyDownWasRaisedForRowCol = null;
|
|
938
|
+
// Bind to keydown events in the render container
|
|
939
|
+
focuser.on('keydown', function (evt) {
|
|
940
|
+
evt.uiGridTargetRenderContainerId = containerId;
|
|
941
|
+
var rowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
|
|
942
|
+
var raiseViewPortKeyDown = uiGridCtrl.grid.options.keyDownOverrides.some(function (override) {
|
|
943
|
+
return Object.keys(override).every( function (property) {
|
|
944
|
+
return override[property] === evt[property];
|
|
945
|
+
});
|
|
946
|
+
});
|
|
947
|
+
var result = raiseViewPortKeyDown ? null : uiGridCtrl.cellNav.handleKeyDown(evt);
|
|
948
|
+
if (result === null) {
|
|
949
|
+
uiGridCtrl.grid.api.cellNav.raise.viewPortKeyDown(evt, rowCol, uiGridCtrl.cellNav.handleKeyDown);
|
|
950
|
+
viewPortKeyDownWasRaisedForRowCol = rowCol;
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
// Bind to keypress events in the render container
|
|
954
|
+
// keypress events are needed by edit function so the key press
|
|
955
|
+
// that initiated an edit is not lost
|
|
956
|
+
// must fire the event in a timeout so the editor can
|
|
957
|
+
// initialize and subscribe to the event on another event loop
|
|
958
|
+
focuser.on('keypress', function (evt) {
|
|
959
|
+
if (viewPortKeyDownWasRaisedForRowCol) {
|
|
960
|
+
$timeout(function () {
|
|
961
|
+
uiGridCtrl.grid.api.cellNav.raise.viewPortKeyPress(evt, viewPortKeyDownWasRaisedForRowCol);
|
|
962
|
+
}, 4);
|
|
963
|
+
|
|
964
|
+
viewPortKeyDownWasRaisedForRowCol = null;
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
|
|
968
|
+
$scope.$on('$destroy', function() {
|
|
969
|
+
// Remove all event handlers associated with this focuser.
|
|
970
|
+
focuser.off();
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
}
|
|
975
|
+
};
|
|
976
|
+
}]);
|
|
977
|
+
|
|
978
|
+
module.directive('uiGridViewport',
|
|
979
|
+
function () {
|
|
980
|
+
return {
|
|
981
|
+
replace: true,
|
|
982
|
+
priority: -99999, // this needs to run very last
|
|
983
|
+
require: ['^uiGrid', '^uiGridRenderContainer', '?^uiGridCellnav'],
|
|
984
|
+
scope: false,
|
|
985
|
+
compile: function () {
|
|
986
|
+
return {
|
|
987
|
+
pre: function ($scope, $elm, $attrs, uiGridCtrl) {
|
|
988
|
+
},
|
|
989
|
+
post: function ($scope, $elm, $attrs, controllers) {
|
|
990
|
+
var uiGridCtrl = controllers[0],
|
|
991
|
+
renderContainerCtrl = controllers[1];
|
|
992
|
+
|
|
993
|
+
// Skip attaching cell-nav specific logic if the directive is not attached above us
|
|
994
|
+
if (!uiGridCtrl.grid.api.cellNav) { return; }
|
|
995
|
+
|
|
996
|
+
var containerId = renderContainerCtrl.containerId;
|
|
997
|
+
// no need to process for other containers
|
|
998
|
+
if (containerId !== 'body') {
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
var grid = uiGridCtrl.grid;
|
|
1003
|
+
|
|
1004
|
+
grid.api.core.on.scrollBegin($scope, function () {
|
|
1005
|
+
|
|
1006
|
+
// Skip if there's no currently-focused cell
|
|
1007
|
+
var lastRowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
|
|
1008
|
+
if (lastRowCol === null) {
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// if not in my container, move on
|
|
1013
|
+
// todo: worry about horiz scroll
|
|
1014
|
+
if (!renderContainerCtrl.colContainer.containsColumn(lastRowCol.col)) {
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
uiGridCtrl.cellNav.clearFocus();
|
|
1019
|
+
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1022
|
+
grid.api.core.on.scrollEnd($scope, function (args) {
|
|
1023
|
+
// Skip if there's no currently-focused cell
|
|
1024
|
+
var lastRowCol = uiGridCtrl.grid.api.cellNav.getFocusedCell();
|
|
1025
|
+
if (lastRowCol === null) {
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
// if not in my container, move on
|
|
1030
|
+
// todo: worry about horiz scroll
|
|
1031
|
+
if (!renderContainerCtrl.colContainer.containsColumn(lastRowCol.col)) {
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
uiGridCtrl.cellNav.broadcastCellNav(lastRowCol);
|
|
1036
|
+
});
|
|
1037
|
+
|
|
1038
|
+
grid.api.cellNav.on.navigate($scope, function () {
|
|
1039
|
+
// focus again because it can be lost
|
|
1040
|
+
uiGridCtrl.focus();
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
};
|
|
1046
|
+
});
|
|
1047
|
+
|
|
1048
|
+
/**
|
|
1049
|
+
* @ngdoc directive
|
|
1050
|
+
* @name ui.grid.cellNav.directive:uiGridCell
|
|
1051
|
+
* @element div
|
|
1052
|
+
* @restrict A
|
|
1053
|
+
* @description Stacks on top of ui.grid.uiGridCell to provide cell navigation
|
|
1054
|
+
*/
|
|
1055
|
+
module.directive('uiGridCell', ['uiGridCellNavConstants', 'uiGridConstants', 'GridRowColumn',
|
|
1056
|
+
function (uiGridCellNavConstants, uiGridConstants, GridRowColumn) {
|
|
1057
|
+
return {
|
|
1058
|
+
priority: -150, // run after default uiGridCell directive and ui.grid.edit uiGridCell
|
|
1059
|
+
restrict: 'A',
|
|
1060
|
+
require: ['^uiGrid', '?^uiGridCellnav'],
|
|
1061
|
+
scope: false,
|
|
1062
|
+
link: function ($scope, $elm, $attrs, controllers) {
|
|
1063
|
+
var uiGridCtrl = controllers[0],
|
|
1064
|
+
uiGridCellnavCtrl = controllers[1];
|
|
1065
|
+
// Skip attaching cell-nav specific logic if the directive is not attached above us
|
|
1066
|
+
if (!uiGridCtrl.grid.api.cellNav) { return; }
|
|
1067
|
+
|
|
1068
|
+
if (!$scope.col.colDef.allowCellFocus) {
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// Convinience local variables
|
|
1073
|
+
var grid = uiGridCtrl.grid;
|
|
1074
|
+
$scope.focused = false;
|
|
1075
|
+
|
|
1076
|
+
// Make this cell focusable but only with javascript/a mouse click
|
|
1077
|
+
$elm.attr('tabindex', -1);
|
|
1078
|
+
|
|
1079
|
+
// When a cell is clicked, broadcast a cellNav event saying that this row+col combo is now focused
|
|
1080
|
+
$elm.find('div').on('click', function (evt) {
|
|
1081
|
+
uiGridCtrl.cellNav.broadcastCellNav(new GridRowColumn($scope.row, $scope.col), evt.ctrlKey || evt.metaKey, evt);
|
|
1082
|
+
|
|
1083
|
+
evt.stopPropagation();
|
|
1084
|
+
$scope.$apply();
|
|
1085
|
+
});
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
/*
|
|
1089
|
+
* XXX Hack for screen readers.
|
|
1090
|
+
* This allows the grid to focus using only the screen reader cursor.
|
|
1091
|
+
* Since the focus event doesn't include key press information we can't use it
|
|
1092
|
+
* as our primary source of the event.
|
|
1093
|
+
*/
|
|
1094
|
+
$elm.on('mousedown', preventMouseDown);
|
|
1095
|
+
|
|
1096
|
+
// turn on and off for edit events
|
|
1097
|
+
if (uiGridCtrl.grid.api.edit) {
|
|
1098
|
+
uiGridCtrl.grid.api.edit.on.beginCellEdit($scope, function () {
|
|
1099
|
+
$elm.off('mousedown', preventMouseDown);
|
|
1100
|
+
});
|
|
1101
|
+
|
|
1102
|
+
uiGridCtrl.grid.api.edit.on.afterCellEdit($scope, function () {
|
|
1103
|
+
$elm.on('mousedown', preventMouseDown);
|
|
1104
|
+
});
|
|
1105
|
+
|
|
1106
|
+
uiGridCtrl.grid.api.edit.on.cancelCellEdit($scope, function () {
|
|
1107
|
+
$elm.on('mousedown', preventMouseDown);
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
// In case we created a new row, and we are the new created row by ngRepeat
|
|
1112
|
+
// then this cell content might have been selected previously
|
|
1113
|
+
refreshCellFocus();
|
|
1114
|
+
|
|
1115
|
+
function preventMouseDown(evt) {
|
|
1116
|
+
// Prevents the foucus event from firing if the click event is already going to fire.
|
|
1117
|
+
// If both events fire it will cause bouncing behavior.
|
|
1118
|
+
evt.preventDefault();
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
// You can only focus on elements with a tabindex value
|
|
1122
|
+
$elm.on('focus', function (evt) {
|
|
1123
|
+
uiGridCtrl.cellNav.broadcastCellNav(new GridRowColumn($scope.row, $scope.col), false, evt);
|
|
1124
|
+
evt.stopPropagation();
|
|
1125
|
+
$scope.$apply();
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1128
|
+
// This event is fired for all cells. If the cell matches, then focus is set
|
|
1129
|
+
$scope.$on(uiGridCellNavConstants.CELL_NAV_EVENT, refreshCellFocus);
|
|
1130
|
+
|
|
1131
|
+
// Refresh cell focus when a new row id added to the grid
|
|
1132
|
+
var dataChangeDereg = uiGridCtrl.grid.registerDataChangeCallback(function (grid) {
|
|
1133
|
+
// Clear the focus if it's set to avoid the wrong cell getting focused during
|
|
1134
|
+
// a short period of time (from now until $timeout function executed)
|
|
1135
|
+
clearFocus();
|
|
1136
|
+
|
|
1137
|
+
$scope.$applyAsync(refreshCellFocus);
|
|
1138
|
+
}, [uiGridConstants.dataChange.ROW]);
|
|
1139
|
+
|
|
1140
|
+
function refreshCellFocus() {
|
|
1141
|
+
var isFocused = grid.cellNav.focusedCells.some(function (focusedRowCol, index) {
|
|
1142
|
+
return (focusedRowCol.row === $scope.row && focusedRowCol.col === $scope.col);
|
|
1143
|
+
});
|
|
1144
|
+
if (isFocused) {
|
|
1145
|
+
setFocused();
|
|
1146
|
+
} else {
|
|
1147
|
+
clearFocus();
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
function setFocused() {
|
|
1152
|
+
if (!$scope.focused) {
|
|
1153
|
+
var div = $elm.find('div');
|
|
1154
|
+
div.addClass('ui-grid-cell-focus');
|
|
1155
|
+
$elm.attr('aria-selected', true);
|
|
1156
|
+
uiGridCellnavCtrl.setAriaActivedescendant($elm.attr('id'));
|
|
1157
|
+
$scope.focused = true;
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
function clearFocus() {
|
|
1162
|
+
if ($scope.focused) {
|
|
1163
|
+
var div = $elm.find('div');
|
|
1164
|
+
div.removeClass('ui-grid-cell-focus');
|
|
1165
|
+
$elm.attr('aria-selected', false);
|
|
1166
|
+
uiGridCellnavCtrl.removeAriaActivedescendant($elm.attr('id'));
|
|
1167
|
+
$scope.focused = false;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
$scope.$on('$destroy', function () {
|
|
1172
|
+
dataChangeDereg();
|
|
1173
|
+
|
|
1174
|
+
// .off withouth paramaters removes all handlers
|
|
1175
|
+
$elm.find('div').off();
|
|
1176
|
+
$elm.off();
|
|
1177
|
+
});
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
}]);
|
|
1181
|
+
})();
|