neo.mjs 8.0.0 → 8.1.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/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/grid/covid/neo-config.json +6 -5
- 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 +8 -8
- package/resources/scss/src/apps/portal/home/FooterContainer.scss +11 -2
- package/resources/scss/src/examples/grid/covid/GridContainer.scss +1 -1
- package/resources/scss/src/grid/Container.scss +13 -23
- package/resources/scss/src/grid/View.scss +45 -19
- package/resources/scss/src/grid/header/Button.scss +2 -4
- package/resources/scss/src/grid/header/Toolbar.scss +1 -2
- 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/Xhr.mjs +1 -1
- package/src/button/Base.mjs +2 -2
- package/src/collection/Base.mjs +5 -5
- package/src/component/Base.mjs +3 -3
- package/src/component/DateSelector.mjs +15 -0
- package/src/container/Base.mjs +2 -2
- package/src/controller/Base.mjs +3 -3
- package/src/dialog/Base.mjs +2 -2
- package/src/form/field/Base.mjs +3 -6
- package/src/form/field/CheckBox.mjs +2 -2
- package/src/form/field/ComboBox.mjs +18 -2
- package/src/form/field/Date.mjs +10 -4
- package/src/form/field/FileUpload.mjs +4 -4
- package/src/form/field/Hidden.mjs +2 -2
- package/src/form/field/Text.mjs +2 -2
- package/src/grid/Container.mjs +340 -43
- package/src/grid/View.mjs +599 -124
- package/src/grid/header/Button.mjs +331 -36
- package/src/grid/header/Toolbar.mjs +111 -4
- package/src/grid/plugin/CellEditing.mjs +30 -0
- package/src/layout/Base.mjs +3 -3
- package/src/list/Base.mjs +2 -2
- package/src/list/Circle.mjs +2 -2
- package/src/list/Color.mjs +2 -2
- package/src/list/Component.mjs +2 -2
- package/src/main/DomEvents.mjs +12 -3
- package/src/manager/Base.mjs +3 -3
- package/src/manager/Component.mjs +20 -11
- package/src/manager/DomEvent.mjs +5 -6
- package/src/manager/Focus.mjs +2 -2
- package/src/manager/Instance.mjs +4 -4
- package/src/manager/Task.mjs +2 -2
- package/src/manager/Toast.mjs +3 -3
- package/src/plugin/Base.mjs +18 -4
- package/src/plugin/Popover.mjs +3 -3
- package/src/plugin/PrefixField.mjs +2 -2
- package/src/plugin/Resizable.mjs +3 -7
- package/src/plugin/Responsive.mjs +2 -2
- package/src/selection/Model.mjs +17 -2
- 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/toolbar/Base.mjs +2 -2
- package/src/toolbar/Breadcrumb.mjs +1 -1
- package/src/tooltip/Base.mjs +2 -2
- package/src/util/KeyNavigation.mjs +14 -8
- package/src/worker/Base.mjs +3 -3
- package/src/grid/README.md +0 -3
package/src/grid/View.mjs
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
import Component from '../component/Base.mjs';
|
2
|
+
import NeoArray from '../util/Array.mjs';
|
2
3
|
import VDomUtil from '../util/VDom.mjs';
|
3
4
|
|
4
5
|
/**
|
5
6
|
* @class Neo.grid.View
|
6
7
|
* @extends Neo.component.Base
|
7
8
|
*/
|
8
|
-
class
|
9
|
+
class GridView extends Component {
|
9
10
|
static config = {
|
10
11
|
/**
|
11
12
|
* @member {String} className='Neo.grid.View'
|
@@ -17,10 +18,127 @@ class View extends Component {
|
|
17
18
|
* @protected
|
18
19
|
*/
|
19
20
|
ntype: 'grid-view',
|
21
|
+
/**
|
22
|
+
* Internal flag. Gets calculated when mounting the grid.Container
|
23
|
+
* @member {Number} availableHeight_=0
|
24
|
+
*/
|
25
|
+
availableHeight_: 0,
|
26
|
+
/**
|
27
|
+
* Internal flag. Gets calculated when changing the availableHeight config
|
28
|
+
* @member {Number} availableRows_=0
|
29
|
+
*/
|
30
|
+
availableRows_: 0,
|
31
|
+
/**
|
32
|
+
* Internal flag. Gets calculated after mounting grid.View rows
|
33
|
+
* @member {Number} availableWidth_=0
|
34
|
+
*/
|
35
|
+
availableWidth_: 0,
|
20
36
|
/**
|
21
37
|
* @member {String[]} baseCls=['neo-grid-view']
|
38
|
+
* @protected
|
39
|
+
*/
|
40
|
+
baseCls: ['neo-grid-view'],
|
41
|
+
/**
|
42
|
+
* The amount of rows to paint before the first & after the last visible row,
|
43
|
+
* to enhance the scrolling performance
|
44
|
+
* @member {Number} bufferRowRange_=3
|
45
|
+
*/
|
46
|
+
bufferRowRange_: 3,
|
47
|
+
/**
|
48
|
+
* Define which model field contains the value of colspan definitions
|
49
|
+
* @member {String} colspanField='colspan'
|
50
|
+
*/
|
51
|
+
colspanField: 'colspan',
|
52
|
+
/**
|
53
|
+
* @member {String|null} containerId=null
|
54
|
+
* @protected
|
55
|
+
*/
|
56
|
+
containerId: null,
|
57
|
+
/**
|
58
|
+
* @member {Object[]} columnPositions_=[]
|
59
|
+
* @protected
|
60
|
+
*/
|
61
|
+
columnPositions_: [],
|
62
|
+
/**
|
63
|
+
* @member {Boolean} isScrolling_=false
|
64
|
+
*/
|
65
|
+
isScrolling_: false,
|
66
|
+
/**
|
67
|
+
* @member {Object} recordVnodeMap={}
|
68
|
+
*/
|
69
|
+
recordVnodeMap: {},
|
70
|
+
/**
|
71
|
+
* @member {String} role='rowgroup'
|
72
|
+
*/
|
73
|
+
role: 'rowgroup',
|
74
|
+
/**
|
75
|
+
* Number in px
|
76
|
+
* @member {Number} rowHeight_=0
|
77
|
+
*/
|
78
|
+
rowHeight_: 0,
|
79
|
+
/**
|
80
|
+
* @member {Object} scrollPosition_={x:0,y:0}
|
22
81
|
*/
|
23
|
-
|
82
|
+
scrollPosition_: {x: 0, y: 0},
|
83
|
+
/**
|
84
|
+
* @member {String} selectedRecordField='annotations.selected'
|
85
|
+
*/
|
86
|
+
selectedRecordField: 'annotations.selected',
|
87
|
+
/**
|
88
|
+
* @member {Number} startIndex_=0
|
89
|
+
*/
|
90
|
+
startIndex_: 0,
|
91
|
+
/**
|
92
|
+
* @member {Neo.data.Store|null} store_=null
|
93
|
+
*/
|
94
|
+
store_: null,
|
95
|
+
/**
|
96
|
+
* @member {Boolean} useRowRecordIds=true
|
97
|
+
*/
|
98
|
+
useRowRecordIds: true,
|
99
|
+
/**
|
100
|
+
* Stores the indexes of the first & last painted columns
|
101
|
+
* @member {Array} visibleColumns_=[0,0]
|
102
|
+
* @protected
|
103
|
+
*/
|
104
|
+
visibleColumns_: [0, 0],
|
105
|
+
/**
|
106
|
+
* @member {String[]} wrapperCls=[]
|
107
|
+
*/
|
108
|
+
wrapperCls: ['neo-grid-view-wrapper'],
|
109
|
+
/**
|
110
|
+
* @member {Object} _vdom
|
111
|
+
*/
|
112
|
+
_vdom:
|
113
|
+
{cn: [
|
114
|
+
{cn: []},
|
115
|
+
{cls: 'neo-grid-scrollbar'}
|
116
|
+
]}
|
117
|
+
}
|
118
|
+
|
119
|
+
/**
|
120
|
+
* @member {Number|null}} scrollTimeoutId=null
|
121
|
+
*/
|
122
|
+
scrollTimeoutId = null
|
123
|
+
|
124
|
+
/**
|
125
|
+
* @member {Neo.grid.Container|null} gridContainer
|
126
|
+
*/
|
127
|
+
get gridContainer() {
|
128
|
+
return Neo.getComponent(this.containerId)
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* @member {String[]} selectedRows
|
133
|
+
*/
|
134
|
+
get selectedRows() {
|
135
|
+
let {gridContainer} = this;
|
136
|
+
|
137
|
+
if (gridContainer.selectionModel.ntype === 'selection-grid-rowmodel') {
|
138
|
+
return gridContainer.selectionModel.items
|
139
|
+
}
|
140
|
+
|
141
|
+
return []
|
24
142
|
}
|
25
143
|
|
26
144
|
/**
|
@@ -32,6 +150,9 @@ class View extends Component {
|
|
32
150
|
let me = this;
|
33
151
|
|
34
152
|
me.addDomListeners([{
|
153
|
+
scroll: me.onScroll,
|
154
|
+
scope : me
|
155
|
+
}, {
|
35
156
|
click : me.onCellClick,
|
36
157
|
dblclick: me.onCellDoubleClick,
|
37
158
|
delegate: '.neo-grid-cell',
|
@@ -45,149 +166,369 @@ class View extends Component {
|
|
45
166
|
}
|
46
167
|
|
47
168
|
/**
|
48
|
-
*
|
169
|
+
* Triggered after the availableHeight config got changed
|
170
|
+
* @param {Number} value
|
171
|
+
* @param {Number} oldValue
|
172
|
+
* @protected
|
173
|
+
*/
|
174
|
+
afterSetAvailableHeight(value, oldValue) {
|
175
|
+
if (value > 0) {
|
176
|
+
this.availableRows = Math.ceil(value / this.rowHeight) + 1
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
/**
|
181
|
+
* Triggered after the availableRows config got changed
|
182
|
+
* @param {Number} value
|
183
|
+
* @param {Number} oldValue
|
184
|
+
* @protected
|
49
185
|
*/
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
colCount = columns.length,
|
56
|
-
data = [],
|
57
|
-
i = 0,
|
58
|
-
{vdom} = me,
|
59
|
-
cellCls, cellStyle, config, column, dockLeftMargin, dockRightMargin, id, index, j, rendererOutput,
|
60
|
-
record, rendererValue, selectedRows, trCls;
|
186
|
+
afterSetAvailableRows(value, oldValue) {
|
187
|
+
if (value > 0 && this.store.getCount() > 0) {
|
188
|
+
this.createViewData()
|
189
|
+
}
|
190
|
+
}
|
61
191
|
|
62
|
-
|
192
|
+
/**
|
193
|
+
* Triggered after the availableWidth config got changed
|
194
|
+
* @param {Number} value
|
195
|
+
* @param {Number} oldValue
|
196
|
+
* @protected
|
197
|
+
*/
|
198
|
+
afterSetAvailableWidth(value, oldValue) {
|
199
|
+
if (value > 0) {
|
200
|
+
let me = this;
|
63
201
|
|
64
|
-
|
65
|
-
|
202
|
+
me.vdom.width = value + 'px';
|
203
|
+
me.vdom.cn[1].width = value + 'px';
|
204
|
+
me.update()
|
66
205
|
}
|
206
|
+
}
|
67
207
|
|
68
|
-
|
69
|
-
|
70
|
-
|
208
|
+
/**
|
209
|
+
* Triggered after the bufferRowRange config got changed
|
210
|
+
* @param {Number} value
|
211
|
+
* @param {Number} oldValue
|
212
|
+
* @protected
|
213
|
+
*/
|
214
|
+
afterSetBufferRowRange(value, oldValue) {
|
215
|
+
oldValue !== undefined && this.createViewData()
|
216
|
+
}
|
71
217
|
|
72
|
-
|
218
|
+
/**
|
219
|
+
* Triggered after the columnPositions config got changed
|
220
|
+
* @param {Object[]} value
|
221
|
+
* @param {Object[]} oldValue
|
222
|
+
* @protected
|
223
|
+
*/
|
224
|
+
afterSetColumnPositions(value, oldValue) {
|
225
|
+
let me = this;
|
73
226
|
|
74
|
-
|
227
|
+
if (value.length > 0) {
|
228
|
+
// for changing an array inline, we need to use the leading underscore
|
229
|
+
me._visibleColumns[1] = value.length - 1;
|
75
230
|
|
76
|
-
if (
|
77
|
-
|
231
|
+
if (me.store.getCount() > 0) {
|
232
|
+
me.createViewData()
|
233
|
+
}
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
/**
|
238
|
+
* Triggered after the id config got changed
|
239
|
+
* @param {String} value
|
240
|
+
* @param {String} oldValue
|
241
|
+
* @protected
|
242
|
+
*/
|
243
|
+
afterSetId(value, oldValue) {
|
244
|
+
this.vdom.id = value + '__wrapper';
|
245
|
+
|
246
|
+
// silent vdom update, the super call will trigger the engine
|
247
|
+
super.afterSetId(value, oldValue);
|
248
|
+
}
|
78
249
|
|
79
|
-
|
80
|
-
|
81
|
-
|
250
|
+
/**
|
251
|
+
* Triggered after the isScrolling config got changed
|
252
|
+
* @param {Number} value
|
253
|
+
* @param {Number} oldValue
|
254
|
+
* @protected
|
255
|
+
*/
|
256
|
+
afterSetIsScrolling(value, oldValue) {
|
257
|
+
this.toggleCls('neo-is-scrolling', value)
|
258
|
+
}
|
259
|
+
|
260
|
+
/**
|
261
|
+
* Triggered after the rowHeight config got changed
|
262
|
+
* @param {Number} value
|
263
|
+
* @param {Number} oldValue
|
264
|
+
* @protected
|
265
|
+
*/
|
266
|
+
afterSetRowHeight(value, oldValue) {
|
267
|
+
value > 0 && this.updateScrollHeight()
|
268
|
+
}
|
269
|
+
|
270
|
+
/**
|
271
|
+
* Triggered after the scrollPosition config got changed
|
272
|
+
* @param {Object} value
|
273
|
+
* @param {Object} oldValue
|
274
|
+
* @protected
|
275
|
+
*/
|
276
|
+
afterSetScrollPosition(value, oldValue) {
|
277
|
+
let me = this,
|
278
|
+
{bufferRowRange} = me,
|
279
|
+
newStartIndex;
|
280
|
+
|
281
|
+
if (value.x !== oldValue?.x && me.columnPositions.length > 0) {
|
282
|
+
me.updateVisibleColumns()
|
283
|
+
}
|
284
|
+
|
285
|
+
if (value.y !== oldValue?.y) {
|
286
|
+
newStartIndex = Math.floor(value.y / me.rowHeight);
|
287
|
+
|
288
|
+
if (newStartIndex < bufferRowRange) {
|
289
|
+
me.startIndex = 0
|
290
|
+
} else if (Math.abs(me.startIndex - newStartIndex) >= bufferRowRange) {
|
291
|
+
me.startIndex = newStartIndex
|
82
292
|
}
|
293
|
+
}
|
294
|
+
}
|
295
|
+
|
296
|
+
/**
|
297
|
+
* Triggered after the startIndex config got changed
|
298
|
+
* @param {Number} value
|
299
|
+
* @param {Number} oldValue
|
300
|
+
* @protected
|
301
|
+
*/
|
302
|
+
afterSetStartIndex(value, oldValue) {
|
303
|
+
oldValue !== undefined && this.createViewData()
|
304
|
+
}
|
83
305
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
306
|
+
/**
|
307
|
+
* Triggered after the store config got changed
|
308
|
+
* @param {Neo.data.Store|null} value
|
309
|
+
* @param {Neo.data.Store|null} oldValue
|
310
|
+
* @protected
|
311
|
+
*/
|
312
|
+
afterSetStore(value, oldValue) {
|
313
|
+
if (value) {
|
314
|
+
let me = this;
|
315
|
+
|
316
|
+
value.on({
|
317
|
+
load : me.updateScrollHeight,
|
318
|
+
scope: me
|
89
319
|
});
|
90
320
|
|
91
|
-
|
92
|
-
|
321
|
+
value.getCount() > 0 && me.updateScrollHeight()
|
322
|
+
}
|
323
|
+
}
|
93
324
|
|
94
|
-
|
325
|
+
/**
|
326
|
+
* Triggered after the visibleColumns config got changed
|
327
|
+
* @param {Number} value
|
328
|
+
* @param {Number} oldValue
|
329
|
+
* @protected
|
330
|
+
*/
|
331
|
+
afterSetVisibleColumns(value, oldValue) {
|
332
|
+
if (oldValue !== undefined) {
|
333
|
+
this.createViewData()
|
334
|
+
}
|
335
|
+
}
|
336
|
+
|
337
|
+
/**
|
338
|
+
* @param {Object} data
|
339
|
+
* @param {String} [data.cellId]
|
340
|
+
* @param {Object} data.column
|
341
|
+
* @param {Neo.grid.Container} data.gridContainer
|
342
|
+
* @param {Number} data.index
|
343
|
+
* @param {Object} data.record
|
344
|
+
* @returns {Object}
|
345
|
+
*/
|
346
|
+
applyRendererOutput(data) {
|
347
|
+
let {cellId, column, gridContainer, index, record} = data,
|
348
|
+
me = this,
|
349
|
+
cellCls = ['neo-grid-cell'],
|
350
|
+
colspan = record[me.colspanField],
|
351
|
+
{dataField} = column,
|
352
|
+
fieldValue = Neo.ns(dataField, false, record),
|
353
|
+
cellConfig, rendererOutput;
|
354
|
+
|
355
|
+
if (fieldValue === null || fieldValue === undefined) {
|
356
|
+
fieldValue = ''
|
357
|
+
}
|
95
358
|
|
96
|
-
|
97
|
-
|
98
|
-
|
359
|
+
rendererOutput = column.renderer.call(column.rendererScope || gridContainer, {
|
360
|
+
column,
|
361
|
+
dataField,
|
362
|
+
gridContainer,
|
363
|
+
index,
|
364
|
+
record,
|
365
|
+
value: fieldValue
|
366
|
+
});
|
99
367
|
|
100
|
-
|
101
|
-
|
368
|
+
switch (Neo.typeOf(rendererOutput)) {
|
369
|
+
case 'Object': {
|
370
|
+
if (rendererOutput.html) {
|
371
|
+
rendererOutput.cls && cellCls.push(...rendererOutput.cls);
|
372
|
+
} else {
|
373
|
+
rendererOutput = [rendererOutput];
|
102
374
|
}
|
375
|
+
break
|
376
|
+
}
|
377
|
+
case 'Date':
|
378
|
+
case 'Number':
|
379
|
+
case 'String': {
|
380
|
+
rendererOutput = {
|
381
|
+
cls : cellCls,
|
382
|
+
html: rendererOutput?.toString()
|
383
|
+
};
|
384
|
+
break
|
385
|
+
}
|
386
|
+
}
|
103
387
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
index: i,
|
108
|
-
record,
|
109
|
-
value: rendererValue
|
110
|
-
});
|
388
|
+
if (rendererOutput === null || rendererOutput === undefined) {
|
389
|
+
rendererOutput = ''
|
390
|
+
}
|
111
391
|
|
112
|
-
|
392
|
+
if (column.cellAlign !== 'left') {
|
393
|
+
cellCls.push('neo-' + column.cellAlign)
|
394
|
+
}
|
113
395
|
|
114
|
-
|
115
|
-
|
116
|
-
|
396
|
+
if (!cellId) {
|
397
|
+
cellId = me.getCellId(record, column.dataField)
|
398
|
+
}
|
117
399
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
400
|
+
cellConfig = {
|
401
|
+
'aria-colindex': index + 1, // 1 based
|
402
|
+
id : cellId,
|
403
|
+
cls : cellCls,
|
404
|
+
role : 'gridcell',
|
405
|
+
style : rendererOutput.style || {},
|
406
|
+
tabIndex : '-1'
|
407
|
+
};
|
408
|
+
|
409
|
+
if (column.width) {
|
410
|
+
cellConfig.style.minWidth = `${column.width}px`
|
411
|
+
}
|
124
412
|
|
125
|
-
|
413
|
+
if (colspan && Object.keys(colspan).includes(dataField)) {
|
414
|
+
cellConfig.colspan = colspan[dataField]
|
415
|
+
}
|
126
416
|
|
127
|
-
|
128
|
-
|
129
|
-
|
417
|
+
if (Neo.typeOf(rendererOutput) === 'Object') {
|
418
|
+
cellConfig.innerHTML = rendererOutput.html || ''
|
419
|
+
} else {
|
420
|
+
cellConfig.cn = rendererOutput
|
421
|
+
}
|
130
422
|
|
131
|
-
|
132
|
-
|
133
|
-
cls : cellCls,
|
134
|
-
innerHTML: rendererOutput.html || '',
|
135
|
-
style : cellStyle,
|
136
|
-
tabIndex : '-1'
|
137
|
-
};
|
423
|
+
return cellConfig
|
424
|
+
}
|
138
425
|
|
139
|
-
|
140
|
-
|
426
|
+
/**
|
427
|
+
* @param {Object} opts
|
428
|
+
* @param {Object} opts.record
|
429
|
+
* @param {Number} [opts.rowIndex]
|
430
|
+
* @returns {Object}
|
431
|
+
*/
|
432
|
+
createRow({record, rowIndex}) {
|
433
|
+
if (!Neo.isNumber(rowIndex)) {
|
434
|
+
rowIndex = this.store.indexOf(record)
|
435
|
+
}
|
141
436
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
437
|
+
let me = this,
|
438
|
+
{gridContainer, selectedRows, visibleColumns} = me,
|
439
|
+
columns = gridContainer.items[0].items,
|
440
|
+
id = me.getRowId(record, rowIndex),
|
441
|
+
trCls = me.getTrClass(record, rowIndex),
|
442
|
+
config, column, gridRow, i;
|
147
443
|
|
148
|
-
|
149
|
-
|
150
|
-
|
444
|
+
me.recordVnodeMap[id] = rowIndex;
|
445
|
+
|
446
|
+
if (rowIndex % 2 !== 0) {
|
447
|
+
trCls.push('neo-even')
|
448
|
+
}
|
449
|
+
|
450
|
+
if (selectedRows && Neo.ns(me.selectedRecordField, false, record)) {
|
451
|
+
NeoArray.add(selectedRows, id)
|
452
|
+
}
|
453
|
+
|
454
|
+
if (selectedRows?.includes(id)) {
|
455
|
+
trCls.push('neo-selected');
|
151
456
|
|
152
|
-
|
457
|
+
gridContainer.fire('select', {
|
458
|
+
record
|
459
|
+
})
|
460
|
+
}
|
461
|
+
|
462
|
+
gridRow = {
|
463
|
+
id,
|
464
|
+
'aria-rowindex': rowIndex + 2, // header row => 1, first body row => 2
|
465
|
+
cls : trCls,
|
466
|
+
cn : [],
|
467
|
+
role : 'row',
|
468
|
+
tabIndex : '-1',
|
469
|
+
|
470
|
+
style: {
|
471
|
+
height : me.rowHeight + 'px',
|
472
|
+
transform: `translate(0px, ${rowIndex * me.rowHeight}px)`
|
153
473
|
}
|
474
|
+
};
|
154
475
|
|
155
|
-
|
476
|
+
for (i=visibleColumns[0]; i <= visibleColumns[1]; i++) {
|
477
|
+
column = columns[i];
|
478
|
+
config = me.applyRendererOutput({column, gridContainer, index: rowIndex, record});
|
156
479
|
|
157
|
-
|
158
|
-
|
159
|
-
|
480
|
+
if (column.dock) {
|
481
|
+
config.cls = ['neo-locked', ...config.cls || []]
|
482
|
+
}
|
160
483
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
484
|
+
config.style = {
|
485
|
+
...config.style,
|
486
|
+
left : me.columnPositions[i].x + 'px',
|
487
|
+
width: me.columnPositions[i].width + 'px'
|
165
488
|
}
|
489
|
+
|
490
|
+
gridRow.cn.push(config)
|
166
491
|
}
|
167
492
|
|
168
|
-
|
493
|
+
return gridRow
|
494
|
+
}
|
495
|
+
|
496
|
+
/**
|
497
|
+
*
|
498
|
+
*/
|
499
|
+
createViewData() {
|
500
|
+
let me = this,
|
501
|
+
{bufferRowRange, selectedRows, startIndex} = me,
|
502
|
+
rows = [],
|
503
|
+
endIndex, i;
|
504
|
+
|
505
|
+
if (me.availableRows < 1 || me.columnPositions.length < 1) {
|
506
|
+
return
|
507
|
+
}
|
508
|
+
|
509
|
+
endIndex = Math.min(me.store.getCount(), me.availableRows + startIndex + bufferRowRange);
|
510
|
+
startIndex = Math.max(0, startIndex - bufferRowRange);
|
511
|
+
|
512
|
+
for (i=startIndex; i < endIndex; i++) {
|
513
|
+
rows.push(me.createRow({record: me.store.items[i], rowIndex: i}))
|
514
|
+
}
|
169
515
|
|
170
|
-
|
171
|
-
container.dockRightMargin = dockRightMargin;
|
516
|
+
me.getVdomRoot().cn = rows;
|
172
517
|
|
173
518
|
me.promiseUpdate().then(() => {
|
174
519
|
if (selectedRows?.length > 0) {
|
175
|
-
// this logic only works for selection.
|
176
|
-
Neo.main.DomAccess.scrollToTableRow({
|
177
|
-
appName: me.appName,
|
178
|
-
id : selectedRows[0]
|
179
|
-
})
|
520
|
+
// this logic only works for selection.grid.RowModel
|
521
|
+
Neo.main.DomAccess.scrollToTableRow({appName: me.appName, id: selectedRows[0]})
|
180
522
|
}
|
181
523
|
})
|
182
524
|
}
|
183
525
|
|
184
526
|
/**
|
185
|
-
* @param
|
186
|
-
* @param {Boolean} silent
|
527
|
+
* @param args
|
187
528
|
*/
|
188
|
-
destroy(
|
529
|
+
destroy(...args) {
|
189
530
|
this.store = null;
|
190
|
-
super.destroy(
|
531
|
+
super.destroy(...args)
|
191
532
|
}
|
192
533
|
|
193
534
|
/**
|
@@ -196,11 +537,11 @@ class View extends Component {
|
|
196
537
|
*/
|
197
538
|
fireCellEvent(data, eventName) {
|
198
539
|
let me = this,
|
199
|
-
|
540
|
+
id = data.currentTarget,
|
200
541
|
dataField = me.getCellDataField(id),
|
201
542
|
record = me.getRecord(id);
|
202
543
|
|
203
|
-
me.
|
544
|
+
me.gridContainer.fire(eventName, {data, dataField, record, view: me})
|
204
545
|
}
|
205
546
|
|
206
547
|
/**
|
@@ -209,10 +550,10 @@ class View extends Component {
|
|
209
550
|
*/
|
210
551
|
fireRowEvent(data, eventName) {
|
211
552
|
let me = this,
|
212
|
-
|
553
|
+
id = data.currentTarget,
|
213
554
|
record = me.getRecord(id);
|
214
555
|
|
215
|
-
me.
|
556
|
+
me.gridContainer.fire(eventName, {data, record, view: me})
|
216
557
|
}
|
217
558
|
|
218
559
|
/**
|
@@ -225,15 +566,39 @@ class View extends Component {
|
|
225
566
|
|
226
567
|
/**
|
227
568
|
* @param {Object} record
|
228
|
-
* @param {String}
|
569
|
+
* @param {String} dataField
|
229
570
|
* @returns {String}
|
230
571
|
*/
|
231
|
-
getCellId(record,
|
232
|
-
return this.id + '__' + record[this.store.keyProperty] + '__' +
|
572
|
+
getCellId(record, dataField) {
|
573
|
+
return this.id + '__' + record[this.store.keyProperty] + '__' + dataField
|
574
|
+
}
|
575
|
+
|
576
|
+
/**
|
577
|
+
* Get a grid column or column index by a given field name
|
578
|
+
* @param {String} field
|
579
|
+
* @param {Boolean} returnIndex=false
|
580
|
+
* @returns {Object|Number|null}
|
581
|
+
*/
|
582
|
+
getColumn(field, returnIndex=false) {
|
583
|
+
let {gridContainer} = this,
|
584
|
+
columns = gridContainer.headerToolbar.items,
|
585
|
+
i = 0,
|
586
|
+
len = columns.length,
|
587
|
+
column;
|
588
|
+
|
589
|
+
for (; i < len; i++) {
|
590
|
+
column = columns[i];
|
591
|
+
|
592
|
+
if (column.dataField === field) {
|
593
|
+
return returnIndex ? i : column
|
594
|
+
}
|
595
|
+
}
|
596
|
+
|
597
|
+
return null
|
233
598
|
}
|
234
599
|
|
235
600
|
/**
|
236
|
-
* Get the matching record by passing a row id, a cell id or an id inside a
|
601
|
+
* Get the matching record by passing a row id, a cell id or an id inside a grid cell.
|
237
602
|
* @param {String} nodeId
|
238
603
|
* @returns {Object|null}
|
239
604
|
*/
|
@@ -243,7 +608,7 @@ class View extends Component {
|
|
243
608
|
node, parentNodes;
|
244
609
|
|
245
610
|
if (record) {
|
246
|
-
return record
|
611
|
+
return record;
|
247
612
|
}
|
248
613
|
|
249
614
|
parentNodes = VDomUtil.getParentNodes(me.vdom, nodeId);
|
@@ -273,7 +638,15 @@ class View extends Component {
|
|
273
638
|
* @returns {String}
|
274
639
|
*/
|
275
640
|
getRowId(record, index) {
|
276
|
-
|
641
|
+
let me = this,
|
642
|
+
{store} = me;
|
643
|
+
|
644
|
+
if (me.useRowRecordIds) {
|
645
|
+
return `${me.id}__tr__${record[store.keyProperty]}`
|
646
|
+
} else {
|
647
|
+
index = Neo.isNumber(index) ? index : store.indexOf(record);
|
648
|
+
return me.vdom.cn[index]?.id || Neo.getId('tr')
|
649
|
+
}
|
277
650
|
}
|
278
651
|
|
279
652
|
/**
|
@@ -286,6 +659,29 @@ class View extends Component {
|
|
286
659
|
return ['neo-grid-row']
|
287
660
|
}
|
288
661
|
|
662
|
+
/**
|
663
|
+
* @override
|
664
|
+
* @returns {*}
|
665
|
+
*/
|
666
|
+
getVdomRoot() {
|
667
|
+
return this.vdom.cn[0]
|
668
|
+
}
|
669
|
+
|
670
|
+
/**
|
671
|
+
* @returns {Object[]} The new vdom items root
|
672
|
+
*/
|
673
|
+
getVdomItemsRoot() {
|
674
|
+
return this.vdom.cn[0]
|
675
|
+
}
|
676
|
+
|
677
|
+
/**
|
678
|
+
* @override
|
679
|
+
* @returns {Neo.vdom.VNode}
|
680
|
+
*/
|
681
|
+
getVnodeRoot() {
|
682
|
+
return this.vnode.childNodes[0]
|
683
|
+
}
|
684
|
+
|
289
685
|
/**
|
290
686
|
* @param {Object} data
|
291
687
|
*/
|
@@ -314,6 +710,25 @@ class View extends Component {
|
|
314
710
|
this.fireRowEvent(data, 'rowDoubleClick')
|
315
711
|
}
|
316
712
|
|
713
|
+
/**
|
714
|
+
* Only triggers for vertical scrolling
|
715
|
+
* @param {Object} data
|
716
|
+
*/
|
717
|
+
onScroll(data) {
|
718
|
+
let me = this;
|
719
|
+
|
720
|
+
me.scrollTimeoutId && clearTimeout(me.scrollTimeoutId);
|
721
|
+
|
722
|
+
me.scrollTimeoutId = setTimeout(() => {
|
723
|
+
me.isScrolling = false
|
724
|
+
}, 30);
|
725
|
+
|
726
|
+
me.set({
|
727
|
+
isScrolling : true,
|
728
|
+
scrollPosition: {x: me.scrollPosition.x, y: data.scrollTop}
|
729
|
+
})
|
730
|
+
}
|
731
|
+
|
317
732
|
/**
|
318
733
|
* Gets triggered after changing the value of a record field.
|
319
734
|
* E.g. myRecord.foo = 'bar';
|
@@ -322,25 +737,85 @@ class View extends Component {
|
|
322
737
|
* @param {Neo.data.Model} opts.model The model instance of the changed record
|
323
738
|
* @param {Object} opts.record
|
324
739
|
*/
|
325
|
-
onStoreRecordChange(
|
326
|
-
let me
|
327
|
-
|
328
|
-
|
740
|
+
onStoreRecordChange({fields, model, record}) {
|
741
|
+
let me = this,
|
742
|
+
fieldNames = fields.map(field => field.name),
|
743
|
+
needsUpdate = false,
|
744
|
+
{gridContainer} = me,
|
745
|
+
{selectionModel} = gridContainer,
|
746
|
+
{vdom} = me,
|
747
|
+
cellId, cellNode, column, index, scope;
|
748
|
+
|
749
|
+
if (fieldNames.includes(me.colspanField)) {
|
750
|
+
index = me.store.indexOf(record);
|
751
|
+
me.vdom.cn[index] = me.createRow({record, rowIndex: index});
|
752
|
+
me.update()
|
753
|
+
} else {
|
754
|
+
fields.forEach(field => {
|
755
|
+
if (field.name === me.selectedRecordField) {
|
756
|
+
if (selectionModel.ntype === 'selection-grid-rowmodel') {
|
757
|
+
selectionModel[field.value ? 'select' : 'deselect'](me.getRowId(record))
|
758
|
+
}
|
759
|
+
} else {
|
760
|
+
cellId = me.getCellId(record, field.name);
|
761
|
+
cellNode = VDomUtil.find(vdom, cellId);
|
762
|
+
|
763
|
+
// the vdom might not exist yet => nothing to do in this case
|
764
|
+
if (cellNode?.vdom) {
|
765
|
+
column = me.getColumn(field.name);
|
766
|
+
index = cellNode.index;
|
767
|
+
needsUpdate = true;
|
768
|
+
scope = column.rendererScope || gridContainer;
|
769
|
+
|
770
|
+
cellNode.parentNode.cn[index] = me.applyRendererOutput({cellId, column, gridContainer, index, record})
|
771
|
+
}
|
772
|
+
}
|
773
|
+
})
|
774
|
+
}
|
329
775
|
|
330
|
-
|
331
|
-
|
332
|
-
cellNode = me.getVdomChild(cellId);
|
776
|
+
needsUpdate && me.update()
|
777
|
+
}
|
333
778
|
|
334
|
-
|
779
|
+
/**
|
780
|
+
*
|
781
|
+
*/
|
782
|
+
updateScrollHeight() {
|
783
|
+
let me = this,
|
784
|
+
countRecords = me.store.getCount(),
|
785
|
+
{rowHeight} = me;
|
786
|
+
|
787
|
+
if (countRecords > 0 && rowHeight > 0) {
|
788
|
+
me.vdom.cn[1].height = `${(countRecords + 1) * rowHeight}px`;
|
789
|
+
me.update()
|
790
|
+
}
|
791
|
+
}
|
335
792
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
793
|
+
/**
|
794
|
+
*
|
795
|
+
*/
|
796
|
+
updateVisibleColumns() {
|
797
|
+
let me = this,
|
798
|
+
{x} = me.scrollPosition,
|
799
|
+
i = 0,
|
800
|
+
len = me.columnPositions.length,
|
801
|
+
endIndex = len - 1,
|
802
|
+
column, startIndex;
|
803
|
+
|
804
|
+
for (; i < len; i++) {
|
805
|
+
column = me.columnPositions[i];
|
806
|
+
|
807
|
+
if (x >= column.x && x <= column.x + column.width) {
|
808
|
+
startIndex = i
|
809
|
+
}
|
810
|
+
|
811
|
+
if (me.containerWidth + x < column.x) {
|
812
|
+
endIndex = i - 1;
|
813
|
+
break
|
814
|
+
}
|
815
|
+
}
|
341
816
|
|
342
|
-
|
817
|
+
me.visibleColumns = [startIndex, endIndex]
|
343
818
|
}
|
344
819
|
}
|
345
820
|
|
346
|
-
export default Neo.setupClass(
|
821
|
+
export default Neo.setupClass(GridView);
|