alchemy-form 0.1.5 → 0.1.6
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 +9 -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 +34 -2
- package/element/20_query_builder_base.js +82 -0
- package/element/alchemy_field.js +19 -2
- package/element/alchemy_select.js +37 -2
- package/element/alchemy_select_item.js +9 -0
- 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 +221 -0
- package/element/query_builder_value.js +435 -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 +351 -0
- package/helper/query_builder_variable_definition/boolean_variable_definition.js +24 -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/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/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/select/qb_item.hwk +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## 0.1.6 (2022-05-31)
|
|
2
|
+
|
|
3
|
+
* Fix `FormApi#related` action searching through multiple fields in an `and` group
|
|
4
|
+
* Use microcopy translations in buttons
|
|
5
|
+
* Add `Action` class for user interaction
|
|
6
|
+
* Add context-menu support to `alchemy-table`
|
|
7
|
+
* Add support for using custom templates for `alchemy-select` options
|
|
8
|
+
* Add QueryBuilder
|
|
9
|
+
|
|
1
10
|
## 0.1.5 (2022-03-21)
|
|
2
11
|
|
|
3
12
|
* Print `alchemy-select-item` contents as text, not html
|
|
@@ -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
|
*/
|
|
@@ -28,6 +28,7 @@ FormApi.setAction(async function related(conduit) {
|
|
|
28
28
|
const model = this.getModel(body.assoc_model);
|
|
29
29
|
let crit = model.find();
|
|
30
30
|
crit.limit(50);
|
|
31
|
+
crit.setOption('scenario', 'related_data');
|
|
31
32
|
|
|
32
33
|
if (body.config && body.config.search) {
|
|
33
34
|
let display_fields = Array.cast(model.displayField);
|
|
@@ -40,7 +41,7 @@ FormApi.setAction(async function related(conduit) {
|
|
|
40
41
|
continue;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
or.where(field).equals(rx);
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
|
|
@@ -53,3 +54,34 @@ FormApi.setAction(async function related(conduit) {
|
|
|
53
54
|
|
|
54
55
|
conduit.end(result);
|
|
55
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
|
+
});
|
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,6 +1209,13 @@ 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
|
|
|
@@ -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
|
*
|
package/element/alchemy_table.js
CHANGED
|
@@ -513,7 +513,7 @@ Table.setMethod(function getCurrentStateUrl() {
|
|
|
513
513
|
*
|
|
514
514
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
515
515
|
* @since 0.1.0
|
|
516
|
-
* @version 0.1.
|
|
516
|
+
* @version 0.1.6
|
|
517
517
|
*
|
|
518
518
|
* @param {Array} records
|
|
519
519
|
*/
|
|
@@ -530,6 +530,7 @@ Table.setMethod(function setRecords(records) {
|
|
|
530
530
|
}
|
|
531
531
|
|
|
532
532
|
this.showPagination();
|
|
533
|
+
this.attachContextMenus();
|
|
533
534
|
});
|
|
534
535
|
|
|
535
536
|
/**
|
|
@@ -593,7 +594,7 @@ Table.setMethod(function showPagination() {
|
|
|
593
594
|
*
|
|
594
595
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
595
596
|
* @since 0.1.0
|
|
596
|
-
* @version 0.1.
|
|
597
|
+
* @version 0.1.6
|
|
597
598
|
*
|
|
598
599
|
* @param {Object} entry
|
|
599
600
|
*
|
|
@@ -604,7 +605,10 @@ Table.setMethod(function createDataRow(entry) {
|
|
|
604
605
|
let field,
|
|
605
606
|
value,
|
|
606
607
|
tr = this.createElement('tr'),
|
|
607
|
-
td
|
|
608
|
+
td,
|
|
609
|
+
id = entry.$pk || entry._id || entry.id;
|
|
610
|
+
|
|
611
|
+
tr.dataset.pk = id;
|
|
608
612
|
|
|
609
613
|
for (field of this.fieldset) {
|
|
610
614
|
td = this.createElement('td');
|
|
@@ -623,31 +627,22 @@ Table.setMethod(function createDataRow(entry) {
|
|
|
623
627
|
td.classList.add('aft-actions');
|
|
624
628
|
tr.append(td);
|
|
625
629
|
|
|
626
|
-
let actions;
|
|
627
|
-
|
|
628
|
-
if (entry.$hold && entry.$hold.actions) {
|
|
629
|
-
actions = entry.$hold.actions;
|
|
630
|
-
} else {
|
|
631
|
-
actions = entry.$actions;
|
|
632
|
-
}
|
|
630
|
+
let actions = this.getEntryActions(entry, 'row');
|
|
633
631
|
|
|
634
632
|
if (actions && actions.length) {
|
|
633
|
+
|
|
635
634
|
let action,
|
|
636
635
|
anchor;
|
|
637
636
|
|
|
637
|
+
// Iterate over all the defined actions
|
|
638
638
|
for (action of actions) {
|
|
639
|
-
|
|
640
|
-
anchor
|
|
641
|
-
|
|
642
|
-
if (
|
|
643
|
-
|
|
644
|
-
alico.setAttribute('type', action.icon);
|
|
645
|
-
anchor.append(alico);
|
|
646
|
-
} else {
|
|
647
|
-
anchor.textContent = action.title || action.name;
|
|
639
|
+
|
|
640
|
+
anchor = action.constructElement(this);
|
|
641
|
+
|
|
642
|
+
if (!anchor) {
|
|
643
|
+
continue;
|
|
648
644
|
}
|
|
649
645
|
|
|
650
|
-
anchor.setAttribute('href', action.url);
|
|
651
646
|
td.append(anchor);
|
|
652
647
|
}
|
|
653
648
|
}
|
|
@@ -658,6 +653,111 @@ Table.setMethod(function createDataRow(entry) {
|
|
|
658
653
|
return tr;
|
|
659
654
|
});
|
|
660
655
|
|
|
656
|
+
/**
|
|
657
|
+
* Get a list of actions
|
|
658
|
+
*
|
|
659
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
660
|
+
* @since 0.1.6
|
|
661
|
+
* @version 0.1.6
|
|
662
|
+
*
|
|
663
|
+
* @param {Object} record
|
|
664
|
+
* @param {Stirng} filter
|
|
665
|
+
*
|
|
666
|
+
* @return {Alchemy.Form.Action.Action[]}
|
|
667
|
+
*/
|
|
668
|
+
Table.setMethod(function getEntryActions(record, filter) {
|
|
669
|
+
|
|
670
|
+
let result = [];
|
|
671
|
+
|
|
672
|
+
if (!record) {
|
|
673
|
+
return result;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
let actions;
|
|
677
|
+
|
|
678
|
+
if (record.$hold && record.$hold.actions) {
|
|
679
|
+
actions = record.$hold.actions;
|
|
680
|
+
} else {
|
|
681
|
+
actions = record.$actions;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
if(!actions || !actions.length) {
|
|
685
|
+
return result;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
for (let action of actions) {
|
|
689
|
+
|
|
690
|
+
if (!action.type) {
|
|
691
|
+
action.type = 'url';
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// Make sure it's an action instance
|
|
695
|
+
action = Classes.Alchemy.Form.Action.Action.cast(action);
|
|
696
|
+
|
|
697
|
+
if (!action || (filter && !action.isAllowedIn(filter))) {
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
result.push(action);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
return result;
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* Add context menus to rows
|
|
709
|
+
*
|
|
710
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
711
|
+
* @since 0.1.6
|
|
712
|
+
* @version 0.1.6
|
|
713
|
+
*
|
|
714
|
+
* @param {Object} entry
|
|
715
|
+
*/
|
|
716
|
+
Table.setMethod(function attachContextMenus() {
|
|
717
|
+
|
|
718
|
+
if (!Blast.isBrowser) {
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
if (!this.assigned_data.records || !this.assigned_data.records.length) {
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
for (let record of this.assigned_data.records) {
|
|
727
|
+
|
|
728
|
+
let context_actions = this.getEntryActions(record, 'context');
|
|
729
|
+
|
|
730
|
+
if (!context_actions || !context_actions.length) {
|
|
731
|
+
contintue;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
let pk = record.$pk || record._id || record.id;
|
|
735
|
+
|
|
736
|
+
if (!pk) {
|
|
737
|
+
continue;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
let tr = this.querySelector('[data-pk="' + pk + '"]');
|
|
741
|
+
|
|
742
|
+
if (!tr) {
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
tr.addEventListener('contextmenu', e => {
|
|
747
|
+
|
|
748
|
+
this.selectRow(tr);
|
|
749
|
+
|
|
750
|
+
let menu = this.createElement('he-context-menu');
|
|
751
|
+
|
|
752
|
+
for (let action of context_actions) {
|
|
753
|
+
action.addToContextMenu(menu);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
menu.show(e);
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
|
|
661
761
|
/**
|
|
662
762
|
* On new fieldset
|
|
663
763
|
*
|
|
@@ -931,12 +1031,14 @@ Table.setMethod(function sortData() {
|
|
|
931
1031
|
*
|
|
932
1032
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
933
1033
|
* @since 0.1.0
|
|
934
|
-
* @version 0.1.
|
|
1034
|
+
* @version 0.1.6
|
|
935
1035
|
*/
|
|
936
1036
|
Table.setMethod(function introduced() {
|
|
937
1037
|
|
|
938
1038
|
const that = this;
|
|
939
1039
|
|
|
1040
|
+
this.attachContextMenus();
|
|
1041
|
+
|
|
940
1042
|
this.addEventListener('click', function onClick(e) {
|
|
941
1043
|
|
|
942
1044
|
let target = e.target,
|