alchemy-form 0.1.2 → 0.1.3
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 +11 -0
- package/assets/stylesheets/form/alchemy_feedback_input.scss +336 -0
- package/assets/stylesheets/form/general/_colors.scss +114 -0
- package/assets/stylesheets/form/general/_textsizes.scss +55 -0
- package/assets/stylesheets/form/general/index.scss +2 -0
- package/element/00_form_base.js +134 -0
- package/element/05_feedback_input.js +262 -3
- package/element/alchemy_field.js +60 -10
- package/element/alchemy_field_array_entry.js +53 -9
- package/element/alchemy_field_schema.js +72 -42
- package/element/alchemy_label.js +9 -3
- package/element/alchemy_table.js +20 -1
- package/element/number_input.js +106 -0
- package/element/string_input.js +333 -5
- package/helper/widgets/alchemy_form_widget.js +7 -1
- package/package.json +1 -1
- package/view/form/elements/number_input.hwk +36 -0
- package/view/form/inputs/edit/datetime.hwk +8 -1
package/element/alchemy_table.js
CHANGED
|
@@ -126,6 +126,15 @@ Table.setAttribute('page-size', {number: true});
|
|
|
126
126
|
*/
|
|
127
127
|
Table.setAttribute('show-filters', {boolean: true});
|
|
128
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Keep track of the loadRemote calls
|
|
131
|
+
*
|
|
132
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
133
|
+
* @since 0.1.3
|
|
134
|
+
* @version 0.1.3
|
|
135
|
+
*/
|
|
136
|
+
Table.setProperty('load_remote_counter', 0);
|
|
137
|
+
|
|
129
138
|
/**
|
|
130
139
|
* Look for changes to the show-filters attribute
|
|
131
140
|
*
|
|
@@ -834,7 +843,7 @@ Table.setMethod(function selectRow(row) {
|
|
|
834
843
|
*
|
|
835
844
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
836
845
|
* @since 0.1.0
|
|
837
|
-
* @version 0.1.
|
|
846
|
+
* @version 0.1.3
|
|
838
847
|
*/
|
|
839
848
|
Table.setMethod(function loadRemoteData() {
|
|
840
849
|
|
|
@@ -859,14 +868,24 @@ Table.setMethod(function loadRemoteData() {
|
|
|
859
868
|
body : body
|
|
860
869
|
};
|
|
861
870
|
|
|
871
|
+
let load_remote_id = ++this.load_remote_counter;
|
|
872
|
+
|
|
862
873
|
this.delayAssemble(async function() {
|
|
863
874
|
|
|
875
|
+
if (load_remote_id != that.load_remote_counter) {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
|
|
864
879
|
let result = await that.getResource(options);
|
|
865
880
|
|
|
866
881
|
if (!result) {
|
|
867
882
|
return;
|
|
868
883
|
}
|
|
869
884
|
|
|
885
|
+
if (load_remote_id != that.load_remote_counter) {
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
|
|
870
889
|
let records = result.records;
|
|
871
890
|
|
|
872
891
|
that.records = records;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The alchemy-number-input custom element
|
|
3
|
+
*
|
|
4
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
5
|
+
* @since 0.1.3
|
|
6
|
+
* @version 0.1.3
|
|
7
|
+
*/
|
|
8
|
+
var NumberInput = Function.inherits('Alchemy.Element.Form.FeedbackInput', 'NumberInput');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The hawkejs template to use
|
|
12
|
+
*
|
|
13
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
14
|
+
* @since 0.1.3
|
|
15
|
+
* @version 0.1.3
|
|
16
|
+
*/
|
|
17
|
+
NumberInput.setTemplateFile('form/elements/number_input');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The value property
|
|
21
|
+
*
|
|
22
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
23
|
+
* @since 0.1.3
|
|
24
|
+
* @version 0.1.3
|
|
25
|
+
*/
|
|
26
|
+
NumberInput.setProperty(function value() {
|
|
27
|
+
|
|
28
|
+
var input = this.input_el,
|
|
29
|
+
value = input.value;
|
|
30
|
+
|
|
31
|
+
if (value === '') {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return Number(value);
|
|
36
|
+
|
|
37
|
+
}, function setValue(value) {
|
|
38
|
+
|
|
39
|
+
var input = this.input_el;
|
|
40
|
+
|
|
41
|
+
if (value == null || value === '') {
|
|
42
|
+
input.value = '';
|
|
43
|
+
} else {
|
|
44
|
+
input.value = value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The disabled property
|
|
51
|
+
*
|
|
52
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
53
|
+
* @since 0.1.3
|
|
54
|
+
* @version 0.1.3
|
|
55
|
+
*/
|
|
56
|
+
NumberInput.setProperty(function disabled() {
|
|
57
|
+
return this.input_el.disabled;
|
|
58
|
+
}, function setDisabled(value) {
|
|
59
|
+
return this.input_el.disabled = value;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Added to the DOM for the first time
|
|
64
|
+
*
|
|
65
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
66
|
+
* @since 0.1.3
|
|
67
|
+
* @version 0.1.3
|
|
68
|
+
*/
|
|
69
|
+
NumberInput.setMethod(function introduced() {
|
|
70
|
+
|
|
71
|
+
var that = this,
|
|
72
|
+
minus = this.querySelector('.minus'),
|
|
73
|
+
plus = this.querySelector('.plus'),
|
|
74
|
+
input = this.querySelector('.input');
|
|
75
|
+
|
|
76
|
+
var accommodations_summary_element = this.accommodations_summary;
|
|
77
|
+
|
|
78
|
+
minus.addEventListener('click', function onMinus(e) {
|
|
79
|
+
e.preventDefault();
|
|
80
|
+
adjustValue(-1, that);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
plus.addEventListener('click', function onPlus(e) {
|
|
84
|
+
e.preventDefault();
|
|
85
|
+
adjustValue(+1, that);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
function adjustValue(change, obj) {
|
|
89
|
+
|
|
90
|
+
var max = Number(input.getAttribute('max')),
|
|
91
|
+
min = Number(input.getAttribute('min')),
|
|
92
|
+
val = Number(input.value) || 0;
|
|
93
|
+
|
|
94
|
+
val += change;
|
|
95
|
+
|
|
96
|
+
if (val > max) {
|
|
97
|
+
val = max;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (val < min) {
|
|
101
|
+
val = min;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
input.value = val;
|
|
105
|
+
}
|
|
106
|
+
});
|
package/element/string_input.js
CHANGED
|
@@ -3,11 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
5
5
|
* @since 0.1.0
|
|
6
|
-
* @version 0.1.
|
|
6
|
+
* @version 0.1.3
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
StringInput.super.call(this);
|
|
10
|
-
});
|
|
8
|
+
const StringInput = Function.inherits('Alchemy.Element.Form.FeedbackInput', 'StringInput');
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* The template to use for the content of this element
|
|
@@ -16,4 +14,334 @@ var StringInput = Function.inherits('Alchemy.Element.Form.FeedbackInput', functi
|
|
|
16
14
|
* @since 0.1.0
|
|
17
15
|
* @version 0.1.0
|
|
18
16
|
*/
|
|
19
|
-
StringInput.setTemplateFile('form/elements/string_input');
|
|
17
|
+
StringInput.setTemplateFile('form/elements/string_input');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The required attribute
|
|
21
|
+
*
|
|
22
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
23
|
+
* @since 0.1.3
|
|
24
|
+
* @version 0.1.3
|
|
25
|
+
*/
|
|
26
|
+
StringInput.setAttribute('required', {boolean: true});
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The required attribute
|
|
30
|
+
*
|
|
31
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
32
|
+
* @since 0.1.3
|
|
33
|
+
* @version 0.1.3
|
|
34
|
+
*/
|
|
35
|
+
StringInput.setAssignedProperty('validate');
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Revalidate the value
|
|
39
|
+
*
|
|
40
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
41
|
+
* @since 0.1.3
|
|
42
|
+
* @version 0.1.3
|
|
43
|
+
*
|
|
44
|
+
* @return {Object[]}
|
|
45
|
+
*/
|
|
46
|
+
StringInput.setMethod(function getValidationConfig() {
|
|
47
|
+
|
|
48
|
+
let result = [],
|
|
49
|
+
config = this.validate,
|
|
50
|
+
types;
|
|
51
|
+
|
|
52
|
+
if (config && typeof config == 'string') {
|
|
53
|
+
types = config;
|
|
54
|
+
config = null;
|
|
55
|
+
} else if (config && typeof config == 'object') {
|
|
56
|
+
config = Array.cast(config);
|
|
57
|
+
} else {
|
|
58
|
+
types = this.getAttribute('validate');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (types) {
|
|
62
|
+
types = types.split(',');
|
|
63
|
+
} else {
|
|
64
|
+
types = [];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Required always comes first if defined as an attribute
|
|
68
|
+
if (this.required) {
|
|
69
|
+
types.unshift('required');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (let type of types) {
|
|
73
|
+
if (type == 'email') {
|
|
74
|
+
result.push({
|
|
75
|
+
type : 'regex',
|
|
76
|
+
regex : /[a-zA-Z0-9_\.-]+@[a-zA-Z0-9_\.-]+\.[a-zA-Z]{2,}/,
|
|
77
|
+
message : 'microcopy:invalid-email',
|
|
78
|
+
when : 'onblur',
|
|
79
|
+
});
|
|
80
|
+
} else if (type == 'regex') {
|
|
81
|
+
result.push({
|
|
82
|
+
type : 'regex',
|
|
83
|
+
regex : RegExp.interpret(this.getAttribute('validate-regex')),
|
|
84
|
+
message : 'microcopy:invalid-pattern-match',
|
|
85
|
+
when : 'onblur',
|
|
86
|
+
});
|
|
87
|
+
} else if (type == 'remote') {
|
|
88
|
+
let route = this.getAttribute('validate-route'),
|
|
89
|
+
url = this.getAttribute('validate-url');
|
|
90
|
+
|
|
91
|
+
result.push({
|
|
92
|
+
type : 'remote',
|
|
93
|
+
route : route,
|
|
94
|
+
url : url,
|
|
95
|
+
message : 'microcopy:invalid-remote',
|
|
96
|
+
when : 'onblur',
|
|
97
|
+
});
|
|
98
|
+
} else if (type == 'required') {
|
|
99
|
+
result.push({
|
|
100
|
+
type : 'required',
|
|
101
|
+
message : 'microcopy:cannot-be-empty'
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let min_length = Number(this.getAttribute('min-length')) || 0;
|
|
107
|
+
|
|
108
|
+
if (min_length > 0) {
|
|
109
|
+
// Checking the minimum length only has to happen on blur
|
|
110
|
+
result.push({
|
|
111
|
+
type : 'min_length',
|
|
112
|
+
length : min_length,
|
|
113
|
+
message : 'microcopy:is-too-short',
|
|
114
|
+
when : 'onblur',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let max_length = Number(this.getAttribute('max-length')) || 0;
|
|
119
|
+
|
|
120
|
+
if (max_length > 0) {
|
|
121
|
+
// Checking maximum length has to happen immediately
|
|
122
|
+
result.push({
|
|
123
|
+
type : 'max_length',
|
|
124
|
+
length : max_length,
|
|
125
|
+
message : 'microcopy:is-too-long',
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (config) {
|
|
130
|
+
for (let entry of config) {
|
|
131
|
+
|
|
132
|
+
if (!entry.when) {
|
|
133
|
+
entry.when = 'onblur';
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
result.push(entry);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return result;
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Revalidate the value
|
|
145
|
+
*
|
|
146
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
147
|
+
* @since 0.1.3
|
|
148
|
+
* @version 0.1.3
|
|
149
|
+
*
|
|
150
|
+
* @param {Object} trigger The revalidation trigger
|
|
151
|
+
*/
|
|
152
|
+
StringInput.setMethod(async function revalidate(trigger, force) {
|
|
153
|
+
|
|
154
|
+
// Get the current value
|
|
155
|
+
let value = this.value;
|
|
156
|
+
|
|
157
|
+
if (value) {
|
|
158
|
+
value = value.trim();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Don't revalidate the same value twice
|
|
162
|
+
if (this.last_validated_value == value) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (this.success_el) {
|
|
167
|
+
this.success_el.innerHTML = '';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Get the validation counter (important for async validations)
|
|
171
|
+
let validation_counter = ++this.validation_counter;
|
|
172
|
+
|
|
173
|
+
let config = this.getValidationConfig(),
|
|
174
|
+
error_params,
|
|
175
|
+
check_count = 0,
|
|
176
|
+
skip_count = 0,
|
|
177
|
+
required;
|
|
178
|
+
|
|
179
|
+
if (config && config.length) {
|
|
180
|
+
|
|
181
|
+
required = config.findByPath('type', 'required');
|
|
182
|
+
|
|
183
|
+
for (let entry of config) {
|
|
184
|
+
|
|
185
|
+
if (!value.length && !required) {
|
|
186
|
+
skip_count++;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (entry.when) {
|
|
191
|
+
|
|
192
|
+
// Always check when it's being submitted
|
|
193
|
+
if (trigger != 'submit') {
|
|
194
|
+
if (entry.when == 'onblur' && (!trigger || trigger.type != 'blur')) {
|
|
195
|
+
skip_count++;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
check_count++;
|
|
202
|
+
|
|
203
|
+
if (entry.type == 'regex') {
|
|
204
|
+
if (!entry.regex.test(value)) {
|
|
205
|
+
error_params = [entry.message, null, true];
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
} else if (entry.type == 'min_length') {
|
|
209
|
+
if (value.length < entry.length) {
|
|
210
|
+
error_params = [entry.message, {
|
|
211
|
+
value_length: value.length,
|
|
212
|
+
min_length : entry.length,
|
|
213
|
+
}, true];
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
} else if (entry.type == 'max_length') {
|
|
217
|
+
if (value.length > entry.length) {
|
|
218
|
+
error_params = [entry.message, {
|
|
219
|
+
value_length : value.length,
|
|
220
|
+
max_length : entry.length,
|
|
221
|
+
}, true];
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
} else if (entry.type == 'remote') {
|
|
225
|
+
|
|
226
|
+
let url;
|
|
227
|
+
|
|
228
|
+
if (entry.url) {
|
|
229
|
+
url = Classes.RURL.parse(entry.url);
|
|
230
|
+
} else if (entry.route) {
|
|
231
|
+
url = hawkejs.scene.helpers.Router.routeUrl(entry.route);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if(!url) {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
url.param('value', value);
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
|
|
242
|
+
let result = await Blast.fetch(url);
|
|
243
|
+
|
|
244
|
+
if (result) {
|
|
245
|
+
if (!result.allowed) {
|
|
246
|
+
error_params = [result.message || entry.message, null, true];
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
} catch (err) {
|
|
251
|
+
error_params = [entry.message || err.message, null, true];
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Remove errors if not required and empty
|
|
259
|
+
if (!required && !value.length) {
|
|
260
|
+
this.removeErrors();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Make sure something was checked, otherwise exit early
|
|
264
|
+
if (!check_count) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (validation_counter != this.validation_counter) {
|
|
269
|
+
// Another validation happened while we were waiting for the result
|
|
270
|
+
if (!force) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (!skip_count) {
|
|
276
|
+
// Remember we validated this value (if all the checks were done)
|
|
277
|
+
this.last_validated_value = value;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (error_params) {
|
|
281
|
+
this.addError(...error_params);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Remove all errors when we got this far
|
|
286
|
+
this.removeErrors();
|
|
287
|
+
|
|
288
|
+
// Mark it as valid, but only if we checked all the checks
|
|
289
|
+
if (!skip_count) {
|
|
290
|
+
this.classList.add('valid');
|
|
291
|
+
this.inputbox_el.classList.add('valid');
|
|
292
|
+
|
|
293
|
+
let message = this.getAttribute('success-message');
|
|
294
|
+
|
|
295
|
+
if (message) {
|
|
296
|
+
this.addSuccess(message);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Actions to perform when this element
|
|
303
|
+
* has been added to the DOM for the first time
|
|
304
|
+
*
|
|
305
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
306
|
+
* @since 0.1.3
|
|
307
|
+
* @version 0.1.3
|
|
308
|
+
*/
|
|
309
|
+
StringInput.setMethod(function introduced() {
|
|
310
|
+
|
|
311
|
+
const that = this,
|
|
312
|
+
input = this.input_el;
|
|
313
|
+
|
|
314
|
+
if (this.readonly) {
|
|
315
|
+
input.disabled = true;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
let doRevalidate = Fn.throttle((e, force) => {
|
|
319
|
+
this.revalidate(e, force);
|
|
320
|
+
}, {
|
|
321
|
+
minimum_wait : 300,
|
|
322
|
+
immediate : false,
|
|
323
|
+
reset_on_call : true
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
input.addEventListener('focus', e => {
|
|
327
|
+
this.inputbox_el.classList.add('focus');
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
input.addEventListener('blur', e => {
|
|
331
|
+
this.inputbox_el.classList.remove('focus');
|
|
332
|
+
doRevalidate(e, true);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
input.addEventListener('keyup', function onKeyup(e) {
|
|
336
|
+
doRevalidate(e);
|
|
337
|
+
that.emit('changing');
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
input.addEventListener('input',function onInput(e) {
|
|
341
|
+
doRevalidate(e);
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
if (this.value) {
|
|
345
|
+
this.revalidate();
|
|
346
|
+
}
|
|
347
|
+
});
|
|
@@ -16,7 +16,7 @@ const AlchemyForm = Function.inherits('Alchemy.Widget', 'AlchemyForm');
|
|
|
16
16
|
*
|
|
17
17
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
18
18
|
* @since 0.1.0
|
|
19
|
-
* @version 0.1.
|
|
19
|
+
* @version 0.1.3
|
|
20
20
|
*/
|
|
21
21
|
AlchemyForm.setMethod(function populateWidget() {
|
|
22
22
|
|
|
@@ -49,6 +49,12 @@ AlchemyForm.setMethod(function populateWidget() {
|
|
|
49
49
|
form.append(col.widget);
|
|
50
50
|
|
|
51
51
|
this.element.append(form);
|
|
52
|
+
|
|
53
|
+
let violations = this.element.getContextVariable('form_violations');
|
|
54
|
+
|
|
55
|
+
if (violations) {
|
|
56
|
+
form.showError(violations);
|
|
57
|
+
}
|
|
52
58
|
});
|
|
53
59
|
|
|
54
60
|
/**
|
package/package.json
CHANGED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<label
|
|
2
|
+
for="nr_input_<% self.getAttribute('input-name') || '' %>"
|
|
3
|
+
>
|
|
4
|
+
<div class="inputlabel">
|
|
5
|
+
<span class="label" data-he-slot="label"></span>
|
|
6
|
+
<span class="description" data-he-slot="description"></span>
|
|
7
|
+
<hr class="spacer">
|
|
8
|
+
</div>
|
|
9
|
+
</label>
|
|
10
|
+
|
|
11
|
+
<div class="row">
|
|
12
|
+
|
|
13
|
+
<button
|
|
14
|
+
class="control minus"
|
|
15
|
+
tabindex="-1"
|
|
16
|
+
aria-hidden="true"
|
|
17
|
+
></button>
|
|
18
|
+
|
|
19
|
+
<input
|
|
20
|
+
class="input"
|
|
21
|
+
value="<% self.getAttribute('start') %>"
|
|
22
|
+
min="<% self.getAttribute('min') %>"
|
|
23
|
+
max="<% self.getAttribute('max') %>"
|
|
24
|
+
type="number"
|
|
25
|
+
id="nr_input_<% self.getAttribute('input-name') || '' %>"
|
|
26
|
+
name=<% self.getAttribute('input-name') || '' %>
|
|
27
|
+
|
|
28
|
+
<% if (self.hasAttribute('disabled')) print('disabled="disabled"'); %>
|
|
29
|
+
>
|
|
30
|
+
|
|
31
|
+
<button
|
|
32
|
+
class="control plus"
|
|
33
|
+
tabindex="-1"
|
|
34
|
+
aria-hidden="true"
|
|
35
|
+
></button>
|
|
36
|
+
</div>
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
<%
|
|
2
|
+
|
|
2
3
|
if (value) {
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
// Make sure it's a date
|
|
6
|
+
value = Date.create(value);
|
|
7
|
+
|
|
8
|
+
// According to MDN `toISOString()` should work,
|
|
9
|
+
// but neither Chrome or Firefox allow that format (it still contains timezone info)
|
|
10
|
+
value = value.format('Y-m-d\\TH:i:s');
|
|
4
11
|
}
|
|
5
12
|
%>
|
|
6
13
|
<input
|