alchemy-form 0.1.4 → 0.1.7
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/CHANGELOG.md +23 -0
- package/assets/stylesheets/form/alchemy_field_array.scss +4 -0
- package/assets/stylesheets/form/alchemy_toggle.scss +2 -0
- package/assets/stylesheets/form/query_builder.scss +185 -0
- package/config/routes.js +8 -0
- package/controller/form_api_controller.js +51 -2
- package/element/20_query_builder_base.js +82 -0
- package/element/25_query_builder_data.js +139 -0
- package/element/alchemy_field.js +19 -2
- package/element/alchemy_select.js +40 -2
- package/element/alchemy_select_item.js +42 -1
- package/element/alchemy_table.js +123 -21
- package/element/query_builder.js +90 -0
- package/element/query_builder_entry.js +388 -0
- package/element/query_builder_group.js +248 -0
- package/element/query_builder_value.js +316 -0
- package/element/query_builder_variable.js +103 -0
- package/helper/form_actions/00_form_action.js +328 -0
- package/helper/form_actions/url_action.js +69 -0
- package/helper/query_builder_variable_definition/00_variable_definition.js +371 -0
- package/helper/query_builder_variable_definition/boolean_variable_definition.js +24 -0
- package/helper/query_builder_variable_definition/list_variable_definition.js +38 -0
- package/helper/query_builder_variable_definition/number_variable_definition.js +106 -0
- package/helper/query_builder_variable_definition/string_variable_definition.js +46 -0
- package/helper_field/query_builder_assignment.js +11 -0
- package/helper_field/query_builder_field.js +91 -0
- package/helper_field/query_builder_value.js +56 -0
- package/helper_field/query_builder_variable.js +56 -0
- package/package.json +1 -1
- package/view/form/elements/alchemy_field_array.hwk +3 -1
- package/view/form/elements/alchemy_field_array_entry.hwk +3 -1
- package/view/form/elements/alchemy_select_item.hwk +6 -1
- package/view/form/elements/query_builder.hwk +1 -0
- package/view/form/elements/query_builder_entry.hwk +33 -0
- package/view/form/elements/query_builder_group.hwk +64 -0
- package/view/form/elements/query_builder_value.hwk +10 -0
- package/view/form/elements/query_builder_variable.hwk +6 -0
- package/view/form/inputs/edit/query_builder.hwk +5 -0
- package/view/form/inputs/edit/query_builder_assignment.hwk +6 -0
- package/view/form/inputs/edit/query_builder_value.hwk +11 -0
- package/view/form/inputs/edit/query_builder_variable.hwk +10 -0
- package/view/form/select/qb_item.hwk +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
## 0.1.7 (2022-06-12)
|
|
2
|
+
|
|
3
|
+
* Fix `<alchemy-table>` code typo
|
|
4
|
+
* Fix QueryBuilderGroup value being set incorrectly
|
|
5
|
+
* Add `<alchemy-query-builder-value>` element
|
|
6
|
+
* Add `<alchemy-query-builder-variable>` element
|
|
7
|
+
* Add List variable definition, which can contain other variables
|
|
8
|
+
|
|
9
|
+
## 0.1.6 (2022-05-31)
|
|
10
|
+
|
|
11
|
+
* Fix `FormApi#related` action searching through multiple fields in an `and` group
|
|
12
|
+
* Use microcopy translations in buttons
|
|
13
|
+
* Add `Action` class for user interaction
|
|
14
|
+
* Add context-menu support to `alchemy-table`
|
|
15
|
+
* Add support for using custom templates for `alchemy-select` options
|
|
16
|
+
* Add QueryBuilder
|
|
17
|
+
|
|
18
|
+
## 0.1.5 (2022-03-21)
|
|
19
|
+
|
|
20
|
+
* Print `alchemy-select-item` contents as text, not html
|
|
21
|
+
* Only get a maximum of 50 related items
|
|
22
|
+
* Set the parent `alchemy-select` element when creating `alchemy-select-item` element
|
|
23
|
+
|
|
1
24
|
## 0.1.4 (2022-03-16)
|
|
2
25
|
|
|
3
26
|
* Make fields work with the new `Alchemy.Map.Backed` and `Alchemy.Map.Enum` class
|
|
@@ -34,6 +34,7 @@ alchemy-toggle {
|
|
|
34
34
|
height: 36px;
|
|
35
35
|
flex: 0 0 134px;
|
|
36
36
|
border-radius: 4px;
|
|
37
|
+
min-width: 134px;
|
|
37
38
|
|
|
38
39
|
transition: background-color 0.3s cubic-bezier(0, 1, 0.5, 1);
|
|
39
40
|
background: #848484;
|
|
@@ -43,6 +44,7 @@ alchemy-toggle {
|
|
|
43
44
|
&:after {
|
|
44
45
|
text-transform: uppercase;
|
|
45
46
|
text-align: center;
|
|
47
|
+
box-sizing: inherit;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
&:before {
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--qb-border-color: #d3d3d3;
|
|
3
|
+
--qb-btn-background-color: #fafafa;
|
|
4
|
+
--qb-text-color: #3e3e3e;
|
|
5
|
+
|
|
6
|
+
--qb-btn-primary: #286090;
|
|
7
|
+
--qb-btn-primary-border: #204d74;
|
|
8
|
+
--qb-btn-primary-text-color: #fafafa;
|
|
9
|
+
|
|
10
|
+
--qb-btn-active: #3da50e;
|
|
11
|
+
--qb-btn-active-text: #fff;
|
|
12
|
+
--qb-btn-border-color: #d3d3d3;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
alchemy-query-builder {
|
|
16
|
+
display: block;
|
|
17
|
+
border-color: var(--qb-border-color);
|
|
18
|
+
padding: 1rem;
|
|
19
|
+
position: relative;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
alchemy-query-builder-group {
|
|
23
|
+
display: block;
|
|
24
|
+
padding: 10px;
|
|
25
|
+
padding-bottom: 6px;
|
|
26
|
+
background-color: rgba(250,240,210,.5);
|
|
27
|
+
border: 1px solid #dcc896;
|
|
28
|
+
position: relative;
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
margin: 4px 0;
|
|
32
|
+
padding: 5px;
|
|
33
|
+
border: 1px solid #eee;
|
|
34
|
+
border-radius: 3px;
|
|
35
|
+
|
|
36
|
+
.qb-group-header {
|
|
37
|
+
margin-bottom: 10px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.qb-group-actions {
|
|
41
|
+
float: right;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.qb-group-body {
|
|
45
|
+
.qb-rules-list {
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-flow: column;
|
|
48
|
+
gap: 1rem;
|
|
49
|
+
padding: 0 0 0 15px;
|
|
50
|
+
|
|
51
|
+
& > :first-child::before {
|
|
52
|
+
top: -11px;
|
|
53
|
+
height: calc(50% + 14px);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
& > :last-child::before {
|
|
57
|
+
border-radius: 0 0 0 4px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
& > ::after {
|
|
61
|
+
top: 50%;
|
|
62
|
+
border-width: 0 0 0 2px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
& >:last-child::after {
|
|
66
|
+
display: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
> ::before {
|
|
70
|
+
top: -2px;
|
|
71
|
+
border-width: 0 0 2px 2px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
> ::before,
|
|
75
|
+
> ::after {
|
|
76
|
+
content: '';
|
|
77
|
+
position: absolute;
|
|
78
|
+
left: -10px;
|
|
79
|
+
width: 10px;
|
|
80
|
+
height: calc(50% + 4px);
|
|
81
|
+
border-color: #ccc;
|
|
82
|
+
border-style: solid;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
alchemy-query-builder-value {
|
|
89
|
+
min-width: 10rem;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
alchemy-query-builder-entry {
|
|
93
|
+
min-width: 40rem;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
alchemy-query-builder-value,
|
|
97
|
+
alchemy-query-builder-entry {
|
|
98
|
+
display: flex;
|
|
99
|
+
gap: 0.7rem;
|
|
100
|
+
|
|
101
|
+
alchemy-select {
|
|
102
|
+
min-width: 11rem;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.qb-delete-wrapper {
|
|
106
|
+
flex: 1;
|
|
107
|
+
text-align: right;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.qb-value-wrapper {
|
|
111
|
+
display: flex;
|
|
112
|
+
gap: 0.3rem;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.qb-value-input {
|
|
116
|
+
height: 100%;
|
|
117
|
+
color: black;
|
|
118
|
+
padding: 0 0.5rem;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.qb-group-invert,
|
|
123
|
+
.qb-button-group,
|
|
124
|
+
.qb-group-type {
|
|
125
|
+
display: inline-flex;
|
|
126
|
+
box-shadow: 0 1px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12);
|
|
127
|
+
user-select: none;
|
|
128
|
+
|
|
129
|
+
> input {
|
|
130
|
+
height: 1px;
|
|
131
|
+
width: 1px;
|
|
132
|
+
opacity: 0;
|
|
133
|
+
position: absolute;
|
|
134
|
+
margin: 0 0 0 -1px;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
> input + label {
|
|
138
|
+
opacity: 0.7;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
> input:checked + label {
|
|
142
|
+
background-color: var(--qb-btn-active);
|
|
143
|
+
border-color: var(--qb-btn-active);
|
|
144
|
+
color: var(--qb-btn-active-text);
|
|
145
|
+
opacity: 1;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.qb-primary {
|
|
150
|
+
--qb-btn-background-color: var(--qb-btn-primary);
|
|
151
|
+
--qb-text-color: var(--qb-btn-primary-text-color);
|
|
152
|
+
--qb-btn-border-color: var(--qb-btn-primary-border);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
button.qb-btn {
|
|
156
|
+
border-color: var(--qb-btn-border-color);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.qb-btn {
|
|
160
|
+
background-color: var(--qb-btn-background-color);
|
|
161
|
+
color: var(--qb-text-color);
|
|
162
|
+
transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
163
|
+
border-radius: 2px;
|
|
164
|
+
cursor: pointer;
|
|
165
|
+
display: inline-block;
|
|
166
|
+
font-weight: bold;
|
|
167
|
+
text-align: center;
|
|
168
|
+
padding: 2px 12px 1px;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.qb-select-item {
|
|
172
|
+
display: flex;
|
|
173
|
+
flex-flow: column;
|
|
174
|
+
padding-right: 1rem;
|
|
175
|
+
|
|
176
|
+
.option-title {
|
|
177
|
+
font-weight: bold;
|
|
178
|
+
font-size: 1rem;
|
|
179
|
+
white-space: nowrap;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.option-description {
|
|
183
|
+
min-width: 10rem;
|
|
184
|
+
}
|
|
185
|
+
}
|
package/config/routes.js
CHANGED
|
@@ -2,4 +2,12 @@ Router.add({
|
|
|
2
2
|
name : 'FormApi#related',
|
|
3
3
|
methods : 'post',
|
|
4
4
|
paths : '/api/form/data/related',
|
|
5
|
+
policy : 'logged_in',
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
Router.add({
|
|
9
|
+
name : 'FormApi#queryBuilderData',
|
|
10
|
+
methods : 'post',
|
|
11
|
+
paths : '/api/form/data/qbdata',
|
|
12
|
+
policy : 'logged_in',
|
|
5
13
|
});
|
|
@@ -17,7 +17,7 @@ const FormApi = Function.inherits('Alchemy.Controller', 'FormApi');
|
|
|
17
17
|
*
|
|
18
18
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
19
19
|
* @since 0.1.0
|
|
20
|
-
* @version 0.1.
|
|
20
|
+
* @version 0.1.6
|
|
21
21
|
*
|
|
22
22
|
* @param {Conduit} conduit
|
|
23
23
|
*/
|
|
@@ -26,8 +26,26 @@ FormApi.setAction(async function related(conduit) {
|
|
|
26
26
|
const body = conduit.body;
|
|
27
27
|
|
|
28
28
|
const model = this.getModel(body.assoc_model);
|
|
29
|
+
let crit = model.find();
|
|
30
|
+
crit.limit(50);
|
|
31
|
+
crit.setOption('scenario', 'related_data');
|
|
32
|
+
|
|
33
|
+
if (body.config && body.config.search) {
|
|
34
|
+
let display_fields = Array.cast(model.displayField);
|
|
35
|
+
|
|
36
|
+
let or = crit.or();
|
|
37
|
+
let rx = RegExp.interpretWildcard('*' + body.config.search + '*', 'i');
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
for (let field of display_fields) {
|
|
40
|
+
if (!field) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
or.where(field).equals(rx);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let records = await model.find('all', crit);
|
|
31
49
|
|
|
32
50
|
let result = {
|
|
33
51
|
available : records.available,
|
|
@@ -36,3 +54,34 @@ FormApi.setAction(async function related(conduit) {
|
|
|
36
54
|
|
|
37
55
|
conduit.end(result);
|
|
38
56
|
});
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The related action
|
|
61
|
+
*
|
|
62
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
63
|
+
* @since 0.1.6
|
|
64
|
+
* @version 0.1.6
|
|
65
|
+
*
|
|
66
|
+
* @param {Conduit} conduit
|
|
67
|
+
*/
|
|
68
|
+
FormApi.setAction(async function queryBuilderData(conduit) {
|
|
69
|
+
|
|
70
|
+
const body = conduit.body;
|
|
71
|
+
const config = body.config || {};
|
|
72
|
+
let result;
|
|
73
|
+
|
|
74
|
+
if (body && body.model) {
|
|
75
|
+
const model = this.getModel(body.model);
|
|
76
|
+
|
|
77
|
+
if (body.$pk) {
|
|
78
|
+
const doc = await model.findByPk(body.$pk);
|
|
79
|
+
|
|
80
|
+
if (doc) {
|
|
81
|
+
result = await doc.loadQueryBuilderData(config);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
conduit.end(result);
|
|
87
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The base abstract query builder custom element
|
|
3
|
+
*
|
|
4
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
5
|
+
* @since 0.1.6
|
|
6
|
+
* @version 0.1.6
|
|
7
|
+
*/
|
|
8
|
+
const QueryBuilderBase = Function.inherits('Alchemy.Element.Form.Base', 'QueryBuilderBase');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Don't register this as a custom element,
|
|
12
|
+
* but don't let child classes inherit this
|
|
13
|
+
*
|
|
14
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
15
|
+
* @since 0.1.6
|
|
16
|
+
* @version 0.1.6
|
|
17
|
+
*/
|
|
18
|
+
QueryBuilderBase.setStatic('is_abstract_class', true, false);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The stylesheet to load for this element
|
|
22
|
+
*
|
|
23
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
24
|
+
* @since 0.1.6
|
|
25
|
+
* @version 0.1.6
|
|
26
|
+
*/
|
|
27
|
+
QueryBuilderBase.setStylesheetFile('form/query_builder');
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get the dataprovider
|
|
31
|
+
*
|
|
32
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
33
|
+
* @since 0.1.6
|
|
34
|
+
* @version 0.1.6
|
|
35
|
+
*/
|
|
36
|
+
QueryBuilderBase.enforceProperty(function dataprovider(new_value) {
|
|
37
|
+
|
|
38
|
+
if (new_value == null) {
|
|
39
|
+
if (this.assigned_data.dataprovider) {
|
|
40
|
+
new_value = this.assigned_data.dataprovider;
|
|
41
|
+
} else if (this.root_query_builder && this.root_query_builder.dataprovider) {
|
|
42
|
+
new_value = this.root_query_builder.dataprovider;
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
this.assigned_data.dataprovider = new_value;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return new_value;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Getter for the rules list element
|
|
53
|
+
*
|
|
54
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
55
|
+
* @since 0.1.6
|
|
56
|
+
* @version 0.1.6
|
|
57
|
+
*/
|
|
58
|
+
QueryBuilderBase.setProperty(function root_query_builder() {
|
|
59
|
+
return this.queryParents('alchemy-query-builder');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get the value type of the given input
|
|
64
|
+
*
|
|
65
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
66
|
+
* @since 0.1.6
|
|
67
|
+
* @version 0.1.6
|
|
68
|
+
*
|
|
69
|
+
* @param {HTMLElement}
|
|
70
|
+
*
|
|
71
|
+
* @return {String}
|
|
72
|
+
*/
|
|
73
|
+
QueryBuilderBase.setMethod(function getValueType(element) {
|
|
74
|
+
|
|
75
|
+
if (!element) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let result = element.value_type || element.type;
|
|
80
|
+
|
|
81
|
+
return result;
|
|
82
|
+
});
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The base abstract query builder custom element
|
|
3
|
+
*
|
|
4
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
5
|
+
* @since 0.1.7
|
|
6
|
+
* @version 0.1.7
|
|
7
|
+
*/
|
|
8
|
+
const QueryBuilderData = Function.inherits('Alchemy.Element.Form.QueryBuilderBase', 'QueryBuilderData');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Don't register this as a custom element,
|
|
12
|
+
* but don't let child classes inherit this
|
|
13
|
+
*
|
|
14
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
15
|
+
* @since 0.1.7
|
|
16
|
+
* @version 0.1.7
|
|
17
|
+
*/
|
|
18
|
+
QueryBuilderData.setStatic('is_abstract_class', true, false);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Check a filter
|
|
22
|
+
*
|
|
23
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
24
|
+
* @since 0.1.6
|
|
25
|
+
* @version 0.1.7
|
|
26
|
+
*/
|
|
27
|
+
QueryBuilderData.setMethod(function checkFilterType(filter_type, entry) {
|
|
28
|
+
|
|
29
|
+
if (!entry) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let whitelist = this[filter_type];
|
|
34
|
+
|
|
35
|
+
if (!whitelist) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let type = entry.type_name || entry.type || entry.id || entry.name;
|
|
40
|
+
|
|
41
|
+
if (!type) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let entries = whitelist.split(',');
|
|
46
|
+
|
|
47
|
+
return entries.indexOf(type) > -1;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Load data for a specific element
|
|
52
|
+
*
|
|
53
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
54
|
+
* @since 0.1.6
|
|
55
|
+
* @version 0.1.6
|
|
56
|
+
*/
|
|
57
|
+
QueryBuilderData.setMethod(async function loadData(config, element) {
|
|
58
|
+
|
|
59
|
+
if (!element) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!config) {
|
|
64
|
+
config = {};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let filter_type,
|
|
68
|
+
result = [],
|
|
69
|
+
items;
|
|
70
|
+
|
|
71
|
+
if (element.classList.contains('qb-source-type')) {
|
|
72
|
+
items = await this.loadSourceTypeData(config);
|
|
73
|
+
filter_type = 'source-types';
|
|
74
|
+
} else if (element.classList.contains('qb-value-variable') || element.classList.contains('qb-variable')) {
|
|
75
|
+
items = await this.loadVariableData(config);
|
|
76
|
+
filter_type = 'variable-types';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (items && items.length) {
|
|
80
|
+
|
|
81
|
+
let entry;
|
|
82
|
+
|
|
83
|
+
for (entry of items) {
|
|
84
|
+
if (!entry) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (filter_type && !this.checkFilterType(filter_type, entry)) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
result.push(entry);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
items: result,
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Load variable data
|
|
103
|
+
*
|
|
104
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
105
|
+
* @since 0.1.6
|
|
106
|
+
* @version 0.1.7
|
|
107
|
+
*/
|
|
108
|
+
QueryBuilderData.setMethod(async function loadVariableData(config) {
|
|
109
|
+
|
|
110
|
+
let dataprovider = this.dataprovider;
|
|
111
|
+
|
|
112
|
+
if (!config) {
|
|
113
|
+
config = {};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
config.source_type = 'variable';
|
|
117
|
+
|
|
118
|
+
let variables = [];
|
|
119
|
+
|
|
120
|
+
if (dataprovider) {
|
|
121
|
+
variables = await dataprovider.loadData(config, this);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let result = [];
|
|
125
|
+
|
|
126
|
+
if (variables && variables.length) {
|
|
127
|
+
let entry;
|
|
128
|
+
|
|
129
|
+
for (entry of variables) {
|
|
130
|
+
if (entry) {
|
|
131
|
+
result.push(entry);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
console.log('Got loadvariable data:', result);
|
|
137
|
+
|
|
138
|
+
return result;
|
|
139
|
+
});
|
package/element/alchemy_field.js
CHANGED
|
@@ -708,16 +708,33 @@ Field.setMethod(function retained() {
|
|
|
708
708
|
*
|
|
709
709
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
710
710
|
* @since 0.1.0
|
|
711
|
-
* @version 0.1.
|
|
711
|
+
* @version 0.1.6
|
|
712
712
|
*
|
|
713
713
|
* @param {Object} config
|
|
714
714
|
* @param {HTMLElement} element
|
|
715
715
|
*/
|
|
716
|
-
Field.setMethod(function loadData(config, element) {
|
|
716
|
+
Field.setMethod(async function loadData(config, element) {
|
|
717
717
|
|
|
718
718
|
let field = this.config;
|
|
719
719
|
|
|
720
720
|
if (field) {
|
|
721
|
+
|
|
722
|
+
let result;
|
|
723
|
+
|
|
724
|
+
if (typeof field.loadData == 'function') {
|
|
725
|
+
|
|
726
|
+
try {
|
|
727
|
+
result = await field.loadData(config, element);
|
|
728
|
+
} catch (err) {
|
|
729
|
+
// Ignore
|
|
730
|
+
console.error('Error loading field data:', err);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
if (result) {
|
|
734
|
+
return result;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
721
738
|
return this.hawkejs_helpers.Alchemy.getResource({
|
|
722
739
|
name : 'FormApi#related',
|
|
723
740
|
post : true,
|
|
@@ -36,6 +36,26 @@ AlchemySelect.setProperty('_clear_count', 0);
|
|
|
36
36
|
*/
|
|
37
37
|
AlchemySelect.setAttribute('total-item-count', {number: true});
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* The optional template to use for value items
|
|
41
|
+
* (The chosen value)
|
|
42
|
+
*
|
|
43
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
44
|
+
* @since 0.1.6
|
|
45
|
+
* @version 0.1.6
|
|
46
|
+
*/
|
|
47
|
+
AlchemySelect.setAttribute('value-item-template');
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The optional template to use for option items
|
|
51
|
+
* (The items visible in the dropdown)
|
|
52
|
+
*
|
|
53
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
54
|
+
* @since 0.1.6
|
|
55
|
+
* @version 0.1.6
|
|
56
|
+
*/
|
|
57
|
+
AlchemySelect.setAttribute('option-item-template');
|
|
58
|
+
|
|
39
59
|
/**
|
|
40
60
|
* The hawkejs template to use
|
|
41
61
|
*
|
|
@@ -809,12 +829,16 @@ AlchemySelect.setMethod(function _processPreloadedValues() {
|
|
|
809
829
|
*
|
|
810
830
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
811
831
|
* @since 0.1.0
|
|
812
|
-
* @version 0.1.
|
|
832
|
+
* @version 0.1.6
|
|
813
833
|
*
|
|
814
834
|
* @param {Object} response
|
|
815
835
|
*/
|
|
816
836
|
AlchemySelect.setMethod(function _processResponseData(response) {
|
|
817
837
|
|
|
838
|
+
if (!response) {
|
|
839
|
+
response = {};
|
|
840
|
+
}
|
|
841
|
+
|
|
818
842
|
if (response.available) {
|
|
819
843
|
this.total_item_count = response.available;
|
|
820
844
|
}
|
|
@@ -823,6 +847,10 @@ AlchemySelect.setMethod(function _processResponseData(response) {
|
|
|
823
847
|
record,
|
|
824
848
|
item;
|
|
825
849
|
|
|
850
|
+
if (!records) {
|
|
851
|
+
records = [];
|
|
852
|
+
}
|
|
853
|
+
|
|
826
854
|
for (record of records) {
|
|
827
855
|
item = this._makeOption(record._id || record.id, record);
|
|
828
856
|
this.addToDropdown(item);
|
|
@@ -1166,7 +1194,7 @@ AlchemySelect.setMethod(function close(event) {
|
|
|
1166
1194
|
*
|
|
1167
1195
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
1168
1196
|
* @since 0.1.0
|
|
1169
|
-
* @version 0.1.
|
|
1197
|
+
* @version 0.1.6
|
|
1170
1198
|
*
|
|
1171
1199
|
* @param {String} type "value" or "option"
|
|
1172
1200
|
* @param {Mixed} value The actual value of this item
|
|
@@ -1181,9 +1209,19 @@ AlchemySelect.setMethod(function _makeValueItem(type, value, data) {
|
|
|
1181
1209
|
// Set the type ("value" or "option")
|
|
1182
1210
|
item.type = type;
|
|
1183
1211
|
|
|
1212
|
+
// Set the custom template to use, if any
|
|
1213
|
+
let custom_template = this[type + '-item-template'];
|
|
1214
|
+
|
|
1215
|
+
if (custom_template) {
|
|
1216
|
+
item.custom_template = custom_template;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1184
1219
|
// Assign the value
|
|
1185
1220
|
item.value = value;
|
|
1186
1221
|
|
|
1222
|
+
// Add a reference to this element
|
|
1223
|
+
item.alchemy_select = this;
|
|
1224
|
+
|
|
1187
1225
|
if (!data) {
|
|
1188
1226
|
data = this.getValueData(value);
|
|
1189
1227
|
}
|
|
@@ -37,6 +37,15 @@ Item.setAttribute('type');
|
|
|
37
37
|
*/
|
|
38
38
|
Item.setAttribute('selected', {boolean: true});
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Should a custom template be used?
|
|
42
|
+
*
|
|
43
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
44
|
+
* @since 0.1.6
|
|
45
|
+
* @version 0.1.6
|
|
46
|
+
*/
|
|
47
|
+
Item.setAttribute('custom-template');
|
|
48
|
+
|
|
40
49
|
/**
|
|
41
50
|
* The value of this item
|
|
42
51
|
*
|
|
@@ -53,4 +62,36 @@ Item.setAssignedProperty('value');
|
|
|
53
62
|
* @since 0.1.0
|
|
54
63
|
* @version 0.1.0
|
|
55
64
|
*/
|
|
56
|
-
Item.setAssignedProperty('data');
|
|
65
|
+
Item.setAssignedProperty('data');
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The parent alchemy-select item
|
|
69
|
+
*
|
|
70
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
71
|
+
* @since 0.1.5
|
|
72
|
+
* @version 0.1.5
|
|
73
|
+
*/
|
|
74
|
+
Item.enforceProperty(function alchemy_select(new_value) {
|
|
75
|
+
|
|
76
|
+
if (new_value == null) {
|
|
77
|
+
new_value = this.closest('alchemy-select');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return new_value;
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The display item
|
|
85
|
+
*
|
|
86
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
87
|
+
* @since 0.1.5
|
|
88
|
+
* @version 0.1.5
|
|
89
|
+
*/
|
|
90
|
+
Item.setProperty(function display_title() {
|
|
91
|
+
|
|
92
|
+
if (!this.data) {
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return this.data.title || this.data.name || this.data.username || this.data.$pk || this.value;
|
|
97
|
+
});
|