alchemy-form 0.1.7 → 0.1.10
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 +24 -0
- package/assets/stylesheets/form/alchemy_select.scss +2 -4
- package/controller/form_api_controller.js +10 -3
- package/element/alchemy_field.js +32 -15
- package/element/alchemy_field_array.js +1 -1
- package/element/alchemy_password_input.js +141 -0
- package/element/alchemy_select.js +136 -38
- package/element/alchemy_table.js +57 -7
- package/element/code_input.js +3 -1
- package/helper/widgets/alchemy_field_widget.js +5 -1
- package/package.json +3 -3
- package/view/form/elements/code_input.hwk +1 -1
- package/view/form/elements/password_input.hwk +36 -0
- package/view/form/inputs/edit/belongs_to.hwk +1 -1
- package/view/form/inputs/edit/html.hwk +5 -0
- package/view/form/inputs/view/datetime.hwk +1 -0
- package/view/form/inputs/view/string.hwk +1 -0
- package/view/form/inputs/view_inline/datetime.hwk +4 -0
- package/view/form/inputs/view_inline/file.hwk +6 -0
- package/view/form/inputs/view_inline/string.hwk +1 -0
- package/view/form/wrappers/view_inline/default.hwk +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
## 0.1.10 (2022-07-14)
|
|
2
|
+
|
|
3
|
+
* Hide `code-input` contents until it's fully loaded
|
|
4
|
+
* Don't crash when failing to get a field definition in a table
|
|
5
|
+
|
|
6
|
+
## 0.1.9 (2022-07-06)
|
|
7
|
+
|
|
8
|
+
* Allow supplying a custom `data-src` to `alchemy-field` elements
|
|
9
|
+
* Add `view` templates for File & Datetime fields
|
|
10
|
+
* Use the new `alchemy.getClientModel()` method in `alchemy-field` element
|
|
11
|
+
* Add `alchemy-password-input` element
|
|
12
|
+
|
|
13
|
+
## 0.1.8 (2022-06-29)
|
|
14
|
+
|
|
15
|
+
* Move the `alchemy-select` pagination checker initializer to a static function
|
|
16
|
+
* Prevent `alchemy-select` from keeping on loading remote data when last few results were empty
|
|
17
|
+
* Fix pagination breaking re-opening of `alchemy-select` dropdown
|
|
18
|
+
* Fix initial value of a `BelongsTo` `alchemy-select` element not loading
|
|
19
|
+
* Fix `alchemy-select` downward-arrow-icon being rendered over value content
|
|
20
|
+
* Use `alchemy-code-input` for HTML fields
|
|
21
|
+
* Allow manually setting a value on `alchemy-field` elements
|
|
22
|
+
* Try to let `Field` instances decide the representation of values in `alchemy-table` elements
|
|
23
|
+
* Don't open the `alchemy-table` contextmenu when clicking on anchors
|
|
24
|
+
|
|
1
25
|
## 0.1.7 (2022-06-12)
|
|
2
26
|
|
|
3
27
|
* Fix `<alchemy-table>` code typo
|
|
@@ -39,7 +39,7 @@ alchemy-select {
|
|
|
39
39
|
align-items: center;
|
|
40
40
|
|
|
41
41
|
input.type-area {
|
|
42
|
-
height: 1.5rem;
|
|
42
|
+
height: 1.5rem !important;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -102,7 +102,6 @@ alchemy-select {
|
|
|
102
102
|
font-family: inherit;
|
|
103
103
|
font-size: 13px;
|
|
104
104
|
line-height: 18px;
|
|
105
|
-
-webkit-font-smoothing: inherit;
|
|
106
105
|
display: inline-block !important;
|
|
107
106
|
padding: 0 !important;
|
|
108
107
|
min-height: 0 !important;
|
|
@@ -113,11 +112,10 @@ alchemy-select {
|
|
|
113
112
|
border: 0 none !important;
|
|
114
113
|
background: none !important;
|
|
115
114
|
line-height: inherit !important;
|
|
116
|
-
-webkit-user-select: auto !important;
|
|
117
|
-
-webkit-box-shadow: none !important;
|
|
118
115
|
box-shadow: none !important;
|
|
119
116
|
outline: none !important;
|
|
120
117
|
flex: 0 1 auto;
|
|
118
|
+
margin-right: 20px !important;
|
|
121
119
|
}
|
|
122
120
|
|
|
123
121
|
.dropdown {
|
|
@@ -17,20 +17,23 @@ 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.8
|
|
21
21
|
*
|
|
22
22
|
* @param {Conduit} conduit
|
|
23
23
|
*/
|
|
24
24
|
FormApi.setAction(async function related(conduit) {
|
|
25
25
|
|
|
26
|
-
const body = conduit.body
|
|
26
|
+
const body = conduit.body || {},
|
|
27
|
+
config = body.config || {};
|
|
27
28
|
|
|
28
29
|
const model = this.getModel(body.assoc_model);
|
|
29
30
|
let crit = model.find();
|
|
30
31
|
crit.limit(50);
|
|
31
32
|
crit.setOption('scenario', 'related_data');
|
|
32
33
|
|
|
33
|
-
if (
|
|
34
|
+
if (config.value) {
|
|
35
|
+
crit.where(model.primary_key).equals(config.value);
|
|
36
|
+
} else if (config.search) {
|
|
34
37
|
let display_fields = Array.cast(model.displayField);
|
|
35
38
|
|
|
36
39
|
let or = crit.or();
|
|
@@ -45,6 +48,10 @@ FormApi.setAction(async function related(conduit) {
|
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
|
|
51
|
+
if (config.page) {
|
|
52
|
+
crit.page(config.page);
|
|
53
|
+
}
|
|
54
|
+
|
|
48
55
|
let records = await model.find('all', crit);
|
|
49
56
|
|
|
50
57
|
let result = {
|
package/element/alchemy_field.js
CHANGED
|
@@ -34,6 +34,15 @@ Field.setStylesheetFile('form/alchemy_field');
|
|
|
34
34
|
*/
|
|
35
35
|
Field.setStatic('use_new_renderer_scope', true);
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* The data source url/route to use
|
|
39
|
+
*
|
|
40
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
41
|
+
* @since 0.1.9
|
|
42
|
+
* @version 0.1.9
|
|
43
|
+
*/
|
|
44
|
+
Field.setAttribute('data-src');
|
|
45
|
+
|
|
37
46
|
/**
|
|
38
47
|
* The name of the field
|
|
39
48
|
*
|
|
@@ -133,7 +142,7 @@ Field.enforceProperty(function alchemy_field_schema(new_value, old_value) {
|
|
|
133
142
|
*
|
|
134
143
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
135
144
|
* @since 0.1.0
|
|
136
|
-
* @version 0.1.
|
|
145
|
+
* @version 0.1.8
|
|
137
146
|
*/
|
|
138
147
|
Field.enforceProperty(function config(new_value, old_value) {
|
|
139
148
|
|
|
@@ -148,7 +157,7 @@ Field.enforceProperty(function config(new_value, old_value) {
|
|
|
148
157
|
|
|
149
158
|
if (new_value && new_value.constructor && new_value.constructor.type_name) {
|
|
150
159
|
this.field_type = new_value.constructor.type_name;
|
|
151
|
-
} else {
|
|
160
|
+
} else if (new_value) {
|
|
152
161
|
this.field_type = null;
|
|
153
162
|
}
|
|
154
163
|
|
|
@@ -160,7 +169,7 @@ Field.enforceProperty(function config(new_value, old_value) {
|
|
|
160
169
|
*
|
|
161
170
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
162
171
|
* @since 0.1.0
|
|
163
|
-
* @version 0.1.
|
|
172
|
+
* @version 0.1.9
|
|
164
173
|
*/
|
|
165
174
|
Field.enforceProperty(function schema(new_value, old_value) {
|
|
166
175
|
|
|
@@ -181,15 +190,10 @@ Field.enforceProperty(function schema(new_value, old_value) {
|
|
|
181
190
|
let model_name = this.model;
|
|
182
191
|
|
|
183
192
|
if (model_name) {
|
|
184
|
-
|
|
185
|
-
let model = alchemy.getModel(model_name);
|
|
193
|
+
let model = alchemy.getClientModel(model_name);
|
|
186
194
|
|
|
187
195
|
if (model) {
|
|
188
196
|
new_value = model.schema;
|
|
189
|
-
|
|
190
|
-
if (Blast.isNode) {
|
|
191
|
-
new_value = JSON.clone(new_value, 'toHawkejs');
|
|
192
|
-
}
|
|
193
197
|
}
|
|
194
198
|
}
|
|
195
199
|
}
|
|
@@ -493,10 +497,14 @@ Field.setProperty(function wrapper_files() {
|
|
|
493
497
|
*
|
|
494
498
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
495
499
|
* @since 0.1.0
|
|
496
|
-
* @version 0.1.
|
|
500
|
+
* @version 0.1.8
|
|
497
501
|
*/
|
|
498
502
|
Field.setProperty(function original_value() {
|
|
499
503
|
|
|
504
|
+
if (this.assigned_data.original_value != null) {
|
|
505
|
+
return this.assigned_data.original_value;
|
|
506
|
+
}
|
|
507
|
+
|
|
500
508
|
let alchemy_field_schema = this.alchemy_field_schema,
|
|
501
509
|
path = this.field_path_in_current_schema;
|
|
502
510
|
|
|
@@ -517,6 +525,8 @@ Field.setProperty(function original_value() {
|
|
|
517
525
|
if (form && form.document) {
|
|
518
526
|
return Object.path(form.document, path);
|
|
519
527
|
}
|
|
528
|
+
}, function setOriginalValue(value) {
|
|
529
|
+
return this.assigned_data.original_value = value;
|
|
520
530
|
});
|
|
521
531
|
|
|
522
532
|
/**
|
|
@@ -551,7 +561,7 @@ Field.setProperty(function value_element() {
|
|
|
551
561
|
*
|
|
552
562
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
553
563
|
* @since 0.1.0
|
|
554
|
-
* @version 0.1.
|
|
564
|
+
* @version 0.1.8
|
|
555
565
|
*/
|
|
556
566
|
Field.setProperty(function value() {
|
|
557
567
|
|
|
@@ -569,8 +579,9 @@ Field.setProperty(function value() {
|
|
|
569
579
|
|
|
570
580
|
if (element) {
|
|
571
581
|
element.value = value;
|
|
582
|
+
} else if (this.original_value == null) {
|
|
583
|
+
this.original_value = value;
|
|
572
584
|
}
|
|
573
|
-
|
|
574
585
|
});
|
|
575
586
|
|
|
576
587
|
/**
|
|
@@ -708,7 +719,7 @@ Field.setMethod(function retained() {
|
|
|
708
719
|
*
|
|
709
720
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
710
721
|
* @since 0.1.0
|
|
711
|
-
* @version 0.1.
|
|
722
|
+
* @version 0.1.9
|
|
712
723
|
*
|
|
713
724
|
* @param {Object} config
|
|
714
725
|
* @param {HTMLElement} element
|
|
@@ -735,7 +746,7 @@ Field.setMethod(async function loadData(config, element) {
|
|
|
735
746
|
}
|
|
736
747
|
}
|
|
737
748
|
|
|
738
|
-
|
|
749
|
+
let resource_options = {
|
|
739
750
|
name : 'FormApi#related',
|
|
740
751
|
post : true,
|
|
741
752
|
body : {
|
|
@@ -744,7 +755,13 @@ Field.setMethod(async function loadData(config, element) {
|
|
|
744
755
|
assoc_model : field.options.modelName,
|
|
745
756
|
config : config,
|
|
746
757
|
}
|
|
747
|
-
}
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
if (this.data_src) {
|
|
761
|
+
resource_options.name = this.data_src;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
return this.hawkejs_helpers.Alchemy.getResource(resource_options);
|
|
748
765
|
}
|
|
749
766
|
|
|
750
767
|
});
|
|
@@ -86,7 +86,7 @@ FieldArray.setMethod(function introduced() {
|
|
|
86
86
|
let view_files = alchemy_field.view_files;
|
|
87
87
|
|
|
88
88
|
if (!view_files || !view_files.length) {
|
|
89
|
-
throw new Error('Unable to add new entry for ' + alchemy_field.field_title);
|
|
89
|
+
throw new Error('Unable to add new entry for field "' + alchemy_field.field_title + '", no view files found');
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
let new_entry = that.createElement('alchemy-field-array-entry');
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The number-input custom element
|
|
3
|
+
*
|
|
4
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
5
|
+
* @since 0.1.9
|
|
6
|
+
* @version 0.1.9
|
|
7
|
+
*/
|
|
8
|
+
const PasswordInput = Function.inherits('Alchemy.Element.Form.StringInput', 'PasswordInput');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The template to use for the content of this element
|
|
12
|
+
*
|
|
13
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
14
|
+
* @since 0.1.9
|
|
15
|
+
* @version 0.1.9
|
|
16
|
+
*/
|
|
17
|
+
PasswordInput.setTemplateFile('form/elements/password_input');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Reference to the repeat input element
|
|
21
|
+
*
|
|
22
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
23
|
+
* @since 0.1.9
|
|
24
|
+
* @version 0.1.9
|
|
25
|
+
*/
|
|
26
|
+
PasswordInput.addElementGetter('repeat_el', '.repeat-input');
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Reference to the repeat label element
|
|
30
|
+
*
|
|
31
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
32
|
+
* @since 0.1.9
|
|
33
|
+
* @version 0.1.9
|
|
34
|
+
*/
|
|
35
|
+
PasswordInput.addElementGetter('repeat_label', '.repeat-input-label');
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The value property
|
|
39
|
+
*
|
|
40
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
41
|
+
* @since 0.1.9
|
|
42
|
+
* @version 0.1.9
|
|
43
|
+
*/
|
|
44
|
+
PasswordInput.setProperty(function value() {
|
|
45
|
+
|
|
46
|
+
let val;
|
|
47
|
+
|
|
48
|
+
if (this.input_el) {
|
|
49
|
+
val = this.input_el.value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!val) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!this.valuesAreEqual()) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return val;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Are both inputs the same?
|
|
65
|
+
*
|
|
66
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
67
|
+
* @since 0.1.9
|
|
68
|
+
* @version 0.1.9
|
|
69
|
+
*/
|
|
70
|
+
PasswordInput.setMethod(function valuesAreEqual() {
|
|
71
|
+
|
|
72
|
+
let first_value = this.input_el?.value,
|
|
73
|
+
repeat_value = this.repeat_el?.value;
|
|
74
|
+
|
|
75
|
+
return first_value == repeat_value;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Revalidate the value
|
|
80
|
+
*
|
|
81
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
82
|
+
* @since 0.1.9
|
|
83
|
+
* @version 0.1.9
|
|
84
|
+
*/
|
|
85
|
+
PasswordInput.setMethod(async function revalidate() {
|
|
86
|
+
|
|
87
|
+
let first_value = this.input_el?.value,
|
|
88
|
+
repeat_value = this.repeat_el.value;
|
|
89
|
+
|
|
90
|
+
if (first_value) {
|
|
91
|
+
this.repeat_label.hidden = false;
|
|
92
|
+
} else {
|
|
93
|
+
this.repeat_el.value = '';
|
|
94
|
+
this.repeat_label.hidden = true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
this.removeErrors();
|
|
98
|
+
|
|
99
|
+
if (!first_value && !repeat_value) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (first_value != repeat_value) {
|
|
104
|
+
return this.addError(this.__('does-not-match'), true);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return revalidate.super.call(this);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Actions to perform when this element
|
|
112
|
+
* has been added to the DOM for the first time
|
|
113
|
+
*
|
|
114
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
115
|
+
* @since 0.1.9
|
|
116
|
+
* @version 0.1.9
|
|
117
|
+
*/
|
|
118
|
+
PasswordInput.setMethod(function introduced() {
|
|
119
|
+
|
|
120
|
+
const that = this;
|
|
121
|
+
|
|
122
|
+
introduced.super.call(this);
|
|
123
|
+
|
|
124
|
+
this.repeat_el.addEventListener('focus', function onFocus(e) {
|
|
125
|
+
that.inputbox_el.classList.add('focus');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
this.repeat_el.addEventListener('blur', function onBlur(e) {
|
|
129
|
+
that.inputbox_el.classList.remove('focus');
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
this.repeat_el.addEventListener('keyup', Fn.throttle(function onKeyup(e) {
|
|
133
|
+
that.revalidate();
|
|
134
|
+
that.emit('changing');
|
|
135
|
+
}, {
|
|
136
|
+
minimum_wait : 350,
|
|
137
|
+
immediate : false,
|
|
138
|
+
reset_on_call : true
|
|
139
|
+
}));
|
|
140
|
+
|
|
141
|
+
});
|
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
* @since 0.1.0
|
|
6
6
|
* @version 0.1.0
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
Select.super.call(this);
|
|
10
|
-
});
|
|
8
|
+
const AlchemySelect = Function.inherits('Alchemy.Element.Form.Base', 'Select');
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* The remote url attribute
|
|
@@ -389,14 +387,56 @@ AlchemySelect.setProperty(function loading_dropdown() {
|
|
|
389
387
|
*
|
|
390
388
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
391
389
|
* @since 0.1.0
|
|
392
|
-
* @version 0.1.
|
|
390
|
+
* @version 0.1.8
|
|
393
391
|
*/
|
|
394
392
|
AlchemySelect.setProperty(function search_value() {
|
|
395
|
-
|
|
393
|
+
|
|
394
|
+
let type_area = this.type_area,
|
|
395
|
+
result = '';
|
|
396
396
|
|
|
397
397
|
if (type_area) {
|
|
398
|
-
|
|
398
|
+
result = type_area.value;
|
|
399
399
|
}
|
|
400
|
+
|
|
401
|
+
if (this.previous_search_value == null) {
|
|
402
|
+
this.previous_search_value = '';
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// If the search value changed, nullify the last page result
|
|
406
|
+
if (this.previous_search_value != result) {
|
|
407
|
+
this.setLastSuccessfulLoadedPage(null);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
this.previous_search_value = result;
|
|
411
|
+
|
|
412
|
+
return result;
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Make sure the pagination watcher exists
|
|
417
|
+
*
|
|
418
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
419
|
+
* @since 0.1.0
|
|
420
|
+
* @version 0.1.8
|
|
421
|
+
*/
|
|
422
|
+
AlchemySelect.setStatic(function ensurePaginationChecker() {
|
|
423
|
+
|
|
424
|
+
if (AlchemySelect.has_paginator_viewer) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Only ever add 1 viewer per page
|
|
429
|
+
AlchemySelect.has_paginator_viewer = true;
|
|
430
|
+
|
|
431
|
+
hawkejs.scene.appears('js-he-ais-pager', {live: true, padding: 10, throttle: 200}, function onInfinity(el) {
|
|
432
|
+
|
|
433
|
+
if (!el.parentElement || !el.parentElement.parentElement) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const alchemy_select_instance = el.parentElement.parentElement;
|
|
438
|
+
alchemy_select_instance.loadOptions(++alchemy_select_instance.loaded_page);
|
|
439
|
+
});
|
|
400
440
|
});
|
|
401
441
|
|
|
402
442
|
/**
|
|
@@ -420,7 +460,7 @@ AlchemySelect.setMethod(function rendered() {
|
|
|
420
460
|
*
|
|
421
461
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
422
462
|
* @since 0.1.0
|
|
423
|
-
* @version 0.1.
|
|
463
|
+
* @version 0.1.8
|
|
424
464
|
*/
|
|
425
465
|
AlchemySelect.setMethod(function introduced() {
|
|
426
466
|
|
|
@@ -433,14 +473,7 @@ AlchemySelect.setMethod(function introduced() {
|
|
|
433
473
|
this.makeSortable();
|
|
434
474
|
}
|
|
435
475
|
|
|
436
|
-
|
|
437
|
-
AlchemySelect.has_paginator_viewer = true;
|
|
438
|
-
|
|
439
|
-
hawkejs.scene.appears('js-he-ais-pager', {live: true, padding: 10, throttle: 200}, function onInfinity(el) {
|
|
440
|
-
var ais = el.parentElement.parentElement;
|
|
441
|
-
ais.loadOptions(++ais.loaded_page);
|
|
442
|
-
});
|
|
443
|
-
}
|
|
476
|
+
AlchemySelect.ensurePaginationChecker();
|
|
444
477
|
|
|
445
478
|
this.addEventListener('focus-without', function onFocusOut(e) {
|
|
446
479
|
that.type_area.value = '';
|
|
@@ -462,8 +495,6 @@ AlchemySelect.setMethod(function introduced() {
|
|
|
462
495
|
|
|
463
496
|
this.addEventListener('keydown', function onKeydown(e) {
|
|
464
497
|
|
|
465
|
-
console.log('keydown:', e);
|
|
466
|
-
|
|
467
498
|
// Only listen for keydowns on the alchemy-select itself
|
|
468
499
|
if (e.target != that) {
|
|
469
500
|
return;
|
|
@@ -829,11 +860,12 @@ AlchemySelect.setMethod(function _processPreloadedValues() {
|
|
|
829
860
|
*
|
|
830
861
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
831
862
|
* @since 0.1.0
|
|
832
|
-
* @version 0.1.
|
|
863
|
+
* @version 0.1.8
|
|
833
864
|
*
|
|
834
865
|
* @param {Object} response
|
|
866
|
+
* @param {Number} page The page, if it's via pagination
|
|
835
867
|
*/
|
|
836
|
-
AlchemySelect.setMethod(function _processResponseData(response) {
|
|
868
|
+
AlchemySelect.setMethod(function _processResponseData(response, page) {
|
|
837
869
|
|
|
838
870
|
if (!response) {
|
|
839
871
|
response = {};
|
|
@@ -851,14 +883,48 @@ AlchemySelect.setMethod(function _processResponseData(response) {
|
|
|
851
883
|
records = [];
|
|
852
884
|
}
|
|
853
885
|
|
|
854
|
-
|
|
886
|
+
this._processResponseList(records, page);
|
|
887
|
+
|
|
888
|
+
this.refreshResultAmount();
|
|
889
|
+
this._markSelectedItems();
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Process the response list of a certain paige
|
|
894
|
+
*
|
|
895
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
896
|
+
* @since 0.1.8
|
|
897
|
+
* @version 0.1.8
|
|
898
|
+
*
|
|
899
|
+
* @param {Array} list
|
|
900
|
+
* @param {Number} page
|
|
901
|
+
*/
|
|
902
|
+
AlchemySelect.setMethod(function _processResponseList(list, page) {
|
|
903
|
+
|
|
904
|
+
let record,
|
|
905
|
+
item;
|
|
906
|
+
|
|
907
|
+
if (page == 1 && this.current_option && this.current_option.data) {
|
|
908
|
+
record = this.current_option.data;
|
|
909
|
+
item = this._makeOption(record._id || record.id, record);
|
|
910
|
+
this.addToDropdown(item);
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
for (record of list) {
|
|
855
914
|
item = this._makeOption(record._id || record.id, record);
|
|
856
915
|
this.addToDropdown(item);
|
|
857
916
|
}
|
|
858
917
|
|
|
859
918
|
this.loading_dropdown = false;
|
|
860
|
-
|
|
861
|
-
this
|
|
919
|
+
|
|
920
|
+
// If there were values & they come from a page, record this as a succesful page
|
|
921
|
+
if (page != null && list.length) {
|
|
922
|
+
if (!this.last_page_result) {
|
|
923
|
+
this.setLastSuccessfulLoadedPage(page);
|
|
924
|
+
} else if (page > this.last_page_result) {
|
|
925
|
+
this.setLastSuccessfulLoadedPage(page);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
862
928
|
});
|
|
863
929
|
|
|
864
930
|
/**
|
|
@@ -866,7 +932,7 @@ AlchemySelect.setMethod(function _processResponseData(response) {
|
|
|
866
932
|
*
|
|
867
933
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
868
934
|
* @since 0.1.0
|
|
869
|
-
* @version 0.1.
|
|
935
|
+
* @version 0.1.8
|
|
870
936
|
*
|
|
871
937
|
* @param {Number} page
|
|
872
938
|
*
|
|
@@ -887,6 +953,10 @@ AlchemySelect.setMethod(function loadRemote(page) {
|
|
|
887
953
|
return pledge;
|
|
888
954
|
}
|
|
889
955
|
|
|
956
|
+
if (page == null) {
|
|
957
|
+
page = 1;
|
|
958
|
+
}
|
|
959
|
+
|
|
890
960
|
const that = this;
|
|
891
961
|
|
|
892
962
|
this.loading_dropdown = true;
|
|
@@ -906,11 +976,11 @@ AlchemySelect.setMethod(function loadRemote(page) {
|
|
|
906
976
|
throw err;
|
|
907
977
|
}
|
|
908
978
|
|
|
909
|
-
if (page == null) {
|
|
979
|
+
if (page == null || page == 1) {
|
|
910
980
|
Hawkejs.removeChildren(that.dropdown_content);
|
|
911
981
|
}
|
|
912
982
|
|
|
913
|
-
that._processResponseData(data);
|
|
983
|
+
that._processResponseData(data, page);
|
|
914
984
|
|
|
915
985
|
pledge.resolve(true);
|
|
916
986
|
};
|
|
@@ -1001,7 +1071,19 @@ AlchemySelect.setMethod(function _markSelectedItems() {
|
|
|
1001
1071
|
}
|
|
1002
1072
|
}
|
|
1003
1073
|
}
|
|
1074
|
+
});
|
|
1004
1075
|
|
|
1076
|
+
/**
|
|
1077
|
+
* Set the last successful loaded page
|
|
1078
|
+
*
|
|
1079
|
+
* @author Jelle De Loecker <jelle@develry.be>
|
|
1080
|
+
* @since 0.1.8
|
|
1081
|
+
* @version 0.1.8
|
|
1082
|
+
*
|
|
1083
|
+
* @param {Number} page
|
|
1084
|
+
*/
|
|
1085
|
+
AlchemySelect.setMethod(function setLastSuccessfulLoadedPage(page) {
|
|
1086
|
+
this.last_page_result = page;
|
|
1005
1087
|
});
|
|
1006
1088
|
|
|
1007
1089
|
/**
|
|
@@ -1009,15 +1091,13 @@ AlchemySelect.setMethod(function _markSelectedItems() {
|
|
|
1009
1091
|
*
|
|
1010
1092
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
1011
1093
|
* @since 0.1.0
|
|
1012
|
-
* @version 0.1.
|
|
1094
|
+
* @version 0.1.8
|
|
1013
1095
|
*
|
|
1014
1096
|
* @param {Number} page
|
|
1015
1097
|
*/
|
|
1016
1098
|
AlchemySelect.setMethod(function loadOptions(page) {
|
|
1017
1099
|
|
|
1018
|
-
|
|
1019
|
-
model,
|
|
1020
|
-
field;
|
|
1100
|
+
const that = this;
|
|
1021
1101
|
|
|
1022
1102
|
if (this.total_item_count >= this.loaded_item_count) {
|
|
1023
1103
|
if (this.dropdown_content.children.length == 0) {
|
|
@@ -1029,12 +1109,34 @@ AlchemySelect.setMethod(function loadOptions(page) {
|
|
|
1029
1109
|
return;
|
|
1030
1110
|
}
|
|
1031
1111
|
|
|
1112
|
+
// Prevent it from keeping on loading empty pages if the previous page was empty
|
|
1113
|
+
if (page && this.last_page_result) {
|
|
1114
|
+
let next_allowed_page = this.last_page_result + 1;
|
|
1115
|
+
|
|
1116
|
+
if (page > next_allowed_page) {
|
|
1117
|
+
return;
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
// Previous page will only be set to the last page that had items.
|
|
1122
|
+
// So if there are 0 results overall, it won't ever be set.
|
|
1123
|
+
// In that case: ignore any page load over 1.
|
|
1124
|
+
if (page > 1 && !this.last_page_result) {
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
// If stuff has already been loaded and this is just re-opening the dropdown,
|
|
1129
|
+
// don't do anything yet
|
|
1130
|
+
if (page == null && this.last_page_result > 0) {
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1032
1134
|
// If an URL is provided, use that
|
|
1033
1135
|
if (this.src || this.dataprovider) {
|
|
1034
1136
|
return this.loadRemote(page);
|
|
1035
1137
|
}
|
|
1036
1138
|
|
|
1037
|
-
field = this.model_field;
|
|
1139
|
+
let field = this.model_field;
|
|
1038
1140
|
|
|
1039
1141
|
if (!field) {
|
|
1040
1142
|
return;
|
|
@@ -1042,7 +1144,7 @@ AlchemySelect.setMethod(function loadOptions(page) {
|
|
|
1042
1144
|
|
|
1043
1145
|
this.loading_dropdown = true;
|
|
1044
1146
|
|
|
1045
|
-
model = this.form.getModel(field.modelName);
|
|
1147
|
+
let model = this.form.getModel(field.modelName);
|
|
1046
1148
|
|
|
1047
1149
|
model.find('all', {
|
|
1048
1150
|
limit : 20,
|
|
@@ -1053,12 +1155,7 @@ AlchemySelect.setMethod(function loadOptions(page) {
|
|
|
1053
1155
|
throw err;
|
|
1054
1156
|
}
|
|
1055
1157
|
|
|
1056
|
-
|
|
1057
|
-
var item = that._makeOption(record._id || record.id, record);
|
|
1058
|
-
that.addToDropdown(item);
|
|
1059
|
-
});
|
|
1060
|
-
|
|
1061
|
-
that.loading_dropdown = false;
|
|
1158
|
+
that._processResponseList(records, page);
|
|
1062
1159
|
});
|
|
1063
1160
|
});
|
|
1064
1161
|
|
|
@@ -1699,9 +1796,10 @@ AlchemySelect.setMethod(function applyLocalFilter(query) {
|
|
|
1699
1796
|
*
|
|
1700
1797
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
1701
1798
|
* @since 0.1.0
|
|
1702
|
-
* @version 0.1.
|
|
1799
|
+
* @version 0.1.8
|
|
1703
1800
|
*/
|
|
1704
1801
|
AlchemySelect.setMethod('refreshRemote', Fn.throttle(function refreshRemote() {
|
|
1802
|
+
this.loaded_page = 0;
|
|
1705
1803
|
this.loadRemote();
|
|
1706
1804
|
}, {
|
|
1707
1805
|
minimum_wait : 350,
|
package/element/alchemy_table.js
CHANGED
|
@@ -589,12 +589,55 @@ Table.setMethod(function showPagination() {
|
|
|
589
589
|
pager.showPage(records.page, Math.ceil(records.available / records.page_size));
|
|
590
590
|
});
|
|
591
591
|
|
|
592
|
+
/**
|
|
593
|
+
* Get a fieldset's preferred content view
|
|
594
|
+
*
|
|
595
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
596
|
+
* @since 0.1.8
|
|
597
|
+
* @version 0.1.10
|
|
598
|
+
*
|
|
599
|
+
* @param {FieldConfig} field_config The config on how to display the field
|
|
600
|
+
* @param {Object} container The container where the field should be in
|
|
601
|
+
*
|
|
602
|
+
* @return
|
|
603
|
+
*/
|
|
604
|
+
Table.setMethod(function getFieldConfigView(field_config, container) {
|
|
605
|
+
|
|
606
|
+
let value = field_config.getValueIn(container),
|
|
607
|
+
field;
|
|
608
|
+
|
|
609
|
+
try {
|
|
610
|
+
field = field_config.getFieldDefinition();
|
|
611
|
+
} catch (err) {
|
|
612
|
+
console.error('Failed to get field definition:', err);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
if (value == null && !field) {
|
|
616
|
+
return null;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// Fallback to simple text view
|
|
620
|
+
if (!field) {
|
|
621
|
+
let text = field_config.getDisplayValueIn(container);
|
|
622
|
+
|
|
623
|
+
return Hawkejs.createText(text);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
let alchemy_field = this.createElement('alchemy-field');
|
|
627
|
+
alchemy_field.view_type = 'view_inline';
|
|
628
|
+
alchemy_field.field_name = field.name;
|
|
629
|
+
alchemy_field.config = field;
|
|
630
|
+
alchemy_field.original_value = value;
|
|
631
|
+
|
|
632
|
+
return alchemy_field;
|
|
633
|
+
});
|
|
634
|
+
|
|
592
635
|
/**
|
|
593
636
|
* Create a datarow
|
|
594
637
|
*
|
|
595
638
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
596
639
|
* @since 0.1.0
|
|
597
|
-
* @version 0.1.
|
|
640
|
+
* @version 0.1.8
|
|
598
641
|
*
|
|
599
642
|
* @param {Object} entry
|
|
600
643
|
*
|
|
@@ -602,7 +645,7 @@ Table.setMethod(function showPagination() {
|
|
|
602
645
|
*/
|
|
603
646
|
Table.setMethod(function createDataRow(entry) {
|
|
604
647
|
|
|
605
|
-
let
|
|
648
|
+
let field_set_config,
|
|
606
649
|
value,
|
|
607
650
|
tr = this.createElement('tr'),
|
|
608
651
|
td,
|
|
@@ -610,13 +653,13 @@ Table.setMethod(function createDataRow(entry) {
|
|
|
610
653
|
|
|
611
654
|
tr.dataset.pk = id;
|
|
612
655
|
|
|
613
|
-
for (
|
|
656
|
+
for (field_set_config of this.fieldset) {
|
|
614
657
|
td = this.createElement('td');
|
|
615
658
|
|
|
616
|
-
|
|
659
|
+
let element = this.getFieldConfigView(field_set_config, entry);
|
|
617
660
|
|
|
618
|
-
if (
|
|
619
|
-
td.
|
|
661
|
+
if (element) {
|
|
662
|
+
td.append(element);
|
|
620
663
|
}
|
|
621
664
|
|
|
622
665
|
tr.append(td);
|
|
@@ -709,7 +752,7 @@ Table.setMethod(function getEntryActions(record, filter) {
|
|
|
709
752
|
*
|
|
710
753
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
711
754
|
* @since 0.1.6
|
|
712
|
-
* @version 0.1.
|
|
755
|
+
* @version 0.1.8
|
|
713
756
|
*
|
|
714
757
|
* @param {Object} entry
|
|
715
758
|
*/
|
|
@@ -745,6 +788,13 @@ Table.setMethod(function attachContextMenus() {
|
|
|
745
788
|
|
|
746
789
|
tr.addEventListener('contextmenu', e => {
|
|
747
790
|
|
|
791
|
+
// Ignore right clicks on certain elements
|
|
792
|
+
if (e && e.target) {
|
|
793
|
+
if (e.target.closest('a')) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
748
798
|
this.selectRow(tr);
|
|
749
799
|
|
|
750
800
|
let menu = this.createElement('he-context-menu');
|
package/element/code_input.js
CHANGED
|
@@ -67,7 +67,7 @@ CodeInput.setProperty(function value(value) {
|
|
|
67
67
|
*
|
|
68
68
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
69
69
|
* @since 0.1.0
|
|
70
|
-
* @version 0.1.
|
|
70
|
+
* @version 0.1.10
|
|
71
71
|
*/
|
|
72
72
|
CodeInput.setMethod(async function introduced() {
|
|
73
73
|
|
|
@@ -75,6 +75,8 @@ CodeInput.setMethod(async function introduced() {
|
|
|
75
75
|
|
|
76
76
|
let editor_el = this.querySelector('.code-editor');
|
|
77
77
|
|
|
78
|
+
editor_el.hidden = false;
|
|
79
|
+
|
|
78
80
|
let editor = ace.edit(editor_el);
|
|
79
81
|
|
|
80
82
|
editor.session.setUseWrapMode(true);
|
|
@@ -73,7 +73,7 @@ AlchemyField.enforceProperty(function alchemy_form(new_value) {
|
|
|
73
73
|
*
|
|
74
74
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
75
75
|
* @since 0.1.0
|
|
76
|
-
* @version 0.1.
|
|
76
|
+
* @version 0.1.9
|
|
77
77
|
*/
|
|
78
78
|
AlchemyField.setMethod(function populateWidget() {
|
|
79
79
|
|
|
@@ -101,6 +101,10 @@ AlchemyField.setMethod(function populateWidget() {
|
|
|
101
101
|
field_el.widget_settings = config.widget_settings;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
if (config.data_src) {
|
|
105
|
+
field_el.data_src = config.data_src;
|
|
106
|
+
}
|
|
107
|
+
|
|
104
108
|
this.element.append(field_el);
|
|
105
109
|
});
|
|
106
110
|
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alchemy-form",
|
|
3
3
|
"description": "Form plugin for Alchemy",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.10",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type" : "git",
|
|
7
7
|
"url" : "https://github.com/11ways/alchemy-form.git"
|
|
8
8
|
},
|
|
9
9
|
"peerDependencies": {
|
|
10
|
-
"alchemymvc" : "
|
|
10
|
+
"alchemymvc" : ">=1.2.0"
|
|
11
11
|
},
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"engines": {
|
|
14
|
-
"node" : ">=
|
|
14
|
+
"node" : ">=14.0.0"
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<div class="code-editor"><% Blast.Classes.Hawkejs.replaceChildren($0, child_nodes) %></div>
|
|
1
|
+
<div class="code-editor" hidden><% Blast.Classes.Hawkejs.replaceChildren($0, child_nodes) %></div>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<label>
|
|
2
|
+
<div class="inputlabel">
|
|
3
|
+
<span class="label" data-he-slot="label"></span>
|
|
4
|
+
<span class="description" data-he-slot="description"></span>
|
|
5
|
+
<hr class="spacer">
|
|
6
|
+
</div>
|
|
7
|
+
<div class="inputbox">
|
|
8
|
+
<input
|
|
9
|
+
name=<% self.getAttribute('input-name') || 'name' %>
|
|
10
|
+
placeholder=<% self.getAttribute('placeholder') %>
|
|
11
|
+
minlength=<% self.getAttribute('min-length') %>
|
|
12
|
+
maxlength=<% self.getAttribute('max-length') %>
|
|
13
|
+
class="input"
|
|
14
|
+
value="<% self.getAttribute('value') || '' %>"
|
|
15
|
+
type="password"
|
|
16
|
+
>
|
|
17
|
+
<i class="icon cross"></i>
|
|
18
|
+
<i class="icon checkmark"></i>
|
|
19
|
+
</div>
|
|
20
|
+
</label>
|
|
21
|
+
<label class="repeat-input-label" hidden>
|
|
22
|
+
<div class="inputbox">
|
|
23
|
+
<input
|
|
24
|
+
placeholder=<% self.getAttribute('repeat-placeholder') %>
|
|
25
|
+
class="input repeat-input"
|
|
26
|
+
value="<% self.getAttribute('value') || '' %>"
|
|
27
|
+
minlength=<% self.getAttribute('min-length') %>
|
|
28
|
+
maxlength=<% self.getAttribute('max-length') %>
|
|
29
|
+
type="password"
|
|
30
|
+
>
|
|
31
|
+
<i class="icon cross"></i>
|
|
32
|
+
<i class="icon checkmark"></i>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="errors"></div>
|
|
35
|
+
<div class="success"></div>
|
|
36
|
+
</label>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<% include('form/inputs/view_inline/datetime') %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<span class="alchemy-field-value">{{ value }}</span>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<span class="alchemy-field-value">{{ value }}</span>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<div data-he-name="field"></div>
|