alchemy-form 0.2.9 → 0.3.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/assets/stylesheets/form/elements/_code_input.scss +0 -1
- package/assets/stylesheets/form/elements/_field.scss +15 -0
- package/assets/stylesheets/form/elements/_settings_editor.scss +62 -0
- package/assets/stylesheets/form/elements/_table.scss +0 -1
- package/assets/stylesheets/form/elements/_virtual_scroll.scss +19 -0
- package/assets/stylesheets/form/elements/index.scss +3 -1
- package/config/routes.js +3 -3
- package/controller/form_api_controller.js +2 -4
- package/element/00_form_base.js +21 -0
- package/element/al_code_input.js +51 -13
- package/element/al_field.js +25 -24
- package/element/al_form.js +12 -4
- package/element/al_select.js +2 -1
- package/element/al_settings_editor.js +367 -0
- package/element/al_table.js +13 -7
- package/element/al_virtual_scroll.js +873 -0
- package/package.json +3 -3
- package/view/form/elements/al_settings_editor.hwk +36 -0
- package/view/form/inputs/edit/object.hwk +9 -0
- package/view/form/inputs/edit/settings.hwk +5 -0
- package/view/form/inputs/view/string.hwk +14 -1
- package/view/form/wrappers/default/default.hwk +18 -2
- /package/element/{al_string_input.js → 50-al_string_input.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
## 0.3.0-alpha.1 (2024-02-15)
|
|
2
|
+
|
|
3
|
+
* Upgrade to Alchemy v1.4.0
|
|
4
|
+
* Add edit template for the `Object` field type
|
|
5
|
+
* Add settings editor element
|
|
6
|
+
* Make `readonly` attribute work on `al-field` and `al-form` elements
|
|
7
|
+
* Use "alchemy-field-title" and "alchemy-field-description" microcopy in `al-field` labels
|
|
8
|
+
|
|
9
|
+
## 0.2.10 (2024-01-15)
|
|
10
|
+
|
|
11
|
+
* Fix `al-table` throwing an error when receiving null data
|
|
12
|
+
* Add `al-virtual-scroll` element
|
|
13
|
+
* Make field `constraints` work by using the `Document` instance instead of plain data object
|
|
14
|
+
* Clear old errors when validating a form
|
|
15
|
+
|
|
1
16
|
## 0.2.9 (2023-11-27)
|
|
2
17
|
|
|
3
18
|
* Add support for new local Date/Time fields & Decimal fields
|
|
@@ -33,4 +33,19 @@ al-field {
|
|
|
33
33
|
display: inline-flex;
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
+
|
|
37
|
+
.alchemy-field-empty-value {
|
|
38
|
+
color: #666;
|
|
39
|
+
font-style: italic;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
al-form[readonly] al-field,
|
|
44
|
+
al-field[readonly] {
|
|
45
|
+
pointer-events: none;
|
|
46
|
+
|
|
47
|
+
.alchemy-field-value {
|
|
48
|
+
opacity: 0.8;
|
|
49
|
+
filter: brightness(0.95);
|
|
50
|
+
}
|
|
36
51
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
al-settings-editor {
|
|
2
|
+
display: grid;
|
|
3
|
+
grid-template-columns: minmax(200px, 1.5fr) minmax(25vw, 9fr);
|
|
4
|
+
|
|
5
|
+
.al-settings-group {
|
|
6
|
+
padding-top: 0.5rem;
|
|
7
|
+
margin-bottom: 0.5rem;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.al-settings-setting-header {
|
|
11
|
+
margin-bottom: 0.5rem;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.al-settings-group-title {
|
|
15
|
+
font-weight: bold;
|
|
16
|
+
font-size: 1.6rem;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.al-settings-group-header {
|
|
20
|
+
padding: 0.2rem 1rem 0.5rem;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.al-settings-actions,
|
|
24
|
+
.al-settings-setting {
|
|
25
|
+
padding: 0.2rem 1rem 1.5rem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.al-settings-actions {
|
|
29
|
+
margin-top: 2rem;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.al-settings-setting-title {
|
|
33
|
+
font-weight: bold;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.al-settings-setting-description micro-copy:not(:empty) {
|
|
37
|
+
display: block;
|
|
38
|
+
margin-top: 0.3rem;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.al-settings-sidebar {
|
|
42
|
+
border-right: 1px solid #ebebeb;
|
|
43
|
+
margin-right: 1.5rem;
|
|
44
|
+
|
|
45
|
+
a {
|
|
46
|
+
text-decoration: none;
|
|
47
|
+
color: inherit;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
al-field {
|
|
52
|
+
.field,
|
|
53
|
+
.field input {
|
|
54
|
+
width: 100%;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
al-toc {
|
|
59
|
+
position: sticky;
|
|
60
|
+
top: 1rem;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
al-virtual-scroll {
|
|
2
|
+
display: block;
|
|
3
|
+
min-height: 20rem;
|
|
4
|
+
min-width: 2rem;
|
|
5
|
+
overflow: auto;
|
|
6
|
+
border: 1px solid red;
|
|
7
|
+
|
|
8
|
+
.top-trigger,
|
|
9
|
+
.bottom-trigger {
|
|
10
|
+
width: 1px;
|
|
11
|
+
height: 1px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
[data-loaded-entry-index] {
|
|
15
|
+
border: 1px solid orange;
|
|
16
|
+
min-height: 2rem;
|
|
17
|
+
padding: 1rem;
|
|
18
|
+
}
|
|
19
|
+
}
|
package/config/routes.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
Plugin.addRoute({
|
|
2
2
|
name : 'FormApi#related',
|
|
3
3
|
methods : 'post',
|
|
4
4
|
paths : '/api/form/data/related',
|
|
@@ -7,7 +7,7 @@ Router.add({
|
|
|
7
7
|
is_system_route : true,
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Plugin.addRoute({
|
|
11
11
|
name : 'FormApi#queryBuilderData',
|
|
12
12
|
methods : 'post',
|
|
13
13
|
paths : '/api/form/data/qbdata',
|
|
@@ -16,7 +16,7 @@ Router.add({
|
|
|
16
16
|
is_system_route : true,
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Plugin.addRoute({
|
|
20
20
|
name : 'FormApi#recompute',
|
|
21
21
|
methods : 'post',
|
|
22
22
|
paths : '/api/form/data/recompute/{model_name}/{field}',
|
|
@@ -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.
|
|
20
|
+
* @version 0.3.0
|
|
21
21
|
*
|
|
22
22
|
* @param {Conduit} conduit
|
|
23
23
|
*/
|
|
@@ -32,9 +32,7 @@ FormApi.setAction(async function related(conduit) {
|
|
|
32
32
|
crit.setOption('scenario', 'related_data');
|
|
33
33
|
|
|
34
34
|
if (body.constraints) {
|
|
35
|
-
|
|
36
|
-
crit.where(key).equals(body.constraints[key]);
|
|
37
|
-
}
|
|
35
|
+
crit.applyConditions(body.constraints);
|
|
38
36
|
}
|
|
39
37
|
|
|
40
38
|
if (config.value) {
|
package/element/00_form_base.js
CHANGED
|
@@ -102,6 +102,27 @@ Base.setAttribute('purpose', function getPurpose(value) {
|
|
|
102
102
|
*/
|
|
103
103
|
Base.setAttribute('mode');
|
|
104
104
|
|
|
105
|
+
/**
|
|
106
|
+
* The zone determines where the form/field is being used.
|
|
107
|
+
* For example: admin, frontend, chimera, invoice, ...
|
|
108
|
+
*
|
|
109
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
110
|
+
* @since 0.3.0
|
|
111
|
+
* @version 0.3.0
|
|
112
|
+
*/
|
|
113
|
+
Base.setAttribute('zone', function getZone(value) {
|
|
114
|
+
|
|
115
|
+
if (value) {
|
|
116
|
+
return value;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (!value && this.alchemy_form) {
|
|
120
|
+
value = this.alchemy_form.zone;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return value;
|
|
124
|
+
});
|
|
125
|
+
|
|
105
126
|
/**
|
|
106
127
|
* The view-type determines which type of wrapper/field to use,
|
|
107
128
|
* e.g.: view, list, edit, ...
|
package/element/al_code_input.js
CHANGED
|
@@ -43,6 +43,15 @@ CodeInput.setAttribute('language-mode');
|
|
|
43
43
|
*/
|
|
44
44
|
CodeInput.setAttribute('color-theme');
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Is the value an object?
|
|
48
|
+
*
|
|
49
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
50
|
+
* @since 0.3.0
|
|
51
|
+
* @version 0.3.0
|
|
52
|
+
*/
|
|
53
|
+
CodeInput.setAttribute('value-is-object', {type: 'boolean'});
|
|
54
|
+
|
|
46
55
|
/**
|
|
47
56
|
* The minimum number of lines to show (height)
|
|
48
57
|
*
|
|
@@ -66,25 +75,43 @@ CodeInput.setAttribute('max-lines', {type: 'number'});
|
|
|
66
75
|
*
|
|
67
76
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
68
77
|
* @since 0.1.0
|
|
69
|
-
* @version 0.
|
|
78
|
+
* @version 0.3.0
|
|
70
79
|
*/
|
|
71
|
-
CodeInput.setProperty(function value(
|
|
80
|
+
CodeInput.setProperty(function value() {
|
|
81
|
+
|
|
82
|
+
let result;
|
|
72
83
|
|
|
73
84
|
if (this._editor) {
|
|
74
|
-
|
|
85
|
+
result = this._editor.getValue();
|
|
86
|
+
} else {
|
|
87
|
+
let editor_el = this.querySelector('.code-editor');
|
|
88
|
+
|
|
89
|
+
if (editor_el) {
|
|
90
|
+
result = editor_el.textContent;
|
|
91
|
+
} else {
|
|
92
|
+
if (this.assigned_data.value) {
|
|
93
|
+
return this.assigned_data.value;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
75
98
|
}
|
|
76
99
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (editor_el) {
|
|
80
|
-
return editor_el.textContent;
|
|
100
|
+
if (result && this.value_is_object) {
|
|
101
|
+
result = JSON.safeParse(result);
|
|
81
102
|
}
|
|
82
103
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
104
|
+
return result;
|
|
105
|
+
|
|
106
|
+
}, function setValue(original_value) {
|
|
86
107
|
|
|
87
|
-
|
|
108
|
+
let value;
|
|
109
|
+
|
|
110
|
+
if (this.value_is_object) {
|
|
111
|
+
value = JSON.stringify(value, null, '\t');
|
|
112
|
+
} else {
|
|
113
|
+
value = original_value;
|
|
114
|
+
}
|
|
88
115
|
|
|
89
116
|
if (this._editor) {
|
|
90
117
|
this._editor.setValue(value);
|
|
@@ -101,7 +128,9 @@ CodeInput.setProperty(function value(value) {
|
|
|
101
128
|
return editor_el.textContent = value;
|
|
102
129
|
}
|
|
103
130
|
|
|
104
|
-
this.assigned_data.value =
|
|
131
|
+
this.assigned_data.value = original_value;
|
|
132
|
+
|
|
133
|
+
this.hawkejs_renderer.registerElementInstance(this);
|
|
105
134
|
});
|
|
106
135
|
|
|
107
136
|
/**
|
|
@@ -153,7 +182,14 @@ CodeInput.setMethod(async function introduced() {
|
|
|
153
182
|
}
|
|
154
183
|
|
|
155
184
|
if (this.assigned_data.value) {
|
|
156
|
-
|
|
185
|
+
|
|
186
|
+
let value = this.assigned_data.value;
|
|
187
|
+
|
|
188
|
+
if (this.value_is_object) {
|
|
189
|
+
value = JSON.stringify(value, null, '\t');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
editor.setValue(value, -1);
|
|
157
193
|
}
|
|
158
194
|
|
|
159
195
|
if (this.language_mode) {
|
|
@@ -164,5 +200,7 @@ CodeInput.setMethod(async function introduced() {
|
|
|
164
200
|
}
|
|
165
201
|
}
|
|
166
202
|
|
|
203
|
+
this.style.height = null;
|
|
204
|
+
|
|
167
205
|
this._editor = editor;
|
|
168
206
|
});
|
package/element/al_field.js
CHANGED
|
@@ -77,9 +77,17 @@ Field.setAttribute('wrapper-view');
|
|
|
77
77
|
*
|
|
78
78
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
79
79
|
* @since 0.1.2
|
|
80
|
-
* @version 0.
|
|
80
|
+
* @version 0.3.0
|
|
81
81
|
*/
|
|
82
|
-
Field.setAttribute('readonly',
|
|
82
|
+
Field.setAttribute('readonly', function getReadonlyValue(current_value) {
|
|
83
|
+
|
|
84
|
+
if (current_value == null) {
|
|
85
|
+
current_value = this.alchemy_form?.readonly;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return current_value;
|
|
89
|
+
|
|
90
|
+
}, {boolean: true});
|
|
83
91
|
|
|
84
92
|
/**
|
|
85
93
|
* Widget settings for use in the views
|
|
@@ -585,14 +593,20 @@ Field.setProperty(function value_element() {
|
|
|
585
593
|
*
|
|
586
594
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
587
595
|
* @since 0.1.0
|
|
588
|
-
* @version 0.
|
|
596
|
+
* @version 0.3.0
|
|
589
597
|
*/
|
|
590
598
|
Field.setProperty(function value() {
|
|
591
599
|
|
|
592
600
|
let element = this.value_element;
|
|
593
601
|
|
|
594
602
|
if (element) {
|
|
595
|
-
|
|
603
|
+
let value = element.value;
|
|
604
|
+
|
|
605
|
+
if (this.config) {
|
|
606
|
+
value = this.config.castContainedValues(value);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
return value;
|
|
596
610
|
}
|
|
597
611
|
|
|
598
612
|
return this.value_to_render;
|
|
@@ -1043,32 +1057,19 @@ Field.setMethod(async function loadData(config, element) {
|
|
|
1043
1057
|
*
|
|
1044
1058
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1045
1059
|
* @since 0.2.9
|
|
1046
|
-
* @version 0.
|
|
1060
|
+
* @version 0.3.0
|
|
1047
1061
|
*
|
|
1048
|
-
* @param {Object} constraints
|
|
1062
|
+
* @param {Criteria|Object} constraints
|
|
1063
|
+
*
|
|
1064
|
+
* @param {Object}
|
|
1049
1065
|
*/
|
|
1050
1066
|
Field.setMethod(function resolveConstraintInstruction(constraints) {
|
|
1051
1067
|
|
|
1052
|
-
let context
|
|
1053
|
-
result = {},
|
|
1054
|
-
value,
|
|
1055
|
-
key;
|
|
1056
|
-
|
|
1057
|
-
for (key in constraints) {
|
|
1058
|
-
value = constraints[key];
|
|
1068
|
+
let context = {$0: this.alchemy_form.getValueAsDocument()};
|
|
1059
1069
|
|
|
1060
|
-
|
|
1061
|
-
if (value instanceof Classes.Alchemy.PathEvaluator) {
|
|
1062
|
-
if (!context && this.alchemy_form) {
|
|
1063
|
-
context = this.alchemy_form.getMainValue();
|
|
1064
|
-
}
|
|
1070
|
+
constraints = Classes.Alchemy.Criteria.Criteria.cast(constraints);
|
|
1065
1071
|
|
|
1066
|
-
|
|
1067
|
-
}
|
|
1068
|
-
} else {
|
|
1069
|
-
result[key] = value;
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
+
let result = constraints.compileToConditions(context);
|
|
1072
1073
|
|
|
1073
1074
|
return result;
|
|
1074
1075
|
});
|
package/element/al_form.js
CHANGED
|
@@ -34,6 +34,15 @@ Form.setAttribute('method');
|
|
|
34
34
|
*/
|
|
35
35
|
Form.setAttribute('model');
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Is this a read only form?
|
|
39
|
+
*
|
|
40
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
41
|
+
* @since 0.3.0
|
|
42
|
+
* @version 0.3.0
|
|
43
|
+
*/
|
|
44
|
+
Form.setAttribute('readonly', {boolean: true});
|
|
45
|
+
|
|
37
46
|
/**
|
|
38
47
|
* Should the entire document be submitted?
|
|
39
48
|
*
|
|
@@ -249,8 +258,6 @@ Form.setMethod(function setDocument(document) {
|
|
|
249
258
|
// Set the current document
|
|
250
259
|
this.document = document;
|
|
251
260
|
|
|
252
|
-
console.log('Setting document', document);
|
|
253
|
-
|
|
254
261
|
for (let key in current_value) {
|
|
255
262
|
let original_value = current_value[key],
|
|
256
263
|
new_value = document[key];
|
|
@@ -271,7 +278,7 @@ Form.setMethod(function setDocument(document) {
|
|
|
271
278
|
*
|
|
272
279
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
273
280
|
* @since 0.2.2
|
|
274
|
-
* @version 0.2.
|
|
281
|
+
* @version 0.2.10
|
|
275
282
|
*/
|
|
276
283
|
Form.setMethod(async function validate() {
|
|
277
284
|
|
|
@@ -279,11 +286,12 @@ Form.setMethod(async function validate() {
|
|
|
279
286
|
|
|
280
287
|
let violations = await doc.getViolations();
|
|
281
288
|
|
|
289
|
+
this.clearErrors();
|
|
290
|
+
|
|
282
291
|
if (violations) {
|
|
283
292
|
this.showError(violations);
|
|
284
293
|
throw violations;
|
|
285
294
|
}
|
|
286
|
-
|
|
287
295
|
});
|
|
288
296
|
|
|
289
297
|
/**
|
package/element/al_select.js
CHANGED
|
@@ -951,12 +951,13 @@ AlchemySelect.setMethod(function getRemoteFetchConfig() {
|
|
|
951
951
|
*
|
|
952
952
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
953
953
|
* @since 0.2.0
|
|
954
|
-
* @version 0.
|
|
954
|
+
* @version 0.3.0
|
|
955
955
|
*/
|
|
956
956
|
AlchemySelect.setMethod(function applyFetchedData(err, result, config) {
|
|
957
957
|
|
|
958
958
|
if (err) {
|
|
959
959
|
this.loading_dropdown = false;
|
|
960
|
+
alchemy.handleError(err);
|
|
960
961
|
return;
|
|
961
962
|
}
|
|
962
963
|
|