neo.mjs 8.5.0 → 8.6.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/home/FooterContainer.mjs +1 -1
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/table/nestedRecordFields/EditUserDialog.mjs +25 -8
- package/examples/table/nestedRecordFields/MainContainerStateProvider.mjs +2 -2
- package/examples/table/nestedRecordFields/MainModel.mjs +3 -3
- package/package.json +2 -2
- package/src/DefaultConfig.mjs +2 -2
- package/src/Neo.mjs +4 -4
- package/src/data/Model.mjs +69 -11
- package/src/data/RecordFactory.mjs +82 -55
- package/src/data/Store.mjs +1 -2
- package/src/dialog/Base.mjs +2 -0
- package/src/form/field/ComboBox.mjs +7 -5
- package/src/grid/View.mjs +2 -2
- package/src/grid/header/Button.mjs +2 -2
- package/src/main/DomAccess.mjs +13 -4
- package/src/table/View.mjs +2 -2
package/apps/ServiceWorker.mjs
CHANGED
package/apps/portal/index.html
CHANGED
@@ -89,9 +89,9 @@ class EditUserDialog extends Dialog {
|
|
89
89
|
await me.timeout(20);
|
90
90
|
|
91
91
|
me.getItem('country-field') .value = record.country;
|
92
|
-
me.getItem('firstname-field').value = record
|
93
|
-
me.getItem('lastname-field') .value = record
|
94
|
-
me.getItem('selected-field') .checked = record
|
92
|
+
me.getItem('firstname-field').value = record['user.firstname'];
|
93
|
+
me.getItem('lastname-field') .value = record['user.lastname'];
|
94
|
+
me.getItem('selected-field') .checked = record['annotations.selected'];
|
95
95
|
}
|
96
96
|
}
|
97
97
|
|
@@ -99,21 +99,33 @@ class EditUserDialog extends Dialog {
|
|
99
99
|
* @param {Object} data
|
100
100
|
*/
|
101
101
|
onCountryFieldChange(data) {
|
102
|
-
|
102
|
+
// You can also access the internal setter directly:
|
103
|
+
// this.record.country = data.value.code
|
104
|
+
// Using the API allows bulk changes
|
105
|
+
|
106
|
+
this.record.set({country: data.value.code})
|
103
107
|
}
|
104
108
|
|
105
109
|
/**
|
106
110
|
* @param {Object} data
|
107
111
|
*/
|
108
112
|
onFirstnameFieldChange(data) {
|
109
|
-
|
113
|
+
// You can also access the internal setter directly:
|
114
|
+
// this.record['user.firstname'] = data.value
|
115
|
+
// Using the API allows bulk changes
|
116
|
+
this.record.set({user: {firstname: data.value}})
|
117
|
+
|
118
|
+
|
110
119
|
}
|
111
120
|
|
112
121
|
/**
|
113
122
|
* @param {Object} data
|
114
123
|
*/
|
115
124
|
onLastnameFieldChange(data) {
|
116
|
-
|
125
|
+
// You can also access the internal setter directly:
|
126
|
+
// this.record['user.lastname'] = data.value
|
127
|
+
// Using the API allows bulk changes
|
128
|
+
this.record.set({user: {lastname: data.value}})
|
117
129
|
}
|
118
130
|
|
119
131
|
/**
|
@@ -124,11 +136,16 @@ class EditUserDialog extends Dialog {
|
|
124
136
|
store = me.getStateProvider().getStore('mainStore');
|
125
137
|
|
126
138
|
if (data.value === false) {
|
127
|
-
|
139
|
+
// You can also access the internal setter directly:
|
140
|
+
// me.record['annotations.selected'] = false
|
141
|
+
// Using the API allows bulk changes
|
142
|
+
me.record.set({annotations: {selected: false}})
|
128
143
|
} else {
|
129
144
|
// Assuming we want to support a single row selection
|
130
145
|
store.items.forEach(record => {
|
131
|
-
record.annotations
|
146
|
+
record.set({annotations: {
|
147
|
+
selected: record === me.record ? data.value : false
|
148
|
+
}})
|
132
149
|
})
|
133
150
|
}
|
134
151
|
}
|
@@ -2,7 +2,7 @@ import MainStore from './MainStore.mjs';
|
|
2
2
|
import StateProvider from '../../../src/state/Provider.mjs';
|
3
3
|
import Store from '../../../src/data/Store.mjs';
|
4
4
|
|
5
|
-
const
|
5
|
+
const dataSymbol = Symbol.for('data');
|
6
6
|
|
7
7
|
/**
|
8
8
|
* @class Neo.examples.table.nestedRecordFields.MainContainerStateProvider
|
@@ -51,7 +51,7 @@ class MainContainerStateProvider extends StateProvider {
|
|
51
51
|
country = record.country;
|
52
52
|
|
53
53
|
// hack resetting the current value to get a new record change
|
54
|
-
record[
|
54
|
+
record[dataSymbol].country = null;
|
55
55
|
|
56
56
|
record.country = country
|
57
57
|
})
|
@@ -13,7 +13,7 @@ class MainModel extends Model {
|
|
13
13
|
type: 'Object',
|
14
14
|
|
15
15
|
fields: [{
|
16
|
-
name : '
|
16
|
+
name : 'selected',
|
17
17
|
type : 'Boolean',
|
18
18
|
defaultValue: false
|
19
19
|
}]
|
@@ -28,10 +28,10 @@ class MainModel extends Model {
|
|
28
28
|
type: 'Object',
|
29
29
|
|
30
30
|
fields: [{
|
31
|
-
name: '
|
31
|
+
name: 'firstname',
|
32
32
|
type: 'String'
|
33
33
|
}, {
|
34
|
-
name: '
|
34
|
+
name: 'lastname',
|
35
35
|
type: 'String'
|
36
36
|
}]
|
37
37
|
}]
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "neo.mjs",
|
3
|
-
"version": "8.
|
3
|
+
"version": "8.6.1",
|
4
4
|
"description": "The webworkers driven UI framework",
|
5
5
|
"type": "module",
|
6
6
|
"repository": {
|
@@ -49,7 +49,7 @@
|
|
49
49
|
"autoprefixer": "^10.4.20",
|
50
50
|
"chalk": "^5.4.1",
|
51
51
|
"clean-webpack-plugin": "^4.0.0",
|
52
|
-
"commander": "^13.
|
52
|
+
"commander": "^13.1.0",
|
53
53
|
"cssnano": "^7.0.6",
|
54
54
|
"envinfo": "^7.14.0",
|
55
55
|
"fs-extra": "^11.3.0",
|
package/src/DefaultConfig.mjs
CHANGED
@@ -262,12 +262,12 @@ const DefaultConfig = {
|
|
262
262
|
useVdomWorker: true,
|
263
263
|
/**
|
264
264
|
* buildScripts/injectPackageVersion.mjs will update this value
|
265
|
-
* @default '8.
|
265
|
+
* @default '8.6.1'
|
266
266
|
* @memberOf! module:Neo
|
267
267
|
* @name config.version
|
268
268
|
* @type String
|
269
269
|
*/
|
270
|
-
version: '8.
|
270
|
+
version: '8.6.1'
|
271
271
|
};
|
272
272
|
|
273
273
|
Object.assign(DefaultConfig, {
|
package/src/Neo.mjs
CHANGED
@@ -320,11 +320,11 @@ Neo = globalThis.Neo = Object.assign({
|
|
320
320
|
*
|
321
321
|
* @memberOf module:Neo
|
322
322
|
* @param {Array|String} names The class name string containing dots or an Array of the string parts
|
323
|
-
* @param {Boolean}
|
323
|
+
* @param {Boolean} create=false Set create to true to create empty objects for non-existing parts
|
324
324
|
* @param {Object} [scope] Set a different starting point as globalThis
|
325
325
|
* @returns {Object} reference to the toplevel namespace
|
326
326
|
*/
|
327
|
-
ns(names, create, scope) {
|
327
|
+
ns(names, create=false, scope) {
|
328
328
|
names = Array.isArray(names) ? names : names.split('.');
|
329
329
|
|
330
330
|
return names.reduce((prev, current) => {
|
@@ -342,11 +342,11 @@ Neo = globalThis.Neo = Object.assign({
|
|
342
342
|
* Extended version of Neo.ns() which supports mapping into arrays.
|
343
343
|
* @memberOf module:Neo
|
344
344
|
* @param {Array|String} names The class name string containing dots or an Array of the string parts
|
345
|
-
* @param {Boolean}
|
345
|
+
* @param {Boolean} create=false Set create to true to create empty objects for non-existing parts
|
346
346
|
* @param {Object} [scope] Set a different starting point as globalThis
|
347
347
|
* @returns {Object} reference to the toplevel namespace
|
348
348
|
*/
|
349
|
-
nsWithArrays(names, create, scope) {
|
349
|
+
nsWithArrays(names, create=false, scope) {
|
350
350
|
names = Array.isArray(names) ? names : names.split('.');
|
351
351
|
|
352
352
|
return names.reduce((prev, current) => {
|
package/src/data/Model.mjs
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
import Base
|
1
|
+
import Base from '../core/Base.mjs';
|
2
|
+
import RecordFactory from './RecordFactory.mjs';
|
2
3
|
|
3
4
|
/**
|
4
5
|
* @class Neo.data.Model
|
@@ -17,9 +18,9 @@ class Model extends Base {
|
|
17
18
|
*/
|
18
19
|
ntype: 'model',
|
19
20
|
/**
|
20
|
-
* @member {
|
21
|
+
* @member {Object[]|null} fields_=null
|
21
22
|
*/
|
22
|
-
|
23
|
+
fields_: null,
|
23
24
|
/**
|
24
25
|
* @member {String} keyProperty_='id'
|
25
26
|
*/
|
@@ -38,23 +39,80 @@ class Model extends Base {
|
|
38
39
|
trackModifiedFields: false
|
39
40
|
}
|
40
41
|
|
42
|
+
/**
|
43
|
+
* @member {Map} fieldsMap=new Map()
|
44
|
+
* @protected
|
45
|
+
*/
|
46
|
+
fieldsMap = new Map()
|
47
|
+
/**
|
48
|
+
* @member {Boolean} hasNestedFields=false
|
49
|
+
* @protected
|
50
|
+
*/
|
51
|
+
hasNestedFields = false
|
52
|
+
|
53
|
+
/**
|
54
|
+
* @param {Object} config
|
55
|
+
*/
|
56
|
+
construct(config) {
|
57
|
+
super.construct(config);
|
58
|
+
RecordFactory.createRecordClass(this)
|
59
|
+
}
|
60
|
+
|
61
|
+
/**
|
62
|
+
Triggered after the fields config got changed
|
63
|
+
* @param {Object[]|null} value
|
64
|
+
* @param {Object[]|null} oldValue
|
65
|
+
* @protected
|
66
|
+
*/
|
67
|
+
afterSetFields(value, oldValue) {
|
68
|
+
if (value) {
|
69
|
+
let me = this;
|
70
|
+
|
71
|
+
me.updateFieldsMap(value);
|
72
|
+
|
73
|
+
// Fields can get changed multiple times before the model instance is getting constructed.
|
74
|
+
// We only need the latest state before construction & honor run-time changes.
|
75
|
+
if (me.isConstructed) {
|
76
|
+
RecordFactory.createRecordClass(me, true)
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
41
81
|
/**
|
42
82
|
* Finds a field config by a given field name
|
43
83
|
* @param {String} name
|
44
84
|
* @returns {Object|null} The field config object or null if no match was found
|
45
85
|
*/
|
46
86
|
getField(name) {
|
47
|
-
|
48
|
-
|
49
|
-
len = me.fields?.length || 0;
|
87
|
+
return this.fieldsMap.get(name) || null
|
88
|
+
}
|
50
89
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
90
|
+
/**
|
91
|
+
* @param {Object[]} fields
|
92
|
+
* @param {Boolean} isRoot=true
|
93
|
+
* @param {String} path=''
|
94
|
+
*/
|
95
|
+
updateFieldsMap(fields, isRoot=true, path='') {
|
96
|
+
let me = this,
|
97
|
+
{fieldsMap} = me,
|
98
|
+
fieldName;
|
99
|
+
|
100
|
+
if (isRoot) {
|
101
|
+
fieldsMap.clear();
|
102
|
+
me.hasNestedFields = false
|
55
103
|
}
|
56
104
|
|
57
|
-
|
105
|
+
fields.forEach(field => {
|
106
|
+
fieldName = path + field.name
|
107
|
+
|
108
|
+
// Assuming that nested fields contain the full path as the name, we do not need a prefix.
|
109
|
+
if (field.fields) {
|
110
|
+
me.hasNestedFields = true;
|
111
|
+
me.updateFieldsMap(field.fields, false, field.name + '.')
|
112
|
+
} else {
|
113
|
+
fieldsMap.set(fieldName, field)
|
114
|
+
}
|
115
|
+
})
|
58
116
|
}
|
59
117
|
}
|
60
118
|
|
@@ -2,6 +2,8 @@ import Base from '../core/Base.mjs';
|
|
2
2
|
import Logger from '../util/Logger.mjs';
|
3
3
|
import Model from './Model.mjs';
|
4
4
|
|
5
|
+
const dataSymbol = Symbol.for('data');
|
6
|
+
|
5
7
|
let instance;
|
6
8
|
|
7
9
|
/**
|
@@ -35,57 +37,46 @@ class RecordFactory extends Base {
|
|
35
37
|
|
36
38
|
/**
|
37
39
|
* @param {Object} data
|
38
|
-
* @param {Object} data.config
|
39
40
|
* @param {Object} data.field
|
40
41
|
* @param {Neo.data.RecordFactory} data.me
|
41
42
|
* @param {Neo.data.Model} data.model
|
42
43
|
* @param {String} data.path=''
|
43
44
|
*/
|
44
|
-
createField({
|
45
|
-
let
|
46
|
-
|
47
|
-
|
48
|
-
fieldPath, parsedValue, properties;
|
45
|
+
createField({field, me, model, path=''}) {
|
46
|
+
let fieldName = field.name,
|
47
|
+
fieldPath = path === '' ? fieldName : `${path}.${fieldName}`,
|
48
|
+
properties;
|
49
49
|
|
50
50
|
if (field.fields) {
|
51
51
|
field.fields.forEach(childField => {
|
52
|
-
|
53
|
-
fieldPath = fieldPath.filter(Boolean);
|
54
|
-
fieldPath.push(field.name);
|
55
|
-
|
56
|
-
this.createField({config, field: childField, me, model, path: fieldPath.join('.')})
|
52
|
+
this.createField({field: childField, me, model, path: fieldPath})
|
57
53
|
})
|
58
54
|
} else {
|
59
|
-
if (value === undefined && Object.hasOwn(field, 'defaultValue')) {
|
60
|
-
value = field.defaultValue
|
61
|
-
}
|
62
|
-
|
63
|
-
parsedValue = instance.parseRecordValue(me, field, value, config);
|
64
|
-
|
65
55
|
properties = {
|
66
|
-
[
|
67
|
-
value : Neo.clone(parsedValue, true),
|
68
|
-
writable: true
|
69
|
-
},
|
70
|
-
[fieldName]: {
|
56
|
+
[fieldPath]: {
|
71
57
|
configurable: true,
|
72
58
|
enumerable : true,
|
73
59
|
get() {
|
74
|
-
|
60
|
+
if (model.hasNestedFields) {
|
61
|
+
return Neo.ns(fieldPath, false, this[dataSymbol])
|
62
|
+
}
|
63
|
+
|
64
|
+
return this[dataSymbol][fieldName]
|
75
65
|
},
|
76
66
|
set(value) {
|
77
|
-
let
|
67
|
+
let me = this,
|
68
|
+
oldValue = me[dataSymbol][fieldName];
|
78
69
|
|
79
70
|
value = instance.parseRecordValue(me, field, value);
|
80
71
|
|
81
72
|
if (!Neo.isEqual(value, oldValue)) {
|
82
|
-
|
73
|
+
instance.setRecordData(fieldPath, model, me, value);
|
83
74
|
|
84
75
|
me._isModified = true;
|
85
76
|
me._isModified = instance.isModified(me, model.trackModifiedFields);
|
86
77
|
|
87
78
|
instance.onRecordChange({
|
88
|
-
fields: [{name:
|
79
|
+
fields: [{name: fieldPath, oldValue, value}],
|
89
80
|
model,
|
90
81
|
record: me
|
91
82
|
})
|
@@ -97,11 +88,11 @@ class RecordFactory extends Base {
|
|
97
88
|
// adding the original value of each field
|
98
89
|
if (model.trackModifiedFields) {
|
99
90
|
properties[instance.ovPrefix + field.name] = {
|
100
|
-
value
|
91
|
+
value
|
101
92
|
}
|
102
93
|
}
|
103
94
|
|
104
|
-
Object.defineProperties(
|
95
|
+
Object.defineProperties(me, properties)
|
105
96
|
}
|
106
97
|
}
|
107
98
|
|
@@ -122,37 +113,28 @@ class RecordFactory extends Base {
|
|
122
113
|
|
123
114
|
/**
|
124
115
|
* @param {Neo.data.Model} model
|
116
|
+
* @param {Boolean} overwrite=false
|
125
117
|
* @returns {Object}
|
126
118
|
*/
|
127
|
-
createRecordClass(model) {
|
119
|
+
createRecordClass(model, overwrite=false) {
|
128
120
|
if (model instanceof Model) {
|
129
121
|
let className = `${this.recordNamespace}.${model.className}.${model.id}`,
|
130
122
|
ns = Neo.ns(className),
|
131
123
|
key, nsArray, cls;
|
132
124
|
|
133
|
-
if (!ns) {
|
125
|
+
if (!ns || overwrite) {
|
134
126
|
nsArray = className.split('.');
|
135
127
|
key = nsArray.pop();
|
136
128
|
ns = Neo.ns(nsArray, true);
|
137
129
|
cls = ns[key] = class Record {
|
138
130
|
// We do not want to minify the ctor class name in dist/production
|
139
|
-
static name = 'Record'
|
131
|
+
static name = 'Record';
|
132
|
+
|
133
|
+
[dataSymbol] = {}
|
140
134
|
|
141
135
|
constructor(config) {
|
142
|
-
|
143
|
-
|
144
|
-
Object.defineProperties(me, {
|
145
|
-
_isModified: {
|
146
|
-
value : false,
|
147
|
-
writable: true
|
148
|
-
}
|
149
|
-
});
|
150
|
-
|
151
|
-
if (Array.isArray(model.fields)) {
|
152
|
-
model.fields.forEach(field => {
|
153
|
-
instance.createField({config, field, me, model})
|
154
|
-
})
|
155
|
-
}
|
136
|
+
this.setSilent(config);
|
137
|
+
this._isModified = false
|
156
138
|
}
|
157
139
|
|
158
140
|
/**
|
@@ -170,8 +152,22 @@ class RecordFactory extends Base {
|
|
170
152
|
setSilent(fields) {
|
171
153
|
instance.setRecordFields(model, this, fields, true)
|
172
154
|
}
|
155
|
+
|
156
|
+
/**
|
157
|
+
* When using JSON.stringify(this), we want to get the raw data
|
158
|
+
* @returns {Object}
|
159
|
+
*/
|
160
|
+
toJSON() {
|
161
|
+
return this[dataSymbol]
|
162
|
+
}
|
173
163
|
};
|
174
164
|
|
165
|
+
if (Array.isArray(model.fields)) {
|
166
|
+
model.fields.forEach(field => {
|
167
|
+
instance.createField({field, me: cls.prototype, model})
|
168
|
+
})
|
169
|
+
}
|
170
|
+
|
175
171
|
Object.defineProperty(cls.prototype, 'isRecord', {value: true});
|
176
172
|
Object.defineProperty(cls, 'isClass', {value: true});
|
177
173
|
|
@@ -256,7 +252,7 @@ class RecordFactory extends Base {
|
|
256
252
|
* @param {Object} recordConfig=null
|
257
253
|
* @returns {*}
|
258
254
|
*/
|
259
|
-
parseRecordValue(record, field, value, recordConfig=null) {
|
255
|
+
parseRecordValue(record, field, value, recordConfig=null) {!field && console.log(record, value);
|
260
256
|
if (field.calculate) {
|
261
257
|
return field.calculate(record, field, recordConfig)
|
262
258
|
}
|
@@ -325,24 +321,55 @@ class RecordFactory extends Base {
|
|
325
321
|
return value
|
326
322
|
}
|
327
323
|
|
324
|
+
/**
|
325
|
+
* @param {String} fieldName
|
326
|
+
* @param {Neo.data.Model} model
|
327
|
+
* @param {Record} record
|
328
|
+
* @param {*} value
|
329
|
+
* @protected
|
330
|
+
*/
|
331
|
+
setRecordData(fieldName, model, record, value) {
|
332
|
+
if (model.hasNestedFields && fieldName.includes('.')) {
|
333
|
+
let ns, nsArray;
|
334
|
+
|
335
|
+
nsArray = fieldName.split('.');
|
336
|
+
fieldName = nsArray.pop();
|
337
|
+
ns = Neo.ns(nsArray, true, record[dataSymbol]);
|
338
|
+
|
339
|
+
ns[fieldName] = value
|
340
|
+
} else {
|
341
|
+
record[dataSymbol][fieldName] = value
|
342
|
+
}
|
343
|
+
}
|
344
|
+
|
328
345
|
/**
|
329
346
|
* @param {Neo.data.Model} model
|
330
347
|
* @param {Object} record
|
331
348
|
* @param {Object} fields
|
332
349
|
* @param {Boolean} silent=false
|
350
|
+
* @param {Object[]} changedFields=[] Internal flag
|
333
351
|
*/
|
334
|
-
setRecordFields(model, record, fields, silent=false) {
|
335
|
-
let
|
336
|
-
oldValue;
|
352
|
+
setRecordFields(model, record, fields, silent=false, changedFields=[]) {
|
353
|
+
let {fieldsMap} = model,
|
354
|
+
fieldExists, oldValue;
|
337
355
|
|
338
356
|
Object.entries(fields).forEach(([key, value]) => {
|
339
|
-
|
340
|
-
value = instance.parseRecordValue(record, model.getField(key), value);
|
357
|
+
fieldExists = fieldsMap.has(key);
|
341
358
|
|
342
|
-
if (
|
343
|
-
|
344
|
-
|
345
|
-
|
359
|
+
if (Neo.isObject(value) && !fieldExists) {
|
360
|
+
Object.entries(value).forEach(([childKey, childValue]) => {
|
361
|
+
this.setRecordFields(model, record, {[`${key}.${childKey}`]: childValue}, true, changedFields)
|
362
|
+
})
|
363
|
+
} else if (fieldExists) {
|
364
|
+
oldValue = record[key];
|
365
|
+
value = instance.parseRecordValue(record, model.getField(key), value);
|
366
|
+
|
367
|
+
if (!Neo.isEqual(oldValue, value)) {
|
368
|
+
instance.setRecordData(key, model, record, value);
|
369
|
+
|
370
|
+
record._isModified = true;
|
371
|
+
changedFields.push({name: key, oldValue, value})
|
372
|
+
}
|
346
373
|
}
|
347
374
|
});
|
348
375
|
|
package/src/data/Store.mjs
CHANGED
package/src/dialog/Base.mjs
CHANGED
@@ -414,6 +414,8 @@ class Dialog extends Panel {
|
|
414
414
|
// rendered outside the visible area
|
415
415
|
await me.render(true);
|
416
416
|
|
417
|
+
await me.timeout(30);
|
418
|
+
|
417
419
|
let [dialogRect, bodyRect] = await me.getDomRect([me.id, 'document.body']);
|
418
420
|
|
419
421
|
// Move to cover the animation target
|
@@ -395,9 +395,10 @@ class ComboBox extends Picker {
|
|
395
395
|
* @param {String|null} value The value to filter the picker by
|
396
396
|
*/
|
397
397
|
doFilter(value) {
|
398
|
-
let me
|
399
|
-
{picker,
|
400
|
-
|
398
|
+
let me = this,
|
399
|
+
{picker, store} = me,
|
400
|
+
record = me.value,
|
401
|
+
filter = store.getFilter(me.displayField);
|
401
402
|
|
402
403
|
if (filter) {
|
403
404
|
filter.value = value
|
@@ -408,7 +409,7 @@ class ComboBox extends Picker {
|
|
408
409
|
me.showPicker();
|
409
410
|
|
410
411
|
// List might not exist until the picker is created
|
411
|
-
let {list
|
412
|
+
let {list} = me,
|
412
413
|
{selectionModel} = list;
|
413
414
|
|
414
415
|
// On show, set the active item to be the current selected record or the first
|
@@ -420,7 +421,8 @@ class ComboBox extends Picker {
|
|
420
421
|
}
|
421
422
|
|
422
423
|
me.timeout(100).then(() => {
|
423
|
-
|
424
|
+
let index = store.indexOf(record);
|
425
|
+
|
424
426
|
list._focusIndex = -1; // silent update to ensure afterSetFocusIndex() always gets called
|
425
427
|
list.focusIndex = index > -1 ? index : 0
|
426
428
|
})
|
package/src/grid/View.mjs
CHANGED
@@ -388,7 +388,7 @@ class GridView extends Component {
|
|
388
388
|
cellCls = ['neo-grid-cell'],
|
389
389
|
colspan = record[me.colspanField],
|
390
390
|
{dataField} = column,
|
391
|
-
fieldValue =
|
391
|
+
fieldValue = record[dataField],
|
392
392
|
cellConfig, rendererOutput;
|
393
393
|
|
394
394
|
if (fieldValue === null || fieldValue === undefined) {
|
@@ -495,7 +495,7 @@ class GridView extends Component {
|
|
495
495
|
trCls.push('neo-even')
|
496
496
|
}
|
497
497
|
|
498
|
-
if (selectedRows &&
|
498
|
+
if (selectedRows && record[me.selectedRecordField]) {
|
499
499
|
NeoArray.add(selectedRows, id)
|
500
500
|
}
|
501
501
|
|
@@ -426,9 +426,9 @@ class Button extends BaseButton {
|
|
426
426
|
if (store) {
|
427
427
|
filter = store.getFilter(me.dataField);
|
428
428
|
model = store.model;
|
429
|
-
field = model
|
429
|
+
field = model.getField(me.dataField);
|
430
430
|
|
431
|
-
if (value && field
|
431
|
+
if (value && field?.type.toLowerCase() === 'date') {
|
432
432
|
value = new Date(value)
|
433
433
|
}
|
434
434
|
|
package/src/main/DomAccess.mjs
CHANGED
@@ -520,19 +520,28 @@ class DomAccess extends Base {
|
|
520
520
|
|
521
521
|
/**
|
522
522
|
* @param {String|HTMLElement} nodeId
|
523
|
-
* @returns {HTMLElement}
|
523
|
+
* @returns {HTMLElement|null}
|
524
524
|
* @protected
|
525
525
|
*/
|
526
526
|
getElement(nodeId) {
|
527
|
-
|
527
|
+
let node = nodeId?.nodeType ?
|
528
|
+
nodeId : Neo.config.useDomIds ?
|
529
|
+
document.getElementById(nodeId) :
|
530
|
+
document.querySelector(`[data-neo-id='${nodeId}']`);
|
531
|
+
|
532
|
+
return node || null
|
528
533
|
}
|
529
534
|
|
530
535
|
/**
|
531
|
-
* @param {String|HTMLElement}
|
532
|
-
* @returns {HTMLElement}
|
536
|
+
* @param {String|HTMLElement} nodeId='document.body'
|
537
|
+
* @returns {HTMLElement|null}
|
533
538
|
* @protected
|
534
539
|
*/
|
535
540
|
getElementOrBody(nodeId='document.body') {
|
541
|
+
if (!nodeId) {
|
542
|
+
return null
|
543
|
+
}
|
544
|
+
|
536
545
|
return nodeId.nodeType ? nodeId : (nodeId === 'body' || nodeId === 'document.body') ? document.body : this.getElement(nodeId)
|
537
546
|
}
|
538
547
|
|
package/src/table/View.mjs
CHANGED
@@ -104,7 +104,7 @@ class View extends Component {
|
|
104
104
|
cellCls = ['neo-table-cell'],
|
105
105
|
colspan = record[me.colspanField],
|
106
106
|
{dataField} = column,
|
107
|
-
fieldValue =
|
107
|
+
fieldValue = record[dataField],
|
108
108
|
hasStore = tableContainer.store?.model, // todo: remove as soon as all tables use stores (examples table)
|
109
109
|
{vdom} = me,
|
110
110
|
cellConfig, rendererOutput;
|
@@ -206,7 +206,7 @@ class View extends Component {
|
|
206
206
|
|
207
207
|
me.recordVnodeMap[id] = rowIndex;
|
208
208
|
|
209
|
-
if (selectedRows &&
|
209
|
+
if (selectedRows && record[me.selectedRecordField]) {
|
210
210
|
NeoArray.add(selectedRows, id)
|
211
211
|
}
|
212
212
|
|