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.
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='8.5.0'
23
+ * @member {String} version='8.6.1'
24
24
  */
25
- version: '8.5.0'
25
+ version: '8.6.1'
26
26
  }
27
27
 
28
28
  /**
@@ -16,7 +16,7 @@
16
16
  "@type": "Organization",
17
17
  "name": "Neo.mjs"
18
18
  },
19
- "datePublished": "2025-01-16",
19
+ "datePublished": "2025-01-21",
20
20
  "publisher": {
21
21
  "@type": "Organization",
22
22
  "name": "Neo.mjs"
@@ -107,7 +107,7 @@ class FooterContainer extends Container {
107
107
  }, {
108
108
  module: Component,
109
109
  cls : ['neo-version'],
110
- html : 'v8.5.0'
110
+ html : 'v8.6.1'
111
111
  }]
112
112
  }],
113
113
  /**
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='8.5.0'
23
+ * @member {String} version='8.6.1'
24
24
  */
25
- version: '8.5.0'
25
+ version: '8.6.1'
26
26
  }
27
27
 
28
28
  /**
@@ -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.user.firstname;
93
- me.getItem('lastname-field') .value = record.user.lastname;
94
- me.getItem('selected-field') .checked = record.annotations.selected
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
- this.record.country = data.value.code
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
- this.record.user.firstname = data.value
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
- this.record.user.lastname = data.value
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
- me.record.annotations.selected = false
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.selected = record === me.record ? data.value : false
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 countrySymbol = Symbol.for('country');
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[countrySymbol] = null;
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 : 'annotations.selected',
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: 'user.firstname',
31
+ name: 'firstname',
32
32
  type: 'String'
33
33
  }, {
34
- name: 'user.lastname',
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.5.0",
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.0.0",
52
+ "commander": "^13.1.0",
53
53
  "cssnano": "^7.0.6",
54
54
  "envinfo": "^7.14.0",
55
55
  "fs-extra": "^11.3.0",
@@ -262,12 +262,12 @@ const DefaultConfig = {
262
262
  useVdomWorker: true,
263
263
  /**
264
264
  * buildScripts/injectPackageVersion.mjs will update this value
265
- * @default '8.5.0'
265
+ * @default '8.6.1'
266
266
  * @memberOf! module:Neo
267
267
  * @name config.version
268
268
  * @type String
269
269
  */
270
- version: '8.5.0'
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} [create] Set create to true to create empty objects for non-existing parts
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} [create] Set create to true to create empty objects for non-existing parts
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) => {
@@ -1,4 +1,5 @@
1
- import Base from '../core/Base.mjs';
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 {Array|null} fields=null
21
+ * @member {Object[]|null} fields_=null
21
22
  */
22
- fields: null,
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
- let me = this,
48
- i = 0,
49
- len = me.fields?.length || 0;
87
+ return this.fieldsMap.get(name) || null
88
+ }
50
89
 
51
- for (; i < len; i++) {
52
- if (me.fields[i].name === name) {
53
- return me.fields[i]
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
- return null
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({config, field, me, model, path=''}) {
45
- let value = Neo.ns(field.mapping || field.name, false, config),
46
- fieldName = field.name.split('.').pop(),
47
- symbol = Symbol.for(fieldName),
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
- fieldPath = path.split('.');
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
- [symbol]: {
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
- return this[symbol]
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 oldValue = this[symbol];
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
- this[symbol] = value;
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: field.name, oldValue, value}],
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: parsedValue
91
+ value
101
92
  }
102
93
  }
103
94
 
104
- Object.defineProperties(path ? Neo.ns(path, true, me) : me, properties)
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
- let me = this;
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 changedFields = [],
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
- oldValue = record[key];
340
- value = instance.parseRecordValue(record, model.getField(key), value);
357
+ fieldExists = fieldsMap.has(key);
341
358
 
342
- if (!Neo.isEqual(oldValue, value)) {
343
- record[Symbol.for(key)] = value; // silent update
344
- record._isModified = true;
345
- changedFields.push({name: key, oldValue, value})
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
 
@@ -197,8 +197,7 @@ class Store extends Base {
197
197
  */
198
198
  afterSetModel(value, oldValue) {
199
199
  if (value) {
200
- value.storeId = this.id;
201
- RecordFactory.createRecordClass(value)
200
+ value.storeId = this.id
202
201
  }
203
202
  }
204
203
 
@@ -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 = this,
399
- {picker, record, store} = me,
400
- filter = store.getFilter(me.displayField);
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 } = me,
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
- const index = store.indexOf(record);
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 = Neo.ns(dataField, false, record),
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 && Neo.ns(me.selectedRecordField, false, record)) {
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 && model.getField(me.dataField);
429
+ field = model.getField(me.dataField);
430
430
 
431
- if (value && field.type.toLowerCase() === 'date') {
431
+ if (value && field?.type.toLowerCase() === 'date') {
432
432
  value = new Date(value)
433
433
  }
434
434
 
@@ -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
- return nodeId.nodeType ? nodeId : Neo.config.useDomIds ? document.getElementById(nodeId) : document.querySelector(`[data-neo-id='${nodeId}']`)
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} [nodeId='document.body']
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
 
@@ -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 = Neo.ns(dataField, false, record),
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 && Neo.ns(me.selectedRecordField, false, record)) {
209
+ if (selectedRows && record[me.selectedRecordField]) {
210
210
  NeoArray.add(selectedRows, id)
211
211
  }
212
212