neo.mjs 6.2.1 → 6.3.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/examples/ServiceWorker.mjs +2 -2
- package/examples/popover/MainContainer.mjs +58 -0
- package/examples/{treeSelectionModel → popover}/app.mjs +1 -1
- package/examples/popover/neo-config.json +13 -0
- package/examples/{treeSelectionModel → popover}/tree.json +1 -1
- package/examples/{treeSelectionModel → treeAccordion}/MainContainer.mjs +12 -4
- package/examples/treeAccordion/app.mjs +6 -0
- package/examples/treeAccordion/index.html +11 -0
- package/examples/{treeSelectionModel → treeAccordion}/neo-config.json +1 -1
- package/examples/treeAccordion/tree.json +112 -0
- package/package.json +1 -1
- package/resources/scss/src/examples/popover/MainContainer.scss +111 -0
- package/src/DefaultConfig.mjs +2 -2
- package/src/form/Container.mjs +13 -1
- package/src/form/field/Base.mjs +34 -19
- package/src/form/field/CheckBox.mjs +30 -2
- package/src/form/field/Radio.mjs +15 -3
- package/src/main/addon/Popover.mjs +75 -0
- package/src/tree/Accordion.mjs +70 -17
- /package/examples/{treeSelectionModel → popover}/index.html +0 -0
- /package/resources/scss/src/examples/{treeSelectionModel → treeAccordion}/MainContainer.scss +0 -0
package/apps/ServiceWorker.mjs
CHANGED
@@ -0,0 +1,58 @@
|
|
1
|
+
import ConfigurationViewport from '../ConfigurationViewport.mjs';
|
2
|
+
|
3
|
+
import Component from '../../src/component/Base.mjs';
|
4
|
+
import PopoverPlugin from '../../src/plugin/Popover.mjs';
|
5
|
+
import Button from '../../src/button/Base.mjs';
|
6
|
+
|
7
|
+
/**
|
8
|
+
* @class Neo.examples.popover.MainContainer
|
9
|
+
* @extends Neo.examples.ConfigurationViewport
|
10
|
+
*/
|
11
|
+
class MainContainer extends ConfigurationViewport {
|
12
|
+
static config = {
|
13
|
+
className : 'Neo.examples.popover.MainContainer',
|
14
|
+
autoMount : true,
|
15
|
+
configItemLabelWidth: 100,
|
16
|
+
configItemWidth : 230,
|
17
|
+
layout : {ntype: 'hbox', align: 'stretch'},
|
18
|
+
cls : ['examples-container-accordion']
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
/**
|
23
|
+
* @returns {*}
|
24
|
+
*/
|
25
|
+
createExampleComponent() {
|
26
|
+
return Neo.ntype({
|
27
|
+
ntype : 'container',
|
28
|
+
height: '30%',
|
29
|
+
layout: {ntype: 'vbox', align: 'center', pack: 'center'},
|
30
|
+
items : [{
|
31
|
+
module: Component,
|
32
|
+
height: 10
|
33
|
+
}, {
|
34
|
+
module : Button,
|
35
|
+
width : 200,
|
36
|
+
text : 'Click Me',
|
37
|
+
plugins: [{
|
38
|
+
module: PopoverPlugin,
|
39
|
+
align : 'bc-tc',
|
40
|
+
items : [{
|
41
|
+
ntype : 'panel',
|
42
|
+
headers: [{
|
43
|
+
dock: 'top',
|
44
|
+
html: 'HEADER'
|
45
|
+
}],
|
46
|
+
items : [{
|
47
|
+
html: 'This is a comment about the button'
|
48
|
+
}]
|
49
|
+
}]
|
50
|
+
}]
|
51
|
+
}]
|
52
|
+
});
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
Neo.applyClassConfig(MainContainer);
|
57
|
+
|
58
|
+
export default MainContainer;
|
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"appPath" : "examples/popover/app.mjs",
|
3
|
+
"basePath" : "../../",
|
4
|
+
"environment": "development",
|
5
|
+
"mainPath" : "./Main.mjs",
|
6
|
+
"themes" : ["neo-theme-dark", "neo-theme-light"],
|
7
|
+
"mainThreadAddons": [
|
8
|
+
"DragDrop",
|
9
|
+
"ScrollSync",
|
10
|
+
"Stylesheet",
|
11
|
+
"Popover"
|
12
|
+
]
|
13
|
+
}
|
@@ -10,12 +10,12 @@ import ViewController from '../../src/controller/Component.mjs';
|
|
10
10
|
import ViewModel from '../../src/model/Component.mjs';
|
11
11
|
|
12
12
|
/**
|
13
|
-
* @class Neo.examples.
|
13
|
+
* @class Neo.examples.treeAccordion.MainContainer
|
14
14
|
* @extends Neo.examples.ConfigurationViewport
|
15
15
|
*/
|
16
16
|
class MainContainer extends ConfigurationViewport {
|
17
17
|
static config = {
|
18
|
-
className : 'Neo.examples.
|
18
|
+
className : 'Neo.examples.treeAccordion.MainContainer',
|
19
19
|
autoMount : true,
|
20
20
|
configItemLabelWidth: 100,
|
21
21
|
configItemWidth : 230,
|
@@ -46,6 +46,14 @@ class MainContainer extends ConfigurationViewport {
|
|
46
46
|
listeners : {change: me.onConfigChange.bind(me, 'firstParentIsVisible')},
|
47
47
|
style : {marginTop: '10px'},
|
48
48
|
valueLabelText: 'firstParentIsVisible'
|
49
|
+
}, {
|
50
|
+
module : CheckBox,
|
51
|
+
checked : treeList.showIcon,
|
52
|
+
hideLabel : true,
|
53
|
+
hideValueLabel: false,
|
54
|
+
listeners : {change: me.onConfigChange.bind(me, 'showIcon')},
|
55
|
+
style : {marginTop: '10px'},
|
56
|
+
valueLabelText: 'showIcon'
|
49
57
|
}, {
|
50
58
|
module : NumberField,
|
51
59
|
clearable: true,
|
@@ -89,7 +97,7 @@ class MainContainer extends ConfigurationViewport {
|
|
89
97
|
},
|
90
98
|
|
91
99
|
autoLoad: true,
|
92
|
-
url : '../../examples/
|
100
|
+
url : '../../examples/treeAccordion/tree.json'
|
93
101
|
});
|
94
102
|
|
95
103
|
return Neo.ntype({
|
@@ -135,7 +143,7 @@ class MainContainer extends ConfigurationViewport {
|
|
135
143
|
}, {
|
136
144
|
module: Panel,
|
137
145
|
height: 150,
|
138
|
-
|
146
|
+
flex : 1,
|
139
147
|
|
140
148
|
itemDefaults: {
|
141
149
|
style: {
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<!DOCTYPE HTML>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
5
|
+
<meta charset="UTF-8">
|
6
|
+
<title>Neo Tree</title>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<script src="../../src/MicroLoader.mjs" type="module"></script>
|
10
|
+
</body>
|
11
|
+
</html>
|
@@ -0,0 +1,112 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"id": 1,
|
4
|
+
"name": "ROOT",
|
5
|
+
"parentId": null,
|
6
|
+
"collapsed": false,
|
7
|
+
"isLeaf": false
|
8
|
+
},
|
9
|
+
{
|
10
|
+
"id": 2,
|
11
|
+
"name": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr,",
|
12
|
+
"parentId": 1,
|
13
|
+
"isLeaf": true,
|
14
|
+
"content": "Textfeld",
|
15
|
+
"iconCls": "fa fa-t color-blue"
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"id": 3,
|
19
|
+
"name": "Sed diam nonumy",
|
20
|
+
"parentId": 1,
|
21
|
+
"isLeaf": true,
|
22
|
+
"content": "Textfeld",
|
23
|
+
"iconCls": "fa fa-t color-blue"
|
24
|
+
},
|
25
|
+
{
|
26
|
+
"id": 4,
|
27
|
+
"name": "Eirmod",
|
28
|
+
"parentId": 1,
|
29
|
+
"isLeaf": true,
|
30
|
+
"content": "Textfeld",
|
31
|
+
"iconCls": "fa fa-t color-blue"
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"id": 5,
|
35
|
+
"name": "Tempor",
|
36
|
+
"parentId": 1,
|
37
|
+
"isLeaf": true,
|
38
|
+
"content": "Textfeld",
|
39
|
+
"iconCls": "fa fa-t color-blue"
|
40
|
+
},
|
41
|
+
{
|
42
|
+
"id": 6,
|
43
|
+
"name": "Invidunt ut labore",
|
44
|
+
"parentId": 1,
|
45
|
+
"isLeaf": true,
|
46
|
+
"content": "Textfeld",
|
47
|
+
"iconCls": "fa fa-t color-blue"
|
48
|
+
},
|
49
|
+
{
|
50
|
+
"id": 7,
|
51
|
+
"name": "Dolore magna aliquyam",
|
52
|
+
"parentId": null,
|
53
|
+
"collapsed": false,
|
54
|
+
"isLeaf": false
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"id": 8,
|
58
|
+
"name": "V01 . At vero eos et accusam",
|
59
|
+
"parentId": 7,
|
60
|
+
"collapsed": false,
|
61
|
+
"isLeaf": false,
|
62
|
+
"content": "Auswählliste",
|
63
|
+
"iconCls": "fa fa-chevron-down color-red"
|
64
|
+
},
|
65
|
+
{
|
66
|
+
"id": 9,
|
67
|
+
"name": "Justo 1",
|
68
|
+
"parentId": 8,
|
69
|
+
"isLeaf": true,
|
70
|
+
"content": "Child",
|
71
|
+
"iconCls": "fa-regular fa-square-check color-green"
|
72
|
+
},
|
73
|
+
{
|
74
|
+
"id": 10,
|
75
|
+
"name": "Justo 2",
|
76
|
+
"parentId": 8,
|
77
|
+
"isLeaf": true,
|
78
|
+
"content": "Child",
|
79
|
+
"iconCls": "fa-regular fa-square-check color-green"
|
80
|
+
},
|
81
|
+
{
|
82
|
+
"id": 11,
|
83
|
+
"name": "Rebum",
|
84
|
+
"parentId": null,
|
85
|
+
"collapsed": false,
|
86
|
+
"isLeaf": false
|
87
|
+
},
|
88
|
+
{
|
89
|
+
"id": 12,
|
90
|
+
"name": "F0801 - Stet ",
|
91
|
+
"parentId": 11,
|
92
|
+
"isLeaf": true,
|
93
|
+
"content": "Datumfeld",
|
94
|
+
"iconCls": "fa-solid fa-calendar-days color-yellow"
|
95
|
+
},
|
96
|
+
{
|
97
|
+
"id": 13,
|
98
|
+
"name": "F0802 - Kasd",
|
99
|
+
"parentId": 11,
|
100
|
+
"isLeaf": true,
|
101
|
+
"content": "Datumfeld",
|
102
|
+
"iconCls": "fa-solid fa-calendar-days color-yellow"
|
103
|
+
},
|
104
|
+
{
|
105
|
+
"id": 14,
|
106
|
+
"name": "E30 - Gubergren",
|
107
|
+
"parentId": 11,
|
108
|
+
"isLeaf": true,
|
109
|
+
"content": "Mehrfachauswahl",
|
110
|
+
"iconCls": "fa-regular fa-square-check color-green"
|
111
|
+
}
|
112
|
+
]
|
package/package.json
CHANGED
@@ -0,0 +1,111 @@
|
|
1
|
+
[popover] {
|
2
|
+
inset: unset;
|
3
|
+
border-radius: 5px;
|
4
|
+
box-shadow: 2px 2px 7px #111;
|
5
|
+
background-color: #222;
|
6
|
+
|
7
|
+
//&.neo-popover[popover] {
|
8
|
+
// display: revert;
|
9
|
+
//}
|
10
|
+
|
11
|
+
&.bc-tc {
|
12
|
+
position-fallback: --bc-tc;
|
13
|
+
translate: -50%;
|
14
|
+
margin: .5rem 0;
|
15
|
+
}
|
16
|
+
&.tc-bc {
|
17
|
+
position-fallback: --tc-bc;
|
18
|
+
translate: -50%;
|
19
|
+
margin: .5rem 0;
|
20
|
+
}
|
21
|
+
&.tl-tr {
|
22
|
+
position-fallback: --tl-tr;
|
23
|
+
margin: 0 .5rem;
|
24
|
+
}
|
25
|
+
&.tr-tl {
|
26
|
+
position-fallback: --tl-tr;
|
27
|
+
margin: 0 .5rem;
|
28
|
+
}
|
29
|
+
&.cl-cr {
|
30
|
+
position-fallback: --cl-cr;
|
31
|
+
margin: 0 .25rem;
|
32
|
+
translate: 0 -50%;
|
33
|
+
}
|
34
|
+
&.cr-cl {
|
35
|
+
position-fallback: --cr-cl;
|
36
|
+
margin: 0 .25rem;
|
37
|
+
translate: 0 -50%;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
@position-fallback --bc-tc {
|
42
|
+
@try {
|
43
|
+
bottom: anchor(top);
|
44
|
+
left: anchor(center);
|
45
|
+
}
|
46
|
+
|
47
|
+
@try {
|
48
|
+
top: anchor(bottom);
|
49
|
+
left: anchor(center);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
@position-fallback --tc-bc {
|
54
|
+
@try {
|
55
|
+
top: anchor(bottom);
|
56
|
+
left: anchor(center);
|
57
|
+
}
|
58
|
+
|
59
|
+
@try {
|
60
|
+
bottom: anchor(top);
|
61
|
+
left: anchor(center);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
@position-fallback --tl-tr {
|
66
|
+
@try {
|
67
|
+
top: anchor(top);
|
68
|
+
left: anchor(right);
|
69
|
+
}
|
70
|
+
|
71
|
+
@try {
|
72
|
+
top: anchor(top);
|
73
|
+
right: anchor(left);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
@position-fallback --tr-tl {
|
78
|
+
@try {
|
79
|
+
top: anchor(top);
|
80
|
+
right: anchor(left);
|
81
|
+
}
|
82
|
+
|
83
|
+
@try {
|
84
|
+
top: anchor(top);
|
85
|
+
left: anchor(right);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
@position-fallback --cr-cl {
|
90
|
+
@try {
|
91
|
+
top: anchor(center);
|
92
|
+
right: anchor(left);
|
93
|
+
}
|
94
|
+
|
95
|
+
@try {
|
96
|
+
top: anchor(center);
|
97
|
+
left: anchor(right);
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
@position-fallback --cl-cr {
|
102
|
+
@try {
|
103
|
+
top: anchor(center);
|
104
|
+
left: anchor(right);
|
105
|
+
}
|
106
|
+
|
107
|
+
@try {
|
108
|
+
top: anchor(center);
|
109
|
+
right: anchor(left);
|
110
|
+
}
|
111
|
+
}
|
package/src/DefaultConfig.mjs
CHANGED
@@ -236,12 +236,12 @@ const DefaultConfig = {
|
|
236
236
|
useVdomWorker: true,
|
237
237
|
/**
|
238
238
|
* buildScripts/injectPackageVersion.mjs will update this value
|
239
|
-
* @default '6.
|
239
|
+
* @default '6.3.0'
|
240
240
|
* @memberOf! module:Neo
|
241
241
|
* @name config.version
|
242
242
|
* @type String
|
243
243
|
*/
|
244
|
-
version: '6.
|
244
|
+
version: '6.3.0'
|
245
245
|
};
|
246
246
|
|
247
247
|
Object.assign(DefaultConfig, {
|
package/src/form/Container.mjs
CHANGED
@@ -135,6 +135,7 @@ class Container extends BaseContainer {
|
|
135
135
|
*/
|
136
136
|
async getValues() {
|
137
137
|
let fields = await this.getFields(),
|
138
|
+
Radio = Neo.form.field.Radio,
|
138
139
|
values = {},
|
139
140
|
itemName, key, ns, nsArray, value;
|
140
141
|
|
@@ -156,12 +157,23 @@ class Container extends BaseContainer {
|
|
156
157
|
ns = values
|
157
158
|
}
|
158
159
|
|
160
|
+
// Ensuring that Radios will not return arrays
|
161
|
+
if (Radio && item instanceof Radio) {
|
162
|
+
// Only overwrite an existing value with a checked value
|
163
|
+
if (Object.hasOwn(ns, key)) {
|
164
|
+
if (value !== item.uncheckedValue) {
|
165
|
+
ns[key] = value
|
166
|
+
}
|
167
|
+
} else {
|
168
|
+
ns[key] = value
|
169
|
+
}
|
170
|
+
}
|
159
171
|
/*
|
160
172
|
* CheckBoxes need custom logic
|
161
173
|
* => we only want to pass the uncheckedValue in case the field does not belong to a group
|
162
174
|
* (multiple fields using the same name)
|
163
175
|
*/
|
164
|
-
if (Object.hasOwn(ns, key) && value !== undefined) {
|
176
|
+
else if (Object.hasOwn(ns, key) && value !== undefined) {
|
165
177
|
if (ns[key] === item.uncheckedValue) {
|
166
178
|
ns[key] = []
|
167
179
|
} else if (!Array.isArray(ns[key])) {
|
package/src/form/field/Base.mjs
CHANGED
@@ -76,9 +76,7 @@ class Base extends Component {
|
|
76
76
|
* @param {*} oldValue
|
77
77
|
*/
|
78
78
|
afterSetValue(value, oldValue) {
|
79
|
-
|
80
|
-
this.fireChangeEvent(value, oldValue)
|
81
|
-
}
|
79
|
+
oldValue !== undefined && this.fireChangeEvent(value, oldValue)
|
82
80
|
}
|
83
81
|
|
84
82
|
/**
|
@@ -134,27 +132,42 @@ class Base extends Component {
|
|
134
132
|
*/
|
135
133
|
fireChangeEvent(value, oldValue) {
|
136
134
|
let me = this,
|
137
|
-
FormContainer = Neo.form?.Container
|
135
|
+
FormContainer = Neo.form?.Container,
|
136
|
+
opts = {component: me, oldValue, value};
|
138
137
|
|
139
|
-
me.
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
138
|
+
if (Neo.isFunction(me.getGroupValue)) {
|
139
|
+
opts.groupValue = me.getGroupValue()
|
140
|
+
}
|
141
|
+
|
142
|
+
me.fire('change', opts);
|
144
143
|
|
145
144
|
if (!me.suspendEvents) {
|
146
145
|
ComponentManager.getParents(me).forEach(parent => {
|
147
146
|
if (FormContainer && parent instanceof FormContainer) {
|
148
|
-
parent.fire('fieldChange',
|
149
|
-
component: me,
|
150
|
-
oldValue,
|
151
|
-
value
|
152
|
-
})
|
147
|
+
parent.fire('fieldChange', opts)
|
153
148
|
}
|
154
149
|
})
|
155
150
|
}
|
156
151
|
}
|
157
152
|
|
153
|
+
/**
|
154
|
+
* Forms in neo can be nested. This method will return the closest parent which is a form.Container or null.
|
155
|
+
* @returns {Neo.form.Container|null}
|
156
|
+
*/
|
157
|
+
getClosestForm() {
|
158
|
+
let me = this,
|
159
|
+
FormContainer = Neo.form?.Container,
|
160
|
+
parent;
|
161
|
+
|
162
|
+
for (parent of ComponentManager.getParents(me)) {
|
163
|
+
if (FormContainer && parent instanceof FormContainer) {
|
164
|
+
return parent
|
165
|
+
}
|
166
|
+
}
|
167
|
+
|
168
|
+
return null
|
169
|
+
}
|
170
|
+
|
158
171
|
/**
|
159
172
|
* Override this method as needed
|
160
173
|
* @returns {Object|null}
|
@@ -213,15 +226,17 @@ class Base extends Component {
|
|
213
226
|
super.onFocusLeave?.(data);
|
214
227
|
|
215
228
|
let me = this,
|
216
|
-
FormContainer = Neo.form?.Container
|
229
|
+
FormContainer = Neo.form?.Container,
|
230
|
+
opts = {...data, component: me, value: me.getValue()};
|
231
|
+
|
232
|
+
if (Neo.isFunction(me.getGroupValue)) {
|
233
|
+
opts.groupValue = me.getGroupValue()
|
234
|
+
}
|
217
235
|
|
218
236
|
if (!me.suspendEvents) {
|
219
237
|
ComponentManager.getParents(me).forEach(parent => {
|
220
238
|
if (FormContainer && parent instanceof FormContainer) {
|
221
|
-
parent.fire('fieldFocusLeave',
|
222
|
-
...data,
|
223
|
-
component: me
|
224
|
-
})
|
239
|
+
parent.fire('fieldFocusLeave', opts)
|
225
240
|
}
|
226
241
|
})
|
227
242
|
}
|
@@ -194,7 +194,7 @@ class CheckBox extends Base {
|
|
194
194
|
me.update();
|
195
195
|
|
196
196
|
if (oldValue !== undefined) {
|
197
|
-
me.fireChangeEvent(me.getValue(),
|
197
|
+
me.fireChangeEvent(me.getValue(), me.getOldValue())
|
198
198
|
}
|
199
199
|
}
|
200
200
|
|
@@ -433,6 +433,23 @@ class CheckBox extends Base {
|
|
433
433
|
return true
|
434
434
|
}
|
435
435
|
|
436
|
+
/**
|
437
|
+
* @returns {String[]}
|
438
|
+
*/
|
439
|
+
getGroupValue() {
|
440
|
+
let form = this.getClosestForm(),
|
441
|
+
fields = ComponentManager.find({path: this.getPath()}),
|
442
|
+
value = [];
|
443
|
+
|
444
|
+
fields.forEach(field => {
|
445
|
+
if (field.checked && field.getClosestForm() === form) {
|
446
|
+
NeoArray.add(value, field.value)
|
447
|
+
}
|
448
|
+
});
|
449
|
+
|
450
|
+
return value
|
451
|
+
}
|
452
|
+
|
436
453
|
/**
|
437
454
|
* @returns {String}
|
438
455
|
*/
|
@@ -462,6 +479,17 @@ class CheckBox extends Base {
|
|
462
479
|
}
|
463
480
|
|
464
481
|
/**
|
482
|
+
* Counterpart to getValue(), returning the uncheckedValue if checked
|
483
|
+
* @returns {String|null}
|
484
|
+
*/
|
485
|
+
getOldValue() {
|
486
|
+
let me = this;
|
487
|
+
|
488
|
+
return me.checked ? me.uncheckedValue : me.value
|
489
|
+
}
|
490
|
+
|
491
|
+
/**
|
492
|
+
* Returns this.value if checked, otherwise this.uncheckedValue
|
465
493
|
* @returns {String|null}
|
466
494
|
*/
|
467
495
|
getValue() {
|
@@ -482,7 +510,7 @@ class CheckBox extends Base {
|
|
482
510
|
*/
|
483
511
|
isValid() {
|
484
512
|
this.validate(true); // silent
|
485
|
-
|
513
|
+
|
486
514
|
return this.error ? false : super.isValid()
|
487
515
|
}
|
488
516
|
|
package/src/form/field/Radio.mjs
CHANGED
@@ -45,10 +45,22 @@ class Radio extends CheckBox {
|
|
45
45
|
}
|
46
46
|
|
47
47
|
/**
|
48
|
-
*
|
48
|
+
* Radios should only fire change & fieldChange events if checked.
|
49
|
+
* If there was just 1 radio, you can not uncheck it.
|
50
|
+
* @param {*} value
|
51
|
+
* @param {*} oldValue
|
49
52
|
*/
|
50
|
-
|
51
|
-
|
53
|
+
fireChangeEvent(value, oldValue) {
|
54
|
+
this.checked && super.fireChangeEvent(value, oldValue)
|
55
|
+
}
|
56
|
+
|
57
|
+
/**
|
58
|
+
* @returns {String[]}
|
59
|
+
*/
|
60
|
+
getGroupValue() {
|
61
|
+
let value = super.getGroupValue();
|
62
|
+
|
63
|
+
return value.length > 0 ? value[0] : []
|
52
64
|
}
|
53
65
|
|
54
66
|
/**
|
@@ -0,0 +1,75 @@
|
|
1
|
+
import Base from '../../core/Base.mjs';
|
2
|
+
import DomAccess from '../DomAccess.mjs'
|
3
|
+
/**
|
4
|
+
* Addon for Popover
|
5
|
+
* @class Neo.main.addon.Popover
|
6
|
+
* @extends Neo.core.Base
|
7
|
+
* @singleton
|
8
|
+
*/
|
9
|
+
class Popover extends Base {
|
10
|
+
static config = {
|
11
|
+
/**
|
12
|
+
* @member {String} className='Neo.main.addon.Popover'
|
13
|
+
* @protected
|
14
|
+
*/
|
15
|
+
className: 'Neo.main.addon.Popover',
|
16
|
+
/**
|
17
|
+
* Remote method access for other workers
|
18
|
+
* @member {Object} remote={app: [//...]}
|
19
|
+
* @protected
|
20
|
+
*/
|
21
|
+
remote: {
|
22
|
+
app: [
|
23
|
+
'hide',
|
24
|
+
'show',
|
25
|
+
'toggle'
|
26
|
+
]
|
27
|
+
},
|
28
|
+
/**
|
29
|
+
* @member {Boolean} singleton=true
|
30
|
+
* @protected
|
31
|
+
*/
|
32
|
+
singleton: true
|
33
|
+
}
|
34
|
+
|
35
|
+
/**
|
36
|
+
* @param {Object} data
|
37
|
+
* @param {String} data.id
|
38
|
+
* @returns {Boolean}
|
39
|
+
*/
|
40
|
+
hide(data) {
|
41
|
+
this.getPopover(data.id).hidePopover();
|
42
|
+
return true;
|
43
|
+
}
|
44
|
+
|
45
|
+
/**
|
46
|
+
* @param {Object} data
|
47
|
+
* @param {String} data.id
|
48
|
+
* @returns {Boolean}
|
49
|
+
*/
|
50
|
+
show(data) {
|
51
|
+
this.getPopover(data.id).showPopover();
|
52
|
+
return true;
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* @param {Object} data
|
57
|
+
* @param {String} data.id
|
58
|
+
* @returns {Boolean}
|
59
|
+
*/
|
60
|
+
toggle(data) {
|
61
|
+
this.getPopover(data.id).togglePopover();
|
62
|
+
return true;
|
63
|
+
}
|
64
|
+
|
65
|
+
getPopover(parentId) {
|
66
|
+
const parent = document.getElementById(parentId),
|
67
|
+
popover = document.getElementById(parent.getAttribute('popovertarget'));
|
68
|
+
|
69
|
+
return popover;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
let instance = Neo.applyClassConfig(Popover);
|
74
|
+
|
75
|
+
export default instance;
|
package/src/tree/Accordion.mjs
CHANGED
@@ -7,6 +7,20 @@ import VDomUtil from "../util/VDom.mjs";
|
|
7
7
|
/**
|
8
8
|
* @class Neo.tree.Accordion
|
9
9
|
* @extends Neo.tree.List
|
10
|
+
*
|
11
|
+
* Accordion Store expects the following fields
|
12
|
+
*
|
13
|
+
* [
|
14
|
+
* iconCls, // can be defined in fields:icon
|
15
|
+
* content, // can be defined in fields:text
|
16
|
+
* name, // can be defined in fields:header
|
17
|
+
*
|
18
|
+
* collapsed, // collapsed state for non-leaf-items
|
19
|
+
* isLeaf, // defines it item is leaf-item
|
20
|
+
* id, // defines item id
|
21
|
+
* parentId // leaf or sub-items need a parentId
|
22
|
+
* ]
|
23
|
+
*
|
10
24
|
*/
|
11
25
|
class AccordionTree extends TreeList {
|
12
26
|
static config = {
|
@@ -25,19 +39,24 @@ class AccordionTree extends TreeList {
|
|
25
39
|
*/
|
26
40
|
baseCls: ['neo-tree-list'],
|
27
41
|
/**
|
28
|
-
*
|
42
|
+
* Set to false to hide the initial root item
|
43
|
+
* @member {Boolean} firstParentIsVisible=true
|
29
44
|
*/
|
30
|
-
|
45
|
+
firstParentIsVisible_: true,
|
46
|
+
/**
|
47
|
+
* Define the field names for the store to show header, text and icon
|
48
|
+
* @member {Object} fields={header:'name',icon:'iconCls',text:'content'}
|
49
|
+
*/
|
50
|
+
fields: {
|
51
|
+
header: 'name',
|
52
|
+
icon : 'iconCls',
|
53
|
+
text : 'content'
|
54
|
+
},
|
31
55
|
/**
|
32
56
|
* Set to false will auto expand root parent items and disallow collapsing
|
33
57
|
* @member {Boolean} rootParentIsCollapsible=false
|
34
58
|
*/
|
35
59
|
rootParentsAreCollapsible_: false,
|
36
|
-
/**
|
37
|
-
* Set to false to hide the initial root item
|
38
|
-
* @member {Boolean} firstParentIsVisible=true
|
39
|
-
*/
|
40
|
-
firstParentIsVisible_: true,
|
41
60
|
/**
|
42
61
|
* Currently selected item, which is bindable
|
43
62
|
* @member {Record[]|null} selection=null
|
@@ -50,6 +69,15 @@ class AccordionTree extends TreeList {
|
|
50
69
|
* bind : {html: data => data.selection[0].name}
|
51
70
|
*/
|
52
71
|
selection_: null,
|
72
|
+
/**
|
73
|
+
* Set to false will hide the icons for all leaf items
|
74
|
+
* @member {Boolean} showIcon=true
|
75
|
+
*/
|
76
|
+
showIcon_: true,
|
77
|
+
/**
|
78
|
+
* @member {Boolean} showCollapseExpandAllIcons=true
|
79
|
+
*/
|
80
|
+
showCollapseExpandAllIcons: false,
|
53
81
|
/**
|
54
82
|
* @member {Object} _vdom
|
55
83
|
*/
|
@@ -114,6 +142,31 @@ class AccordionTree extends TreeList {
|
|
114
142
|
}
|
115
143
|
}
|
116
144
|
|
145
|
+
/**
|
146
|
+
* Called when changing showIcon
|
147
|
+
* Changes the display of the icons
|
148
|
+
*
|
149
|
+
* @param {Boolean} value
|
150
|
+
* @param {Boolean} oldValue
|
151
|
+
*/
|
152
|
+
afterSetShowIcon(value, oldValue) {
|
153
|
+
const me = this,
|
154
|
+
store = me.store,
|
155
|
+
hide = !value;
|
156
|
+
|
157
|
+
store.items.forEach((record) => {
|
158
|
+
const itemId = me.getItemId(record[me.getKeyProperty()]),
|
159
|
+
vdom = me.getVdomChild(itemId),
|
160
|
+
itemVdom = VDomUtil.getByFlag(vdom, 'icon');
|
161
|
+
|
162
|
+
if (record.isLeaf) {
|
163
|
+
itemVdom.removeDom = hide;
|
164
|
+
}
|
165
|
+
})
|
166
|
+
|
167
|
+
me.update()
|
168
|
+
}
|
169
|
+
|
117
170
|
/**
|
118
171
|
* Triggered before the selectionModel config gets changed.
|
119
172
|
* @param {Neo.selection.Model} value
|
@@ -211,10 +264,11 @@ class AccordionTree extends TreeList {
|
|
211
264
|
cls,
|
212
265
|
id,
|
213
266
|
cn : [{
|
267
|
+
flag : 'icon',
|
214
268
|
tag : 'span',
|
215
|
-
cls : ['neo-accordion-item-icon', item.
|
216
|
-
id : id + '
|
217
|
-
removeDom: !item.isLeaf
|
269
|
+
cls : ['neo-accordion-item-icon', item[me.fields.icon]],
|
270
|
+
id : id + '__icon',
|
271
|
+
removeDom: (!item.isLeaf || !me.showIcon)
|
218
272
|
}, {
|
219
273
|
cls : [itemCls + '-content'],
|
220
274
|
id : id + '__item-content',
|
@@ -224,13 +278,13 @@ class AccordionTree extends TreeList {
|
|
224
278
|
tag : 'span',
|
225
279
|
cls : [itemCls + '-content-header'],
|
226
280
|
id : id + '__item-content-header',
|
227
|
-
innerHTML: item.
|
281
|
+
innerHTML: item[me.fields.header]
|
228
282
|
}, {
|
229
283
|
flag : 'content',
|
230
284
|
tag : 'span',
|
231
285
|
cls : [itemCls + '-content-text'],
|
232
286
|
id : id + '__item-content-text',
|
233
|
-
innerHTML: item.
|
287
|
+
innerHTML: item[me.fields.text]
|
234
288
|
}]
|
235
289
|
}],
|
236
290
|
style: {
|
@@ -273,7 +327,6 @@ class AccordionTree extends TreeList {
|
|
273
327
|
const me = this,
|
274
328
|
selectionModel = me.selectionModel,
|
275
329
|
itemId = item.id,
|
276
|
-
// ! todo make it String
|
277
330
|
id = Number(itemId.split('__')[1]),
|
278
331
|
record = me.store.get(id);
|
279
332
|
|
@@ -354,11 +407,11 @@ class AccordionTree extends TreeList {
|
|
354
407
|
|
355
408
|
/**
|
356
409
|
* Update a record
|
357
|
-
* @param {Object}
|
358
|
-
* @param {Object[]}
|
359
|
-
* @param {Number}
|
410
|
+
* @param {Object} data
|
411
|
+
* @param {Object[]} data.fields
|
412
|
+
* @param {Number} data.index
|
360
413
|
* @param {Neo.data.Model} data.model
|
361
|
-
* @param {Record}
|
414
|
+
* @param {Record} data.record
|
362
415
|
*/
|
363
416
|
onStoreRecordChange(data) {
|
364
417
|
let me = this,
|
File without changes
|
/package/resources/scss/src/examples/{treeSelectionModel → treeAccordion}/MainContainer.scss
RENAMED
File without changes
|