neo.mjs 8.0.0 → 8.0.1
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/apps/ServiceWorker.mjs +2 -2
- package/apps/portal/index.html +1 -1
- package/apps/portal/view/about/Container.mjs +0 -2
- package/apps/portal/view/about/MemberContainer.mjs +1 -20
- package/apps/portal/view/home/FooterContainer.mjs +1 -5
- package/examples/ConfigurationViewport.mjs +37 -32
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/grid/cellEditing/MainContainer.mjs +175 -0
- package/examples/grid/cellEditing/MainContainerStateProvider.mjs +62 -0
- package/examples/grid/cellEditing/MainModel.mjs +30 -0
- package/examples/grid/cellEditing/MainStore.mjs +54 -0
- package/examples/grid/cellEditing/app.mjs +6 -0
- package/examples/grid/cellEditing/index.html +11 -0
- package/examples/grid/cellEditing/neo-config.json +6 -0
- package/examples/grid/container/MainContainer.mjs +7 -6
- package/examples/grid/covid/GridContainer.mjs +36 -36
- package/examples/grid/covid/Util.mjs +1 -1
- package/examples/table/cellEditing/MainContainer.mjs +174 -0
- package/examples/table/cellEditing/MainContainerStateProvider.mjs +62 -0
- package/examples/table/cellEditing/MainModel.mjs +30 -0
- package/examples/table/cellEditing/MainStore.mjs +54 -0
- package/examples/table/cellEditing/app.mjs +6 -0
- package/examples/table/cellEditing/index.html +11 -0
- package/examples/table/cellEditing/neo-config.json +6 -0
- package/examples/table/nestedRecordFields/MainContainerStateProvider.mjs +2 -1
- package/package.json +5 -5
- package/resources/scss/src/apps/portal/home/FooterContainer.scss +11 -2
- package/resources/scss/src/grid/Container.scss +0 -13
- package/resources/scss/src/grid/plugin/CellEditing.scss +11 -0
- package/resources/scss/src/table/plugin/CellEditing.scss +11 -0
- package/src/DefaultConfig.mjs +2 -2
- package/src/component/DateSelector.mjs +15 -0
- package/src/form/field/Base.mjs +1 -4
- package/src/form/field/ComboBox.mjs +18 -2
- package/src/form/field/Date.mjs +10 -4
- package/src/grid/Container.mjs +242 -39
- package/src/grid/README.md +1 -1
- package/src/grid/View.mjs +282 -129
- package/src/grid/header/Button.mjs +327 -36
- package/src/grid/header/Toolbar.mjs +68 -4
- package/src/grid/plugin/CellEditing.mjs +30 -0
- package/src/main/DomEvents.mjs +12 -3
- package/src/manager/Focus.mjs +2 -2
- package/src/plugin/Base.mjs +15 -1
- package/src/plugin/Resizable.mjs +1 -5
- package/src/selection/Model.mjs +5 -1
- package/src/selection/grid/CellColumnModel.mjs +1 -1
- package/src/selection/grid/CellColumnRowModel.mjs +1 -1
- package/src/selection/grid/CellModel.mjs +1 -1
- package/src/selection/grid/ColumnModel.mjs +2 -2
- package/src/table/Container.mjs +32 -3
- package/src/table/View.mjs +9 -4
- package/src/table/header/Toolbar.mjs +15 -1
- package/src/table/plugin/CellEditing.mjs +330 -0
- package/src/util/KeyNavigation.mjs +14 -8
@@ -88,7 +88,7 @@ class CellColumnRowModel extends CellRowModel {
|
|
88
88
|
idArray = ColumnModel.getCellId(data.path).split('__'),
|
89
89
|
currentColumn = idArray[2],
|
90
90
|
{view} = me,
|
91
|
-
fields = view.columns.map(c => c.
|
91
|
+
fields = view.columns.map(c => c.dataField),
|
92
92
|
newIndex = (fields.indexOf(currentColumn) + step) % fields.length,
|
93
93
|
columnNodeIds, tbodyNode;
|
94
94
|
|
@@ -87,7 +87,7 @@ class CellModel extends BaseModel {
|
|
87
87
|
{view} = me,
|
88
88
|
idArray = data.path[0].id.split('__'),
|
89
89
|
currentColumn = idArray[2],
|
90
|
-
dataFields = view.columns.map(c => c.
|
90
|
+
dataFields = view.columns.map(c => c.dataField),
|
91
91
|
newIndex = (dataFields.indexOf(currentColumn) + step) % dataFields.length,
|
92
92
|
id;
|
93
93
|
|
@@ -72,7 +72,7 @@ class ColumnModel extends BaseModel {
|
|
72
72
|
static getColumnIndex(cellId, columns) {
|
73
73
|
let idArray = cellId.split('__'),
|
74
74
|
currentColumn = idArray[2],
|
75
|
-
dataFields = columns.map(c => c.
|
75
|
+
dataFields = columns.map(c => c.dataField);
|
76
76
|
|
77
77
|
return dataFields.indexOf(currentColumn)
|
78
78
|
}
|
@@ -117,7 +117,7 @@ class ColumnModel extends BaseModel {
|
|
117
117
|
idArray = ColumnModel.getCellId(data.path).split('__'),
|
118
118
|
currentColumn = idArray[2],
|
119
119
|
{view} = me,
|
120
|
-
fields = view.columns.map(c => c.
|
120
|
+
fields = view.columns.map(c => c.dataField),
|
121
121
|
newIndex = (fields.indexOf(currentColumn) + step) % fields.length,
|
122
122
|
columnNodeIds, id, tbodyNode;
|
123
123
|
|
package/src/table/Container.mjs
CHANGED
@@ -27,6 +27,11 @@ class Container extends BaseContainer {
|
|
27
27
|
* @member {String[]} baseCls=['neo-table-container']
|
28
28
|
*/
|
29
29
|
baseCls: ['neo-table-container'],
|
30
|
+
/**
|
31
|
+
* true uses table.plugin.CellEditing
|
32
|
+
* @member {Boolean} cellEditing_=false
|
33
|
+
*/
|
34
|
+
cellEditing_: false,
|
30
35
|
/**
|
31
36
|
* Default configs for each column
|
32
37
|
* @member {Object} columnDefaults=null
|
@@ -150,6 +155,30 @@ class Container extends BaseContainer {
|
|
150
155
|
me.createColumns(me.columns)
|
151
156
|
}
|
152
157
|
|
158
|
+
/**
|
159
|
+
* Triggered after the cellEditing config got changed
|
160
|
+
* @param {Boolean} value
|
161
|
+
* @param {Boolean} oldValue
|
162
|
+
* @protected
|
163
|
+
*/
|
164
|
+
afterSetCellEditing(value, oldValue) {
|
165
|
+
if (value) {
|
166
|
+
import('./plugin/CellEditing.mjs').then(module => {
|
167
|
+
let me = this,
|
168
|
+
{appName, windowId} = me,
|
169
|
+
plugins = me.plugins || [];
|
170
|
+
|
171
|
+
plugins.push({
|
172
|
+
module : module.default,
|
173
|
+
appName,
|
174
|
+
windowId
|
175
|
+
});
|
176
|
+
|
177
|
+
me.plugins = plugins
|
178
|
+
})
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
153
182
|
/**
|
154
183
|
* Triggered after the columns config got changed
|
155
184
|
* @param {Object[]|null} value
|
@@ -350,9 +379,9 @@ class Container extends BaseContainer {
|
|
350
379
|
* @returns {*}
|
351
380
|
*/
|
352
381
|
createColumns(columns) {
|
353
|
-
let me
|
354
|
-
columnDefaults = me
|
355
|
-
sorters
|
382
|
+
let me = this,
|
383
|
+
{columnDefaults} = me,
|
384
|
+
sorters = me.store?.sorters,
|
356
385
|
renderer;
|
357
386
|
|
358
387
|
if (!columns || !columns.length) {
|
package/src/table/View.mjs
CHANGED
@@ -131,6 +131,7 @@ class View extends Component {
|
|
131
131
|
}
|
132
132
|
break
|
133
133
|
}
|
134
|
+
case 'Date':
|
134
135
|
case 'Number':
|
135
136
|
case 'String': {
|
136
137
|
rendererOutput = {
|
@@ -182,10 +183,14 @@ class View extends Component {
|
|
182
183
|
/**
|
183
184
|
* @param {Object} opts
|
184
185
|
* @param {Object} opts.record
|
185
|
-
* @param {Number} opts.rowIndex
|
186
|
+
* @param {Number} [opts.rowIndex]
|
186
187
|
* @returns {Object}
|
187
188
|
*/
|
188
|
-
|
189
|
+
createRow({record, rowIndex}) {
|
190
|
+
if (!Neo.isNumber(rowIndex)) {
|
191
|
+
rowIndex = this.store.indexOf(record)
|
192
|
+
}
|
193
|
+
|
189
194
|
let me = this,
|
190
195
|
tableContainer = me.parent,
|
191
196
|
colspan = record[me.colspanField],
|
@@ -276,7 +281,7 @@ class View extends Component {
|
|
276
281
|
{selectedRows} = me;
|
277
282
|
|
278
283
|
for (; i < amountRows; i++) {
|
279
|
-
rows.push(me.
|
284
|
+
rows.push(me.createRow({record: inputData[i], rowIndex: i}))
|
280
285
|
}
|
281
286
|
|
282
287
|
me.vdom.cn = rows;
|
@@ -472,7 +477,7 @@ class View extends Component {
|
|
472
477
|
|
473
478
|
if (fieldNames.includes(me.colspanField)) {
|
474
479
|
index = me.store.indexOf(record);
|
475
|
-
me.vdom.cn[index] = me.
|
480
|
+
me.vdom.cn[index] = me.createRow({record, rowIndex: index});
|
476
481
|
me.update()
|
477
482
|
} else {
|
478
483
|
fields.forEach(field => {
|
@@ -28,7 +28,7 @@ class Toolbar extends BaseToolbar {
|
|
28
28
|
* @member {Object} itemDefaults={ntype : 'table-header-button'}
|
29
29
|
*/
|
30
30
|
itemDefaults: {
|
31
|
-
ntype
|
31
|
+
ntype: 'table-header-button'
|
32
32
|
},
|
33
33
|
/**
|
34
34
|
* @member {Boolean} showHeaderFilters_=false
|
@@ -143,6 +143,20 @@ class Toolbar extends BaseToolbar {
|
|
143
143
|
me.update()
|
144
144
|
}
|
145
145
|
|
146
|
+
/**
|
147
|
+
* @param {String} dataField
|
148
|
+
* @returns {Neo.button.Base|null}
|
149
|
+
*/
|
150
|
+
getColumn(dataField) {
|
151
|
+
for (const item of this.items) {
|
152
|
+
if (item.dataField === dataField) {
|
153
|
+
return item
|
154
|
+
}
|
155
|
+
}
|
156
|
+
|
157
|
+
return null
|
158
|
+
}
|
159
|
+
|
146
160
|
/**
|
147
161
|
* @param {String} dock
|
148
162
|
* @returns {String} layoutConfig
|
@@ -0,0 +1,330 @@
|
|
1
|
+
import Plugin from '../../plugin/Base.mjs';
|
2
|
+
import TextField from '../../form/field/Text.mjs';
|
3
|
+
import VdomUtil from '../../util/VDom.mjs';
|
4
|
+
|
5
|
+
/**
|
6
|
+
* @class Neo.table.plugin.CellEditing
|
7
|
+
* @extends Neo.plugin.Base
|
8
|
+
*/
|
9
|
+
class CellEditing extends Plugin {
|
10
|
+
static config = {
|
11
|
+
/**
|
12
|
+
* @member {String} className='Neo.table.plugin.CellEditing'
|
13
|
+
* @protected
|
14
|
+
*/
|
15
|
+
className: 'Neo.table.plugin.CellEditing',
|
16
|
+
/**
|
17
|
+
* @member {String} ntype='plugin-table-cell-editing'
|
18
|
+
* @protected
|
19
|
+
*/
|
20
|
+
ntype: 'plugin-table-cell-editing',
|
21
|
+
/**
|
22
|
+
* @member {String} cellCls='neo-table-cell'
|
23
|
+
*/
|
24
|
+
cellCls: 'neo-table-cell',
|
25
|
+
/**
|
26
|
+
* @member {Boolean} disabled_=false
|
27
|
+
*/
|
28
|
+
disabled_: false,
|
29
|
+
/**
|
30
|
+
* @member {String[]} editorCls=['neo-table-editor']
|
31
|
+
*/
|
32
|
+
editorCls: ['neo-table-editor']
|
33
|
+
}
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Storing editor instances per column
|
37
|
+
* @member {Object} editors={}
|
38
|
+
*/
|
39
|
+
editors = {}
|
40
|
+
/**
|
41
|
+
* Storing the currently mounted editor
|
42
|
+
* @member {Neo.form.field.Base|null} mountedEditor=null
|
43
|
+
*/
|
44
|
+
mountedEditor = null
|
45
|
+
|
46
|
+
/**
|
47
|
+
* @param {Object} config
|
48
|
+
*/
|
49
|
+
construct(config) {
|
50
|
+
super.construct(config);
|
51
|
+
|
52
|
+
let me = this,
|
53
|
+
{owner} = me,
|
54
|
+
{selectionModel} = owner;
|
55
|
+
|
56
|
+
owner.on({
|
57
|
+
cellDoubleClick : me.onCellDoubleClick,
|
58
|
+
focusLeave : me.onFocusLeave,
|
59
|
+
selectionModelChange: me.onSelectionModelChange,
|
60
|
+
scope : me
|
61
|
+
});
|
62
|
+
|
63
|
+
// Connect an already registered selectionModel instance
|
64
|
+
if (Neo.typeOf(selectionModel) === 'NeoInstance') {
|
65
|
+
me.onSelectionModelChange({value: selectionModel})
|
66
|
+
}
|
67
|
+
|
68
|
+
owner.keys.add({
|
69
|
+
Enter: 'onTableKeyDown',
|
70
|
+
Space: 'onTableKeyDown',
|
71
|
+
scope: me
|
72
|
+
})
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Triggered after the disabled config got changed
|
77
|
+
* @param {Boolean} value
|
78
|
+
* @param {Boolean} oldValue
|
79
|
+
* @protected
|
80
|
+
*/
|
81
|
+
afterSetDisabled(value, oldValue) {
|
82
|
+
oldValue && this.unmountEditor()
|
83
|
+
}
|
84
|
+
|
85
|
+
/**
|
86
|
+
* @param {args} args
|
87
|
+
*/
|
88
|
+
destroy(...args) {
|
89
|
+
Object.values(this.editors).forEach(editor => {
|
90
|
+
editor.destroy(false, true)
|
91
|
+
});
|
92
|
+
|
93
|
+
super.destroy(...args)
|
94
|
+
}
|
95
|
+
|
96
|
+
/**
|
97
|
+
* @param {Object} record
|
98
|
+
* @param {String} dataField
|
99
|
+
* @returns {Promise<void>}
|
100
|
+
*/
|
101
|
+
async mountEditor(record, dataField) {
|
102
|
+
if (this.disabled) {
|
103
|
+
return
|
104
|
+
}
|
105
|
+
|
106
|
+
let me = this,
|
107
|
+
{appName, windowId} = me,
|
108
|
+
{view} = me.owner,
|
109
|
+
cellId = view.getCellId(record, dataField),
|
110
|
+
cellNode = VdomUtil.find(view.vdom, cellId).vdom,
|
111
|
+
column = me.owner.headerToolbar.getColumn(dataField),
|
112
|
+
editor = me.editors[dataField],
|
113
|
+
value = record[dataField];
|
114
|
+
|
115
|
+
if (me.mountedEditor) {
|
116
|
+
await me.unmountEditor();
|
117
|
+
await me.timeout(10)
|
118
|
+
}
|
119
|
+
|
120
|
+
if (!column.editable) {
|
121
|
+
return
|
122
|
+
}
|
123
|
+
|
124
|
+
if (!editor) {
|
125
|
+
me.editors[dataField] = editor = Neo.create({
|
126
|
+
module : TextField,
|
127
|
+
appName,
|
128
|
+
cls : me.editorCls,
|
129
|
+
dataField,
|
130
|
+
hideLabel: true,
|
131
|
+
parentId : view.id,
|
132
|
+
record,
|
133
|
+
value,
|
134
|
+
windowId,
|
135
|
+
|
136
|
+
keys: {
|
137
|
+
Enter : 'onEditorKeyEnter',
|
138
|
+
Escape: 'onEditorKeyEscape',
|
139
|
+
Tab : 'onEditorKeyTab',
|
140
|
+
scope : me
|
141
|
+
},
|
142
|
+
|
143
|
+
...column.editor
|
144
|
+
})
|
145
|
+
} else {
|
146
|
+
editor.originalConfig.value = value;
|
147
|
+
editor.setSilent({record, value})
|
148
|
+
}
|
149
|
+
|
150
|
+
me.mountedEditor = editor;
|
151
|
+
|
152
|
+
cellNode.cn = [editor.createVdomReference()];
|
153
|
+
delete cellNode.innerHTML;
|
154
|
+
|
155
|
+
view.updateDepth = -1;
|
156
|
+
|
157
|
+
await view.promiseUpdate();
|
158
|
+
|
159
|
+
await me.timeout(10);
|
160
|
+
|
161
|
+
editor.focus()
|
162
|
+
}
|
163
|
+
|
164
|
+
/**
|
165
|
+
*
|
166
|
+
* @param {Object} data
|
167
|
+
* @param {Object} data.data
|
168
|
+
* @param {String} data.dataField
|
169
|
+
* @param {Object} data.record
|
170
|
+
* @param {Neo.table.View} data.view
|
171
|
+
* @returns {Promise<void>}
|
172
|
+
*/
|
173
|
+
async onCellDoubleClick({data, dataField, record, view}) {
|
174
|
+
await this.mountEditor(record, dataField)
|
175
|
+
}
|
176
|
+
|
177
|
+
/**
|
178
|
+
* @param {Object} data
|
179
|
+
* @param {Neo.form.field.Base} field
|
180
|
+
* @returns {Promise<void>}
|
181
|
+
*/
|
182
|
+
async onEditorKeyEnter(data, field) {
|
183
|
+
let me = this;
|
184
|
+
|
185
|
+
await me.submitEditor();
|
186
|
+
await me.timeout(20);
|
187
|
+
me.selectCell(data)
|
188
|
+
}
|
189
|
+
|
190
|
+
/**
|
191
|
+
* @param {Object} data
|
192
|
+
* @param {Neo.form.field.Base} field
|
193
|
+
* @returns {Promise<void>}
|
194
|
+
*/
|
195
|
+
async onEditorKeyEscape(data, field) {
|
196
|
+
let me = this;
|
197
|
+
|
198
|
+
await me.unmountEditor();
|
199
|
+
await me.timeout(20);
|
200
|
+
me.selectCell(data)
|
201
|
+
}
|
202
|
+
|
203
|
+
/**
|
204
|
+
* @param {Object} event
|
205
|
+
* @param {Neo.form.field.Base} field
|
206
|
+
* @returns {Promise<void>}
|
207
|
+
*/
|
208
|
+
async onEditorKeyTab(event, field) {
|
209
|
+
let me = this,
|
210
|
+
{store} = me.owner,
|
211
|
+
oldIndex = store.indexOf(field.record),
|
212
|
+
countRecords = store.getCount(),
|
213
|
+
index = (oldIndex + (event.altKey ? -1 : 1) + countRecords) % countRecords,
|
214
|
+
record = store.getAt(index);
|
215
|
+
|
216
|
+
await me.submitEditor();
|
217
|
+
await me.mountEditor(record, field.dataField)
|
218
|
+
}
|
219
|
+
|
220
|
+
/**
|
221
|
+
* @param {Object} data
|
222
|
+
* @returns {Promise<void>}
|
223
|
+
*/
|
224
|
+
async onFocusLeave(data) {
|
225
|
+
await this.unmountEditor()
|
226
|
+
}
|
227
|
+
|
228
|
+
/**
|
229
|
+
* @param {Object} data
|
230
|
+
*/
|
231
|
+
onSelectionChange(data) {
|
232
|
+
// todo: Once we separate cell selections & focus, we can use this event to mount editors
|
233
|
+
// console.log('onSelectionChange', data);
|
234
|
+
}
|
235
|
+
|
236
|
+
/**
|
237
|
+
* @param {Object} data
|
238
|
+
*/
|
239
|
+
onSelectionModelChange(data) {
|
240
|
+
let selectionModel = data.value;
|
241
|
+
|
242
|
+
if (selectionModel.ntype.includes('cell')) {
|
243
|
+
selectionModel.on('selectionChange', this.onSelectionChange, this)
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
247
|
+
/**
|
248
|
+
* @param {Object} data
|
249
|
+
* @returns {Promise<void>}
|
250
|
+
*/
|
251
|
+
async onTableKeyDown(data) {
|
252
|
+
let me = this,
|
253
|
+
{target} = data,
|
254
|
+
tableView = me.owner.view,
|
255
|
+
dataField, record;
|
256
|
+
|
257
|
+
if (!me.mountedEditor && target.cls?.includes('neo-selected')) {
|
258
|
+
dataField = tableView.getCellDataField(target.id);
|
259
|
+
record = tableView.getRecord(target.id);
|
260
|
+
|
261
|
+
await me.mountEditor(record, dataField)
|
262
|
+
}
|
263
|
+
}
|
264
|
+
|
265
|
+
/**
|
266
|
+
* @param {Object} data
|
267
|
+
* @param {Object[]} data.path
|
268
|
+
*/
|
269
|
+
selectCell({path}) {
|
270
|
+
let me = this,
|
271
|
+
{selectionModel} = me.owner,
|
272
|
+
i = 0,
|
273
|
+
len = path.length,
|
274
|
+
cellId;
|
275
|
+
|
276
|
+
for (; i < len; i++) {
|
277
|
+
if (path[i].cls?.includes(me.cellCls)) {
|
278
|
+
cellId = path[i].id;
|
279
|
+
break
|
280
|
+
}
|
281
|
+
}
|
282
|
+
|
283
|
+
if (cellId) {
|
284
|
+
selectionModel?.deselect(cellId, true); // the cell might still count as selected => silent deselect first
|
285
|
+
selectionModel?.select(cellId);
|
286
|
+
me.owner.focus(cellId)
|
287
|
+
}
|
288
|
+
}
|
289
|
+
|
290
|
+
/**
|
291
|
+
* If the field is valid:
|
292
|
+
* Updates the record field, in case the value of the editor changed,
|
293
|
+
* otherwise unmounts the editor
|
294
|
+
* @returns {Promise<void>}
|
295
|
+
*/
|
296
|
+
async submitEditor() {
|
297
|
+
let me = this,
|
298
|
+
field = me.mountedEditor;
|
299
|
+
|
300
|
+
if (field?.isValid()) {
|
301
|
+
if (field.isDirty) {
|
302
|
+
me.mountedEditor = null;
|
303
|
+
field.record[field.dataField] = field.getSubmitValue()
|
304
|
+
} else {
|
305
|
+
await me.unmountEditor()
|
306
|
+
}
|
307
|
+
}
|
308
|
+
}
|
309
|
+
|
310
|
+
/**
|
311
|
+
* @returns {Promise<void>}
|
312
|
+
*/
|
313
|
+
async unmountEditor() {
|
314
|
+
if (!this.mountedEditor) {
|
315
|
+
return
|
316
|
+
}
|
317
|
+
|
318
|
+
let me = this,
|
319
|
+
record = me.mountedEditor.record,
|
320
|
+
tableView = me.owner.view,
|
321
|
+
rowIndex = tableView.store.indexOf(record);
|
322
|
+
|
323
|
+
me.mountedEditor = null;
|
324
|
+
|
325
|
+
tableView.vdom.cn[rowIndex] = tableView.createRow({record, rowIndex});
|
326
|
+
await tableView.promiseUpdate()
|
327
|
+
}
|
328
|
+
}
|
329
|
+
|
330
|
+
export default Neo.setupClass(CellEditing);
|
@@ -75,10 +75,14 @@ class KeyNavigation extends Base {
|
|
75
75
|
upperCaseKey = me.parseUpperCaseKey(upperCaseKey);
|
76
76
|
|
77
77
|
me.keys.forEach(key => {
|
78
|
-
scope = Neo.get(key.scope);
|
78
|
+
scope = Neo.isString(key.scope) ? Neo.get(key.scope) : key.scope;
|
79
79
|
|
80
80
|
if (key.key.toUpperCase() === upperCaseKey) {
|
81
|
-
|
81
|
+
if (Neo.isFunction(key.fn)) {
|
82
|
+
key.fn.apply(scope, [data, me.component])
|
83
|
+
} else {
|
84
|
+
scope[key.fn]?.apply(scope, [data, me.component])
|
85
|
+
}
|
82
86
|
}
|
83
87
|
})
|
84
88
|
}
|
@@ -94,12 +98,14 @@ class KeyNavigation extends Base {
|
|
94
98
|
keyArray = [];
|
95
99
|
|
96
100
|
if (componentId) {
|
97
|
-
Object.entries(value).forEach(([key,
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
Object.entries(value).forEach(([key, val]) => {
|
102
|
+
if (key !== 'scope') {
|
103
|
+
keyArray.push({
|
104
|
+
fn : val,
|
105
|
+
key,
|
106
|
+
scope: value.scope || componentId // todo: support VCs later on
|
107
|
+
})
|
108
|
+
}
|
103
109
|
});
|
104
110
|
|
105
111
|
value = keyArray
|