alchemy-form 0.1.1 → 0.1.4

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.
@@ -123,4 +123,174 @@ Base.setProperty(function wrapper_type() {
123
123
  this.setAttribute('wrapper-type', value);
124
124
  }
125
125
 
126
+ });
127
+
128
+ /**
129
+ * Get the path of this field value in the current (sub)schema
130
+ *
131
+ * @author Jelle De Loecker <jelle@elevenways.be>
132
+ * @since 0.1.4
133
+ * @version 0.1.4
134
+ */
135
+ Base.setProperty(function field_path_in_current_schema() {
136
+
137
+ let result = [],
138
+ parent = this.getParentField(),
139
+ name;
140
+
141
+ name = this.getPathEntryName();
142
+
143
+ if (name) {
144
+ result.push(name);
145
+ }
146
+
147
+ while (parent && !(parent instanceof Classes.Alchemy.Element.Form.FieldSchema)) {
148
+ name = parent.getPathEntryName();
149
+
150
+ if (name) {
151
+ result.unshift(name);
152
+ }
153
+
154
+ parent = parent.getParentField();
155
+ }
156
+
157
+ return result.join('.');
158
+ });
159
+
160
+ /**
161
+ * Get the path of this field value in the current record
162
+ *
163
+ * @author Jelle De Loecker <jelle@elevenways.be>
164
+ * @since 0.1.3
165
+ * @version 0.1.3
166
+ */
167
+ Base.setProperty(function field_path_in_record() {
168
+
169
+ let result = [],
170
+ parent = this.getParentField(),
171
+ name;
172
+
173
+ name = this.getPathEntryName();
174
+
175
+ if (name) {
176
+ result.push(name);
177
+ }
178
+
179
+ while (parent) {
180
+ name = parent.getPathEntryName();
181
+
182
+ if (name) {
183
+ result.unshift(name);
184
+ }
185
+
186
+ parent = parent.getParentField();
187
+ }
188
+
189
+ return result.join('.');
190
+ });
191
+
192
+ /**
193
+ * Get the parent field/field-entry element
194
+ *
195
+ * @author Jelle De Loecker <jelle@elevenways.be>
196
+ * @since 0.1.3
197
+ * @version 0.1.4
198
+ *
199
+ * @return {Alchemy.Element.Form.Base}
200
+ */
201
+ Base.setMethod(function getParentField() {
202
+
203
+ let parent = this.parentElement;
204
+
205
+ while (parent) {
206
+
207
+ if (parent instanceof Classes.Alchemy.Element.Form.Base) {
208
+ return parent;
209
+ }
210
+
211
+ parent = parent.parentElement;
212
+ }
213
+
214
+ if (this.field_context) {
215
+ return this.field_context;
216
+ }
217
+
218
+ return false;
219
+ });
220
+
221
+ /**
222
+ * Get the name of this thing in a record path
223
+ *
224
+ * @author Jelle De Loecker <jelle@elevenways.be>
225
+ * @since 0.1.3
226
+ * @version 0.1.3
227
+ *
228
+ * @return {String}
229
+ */
230
+ Base.setMethod(function getPathEntryName() {
231
+ return '';
232
+ });
233
+
234
+ /**
235
+ * Get this entry's path origin
236
+ * (The path to the container it's in)
237
+ *
238
+ * @author Jelle De Loecker <jelle@elevenways.be>
239
+ * @since 0.1.3
240
+ * @version 0.1.3
241
+ *
242
+ * @return {String}
243
+ */
244
+ Base.setMethod(function getPathOrigin() {
245
+
246
+ let current = this,
247
+ origin;
248
+
249
+ while (current) {
250
+ origin = current.field_path_in_record;
251
+
252
+ if (origin) {
253
+ return origin;
254
+ }
255
+
256
+ current = current.getParentField();
257
+ }
258
+ });
259
+
260
+ /**
261
+ * Resolve the given path
262
+ *
263
+ * @author Jelle De Loecker <jelle@elevenways.be>
264
+ * @since 0.1.3
265
+ * @version 0.1.3
266
+ *
267
+ * @param {String} name The name to resolve
268
+ * @param {String} origin The origin to use (optional)
269
+ *
270
+ * @return {String}
271
+ */
272
+ Base.setMethod(function resolvePath(name, origin) {
273
+
274
+ if (origin == null) {
275
+ origin = this.getPathOrigin();
276
+ }
277
+
278
+ if (!origin) {
279
+ return name;
280
+ }
281
+
282
+ if (!Array.isArray(origin)) {
283
+ origin = origin.split('.');
284
+ } else {
285
+ origin = origin.slice(0);
286
+ }
287
+
288
+ if (!origin.length) {
289
+ return name;
290
+ }
291
+
292
+ origin.pop();
293
+ origin.push(name);
294
+
295
+ return origin.join('.');
126
296
  });
@@ -7,9 +7,7 @@ const VALUE = Symbol('value');
7
7
  * @since 0.1.0
8
8
  * @version 0.1.0
9
9
  */
10
- var FeedbackInput = Function.inherits('Alchemy.Element.Form', function FeedbackInput() {
11
- FeedbackInput.super.call(this);
12
- });
10
+ var FeedbackInput = Function.inherits('Alchemy.Element.Form.Base', 'FeedbackInput');
13
11
 
14
12
  /**
15
13
  * Don't register this as a custom element
@@ -20,6 +18,99 @@ var FeedbackInput = Function.inherits('Alchemy.Element.Form', function FeedbackI
20
18
  */
21
19
  FeedbackInput.setStatic('is_abstract_class', true, false);
22
20
 
21
+ /**
22
+ * The stylesheet to load for this element
23
+ *
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
25
+ * @since 0.1.3
26
+ * @version 0.1.3
27
+ */
28
+ FeedbackInput.setStylesheetFile('form/alchemy_feedback_input');
29
+
30
+ /**
31
+ * The readonly attribute
32
+ *
33
+ * @author Jelle De Loecker <jelle@elevenways.be>
34
+ * @since 0.1.3
35
+ * @version 0.1.3
36
+ */
37
+ FeedbackInput.setAttribute('readonly', {boolean: true});
38
+
39
+ /**
40
+ * Reference to the errors element
41
+ *
42
+ * @author Jelle De Loecker <jelle@elevenways.be>
43
+ * @since 0.1.3
44
+ * @version 0.1.3
45
+ */
46
+ FeedbackInput.addElementGetter('errors_el', '.errors');
47
+
48
+ /**
49
+ * Reference to the success element
50
+ *
51
+ * @author Jelle De Loecker <jelle@elevenways.be>
52
+ * @since 0.1.3
53
+ * @version 0.1.3
54
+ */
55
+ FeedbackInput.addElementGetter('success_el', '.success');
56
+
57
+ /**
58
+ * Reference to the inputbox element
59
+ *
60
+ * @author Jelle De Loecker <jelle@elevenways.be>
61
+ * @since 0.1.3
62
+ * @version 0.1.3
63
+ */
64
+ FeedbackInput.addElementGetter('inputbox_el', '.inputbox');
65
+
66
+ /**
67
+ * Reference to the input element
68
+ *
69
+ * @author Jelle De Loecker <jelle@elevenways.be>
70
+ * @since 0.1.3
71
+ * @version 0.1.3
72
+ */
73
+ FeedbackInput.addElementGetter('input_el', '.input');
74
+
75
+ /**
76
+ * The last validated value
77
+ *
78
+ * @author Jelle De Loecker <jelle@elevenways.be>
79
+ * @since 0.1.3
80
+ * @version 0.1.3
81
+ */
82
+ FeedbackInput.setProperty('last_validated_value', null);
83
+
84
+ /**
85
+ * The validation counter
86
+ *
87
+ * @author Jelle De Loecker <jelle@elevenways.be>
88
+ * @since 0.1.3
89
+ * @version 0.1.3
90
+ */
91
+ FeedbackInput.setProperty('validation_counter', 0);
92
+
93
+ /**
94
+ * Was this input valid after the last revalidation?
95
+ *
96
+ * @author Jelle De Loecker <jelle@elevenways.be>
97
+ * @since 0.1.3
98
+ * @version 0.1.3
99
+ */
100
+ FeedbackInput.setProperty(function is_valid() {
101
+
102
+ if (this.classList.contains('error')) {
103
+ return false;
104
+ }
105
+
106
+ if (this.classList.contains('valid')) {
107
+ return true;
108
+ }
109
+
110
+ // Default to true
111
+ return true;
112
+ });
113
+
23
114
  /**
24
115
  * The value property
25
116
  *
@@ -57,3 +148,171 @@ FeedbackInput.setProperty(function value() {
57
148
 
58
149
  this[VALUE] = value;
59
150
  });
151
+
152
+ /**
153
+ * Remove all errors
154
+ *
155
+ * @author Jelle De Loecker <jelle@elevenways.be>
156
+ * @since 0.1.3
157
+ * @version 0.1.3
158
+ */
159
+ FeedbackInput.setMethod(function removeErrors() {
160
+ this.classList.remove('valid');
161
+ this.classList.remove('error');
162
+ this.inputbox_el.classList.remove('valid');
163
+ this.inputbox_el.classList.remove('error');
164
+ Hawkejs.removeChildren(this.errors_el);
165
+ Hawkejs.removeChildren(this.success_el);
166
+ });
167
+
168
+ /**
169
+ * Get a message stirng or a microcopy object
170
+ *
171
+ * @author Jelle De Loecker <jelle@elevenways.be>
172
+ * @since 0.1.3
173
+ * @version 0.1.3
174
+ *
175
+ * @return {<micro-copy>|String}
176
+ */
177
+ FeedbackInput.setMethod(function convertMessage(message, parameters) {
178
+
179
+ if (!message) {
180
+ return '';
181
+ }
182
+
183
+ let microcopy;
184
+
185
+ if (typeof message == 'string') {
186
+ if (!message.startsWith('microcopy:')) {
187
+ return message;
188
+ }
189
+
190
+ microcopy = this.createElement('micro-copy');
191
+ microcopy.key = message.after('microcopy:');
192
+
193
+ if (!parameters) {
194
+ parameters = {};
195
+ }
196
+
197
+ microcopy.parameters = parameters;
198
+ } else if (typeof message == 'object') {
199
+
200
+ if (message instanceof Classes.Alchemy.Microcopy) {
201
+ microcopy = message.toElement();
202
+ } else {
203
+ microcopy = message;
204
+ }
205
+
206
+ if (parameters) {
207
+ microcopy.parameters = parameters;
208
+ } else {
209
+ parameters = microcopy.parameters;
210
+ }
211
+
212
+ if (!parameters) {
213
+ microcopy.parameters = parameters = {};
214
+ }
215
+ }
216
+
217
+ if (!parameters.field) {
218
+ parameters.field = this.getAttribute('input-name');
219
+ }
220
+
221
+ let friendly = this.dataset.friendly;
222
+
223
+ if (!friendly) {
224
+ let label = this.querySelector('[slot="label"]');
225
+
226
+ if (label) {
227
+ friendly = label.textContent;
228
+ }
229
+ }
230
+
231
+ if (friendly) {
232
+ parameters.field = friendly;
233
+ }
234
+
235
+ return microcopy;
236
+ });
237
+
238
+ /**
239
+ * Add an error
240
+ *
241
+ * @author Jelle De Loecker <jelle@elevenways.be>
242
+ * @since 0.1.3
243
+ * @version 0.1.3
244
+ */
245
+ FeedbackInput.setMethod(function addError(message, parameters, clear_first, add_friendly) {
246
+
247
+ var p = this.createElement('p'),
248
+ i = this.createElement('i'),
249
+ span = this.createElement('span'),
250
+ friendly = this.dataset.friendly,
251
+ strong = this.createElement('strong');
252
+
253
+ if (typeof parameters == 'boolean') {
254
+ add_friendly = clear_first;
255
+ clear_first = parameters;
256
+ parameters = null;
257
+ }
258
+
259
+ if (clear_first) {
260
+ this.removeErrors();
261
+ }
262
+
263
+ p.classList.add('errorlabel');
264
+ i.classList.add('erroricon');
265
+ span.classList.add('text');
266
+
267
+ p.append(i);
268
+ p.append(span);
269
+
270
+ // Try getting a microcopy
271
+ message = this.convertMessage(message, parameters);
272
+
273
+ strong.append(message);
274
+ span.append(strong);
275
+
276
+ this.errors_el.append(p);
277
+
278
+ if (this.external_element) {
279
+ this.external_element.disabled = true;
280
+ }
281
+
282
+ if (this.show_element) {
283
+ this.show_element.hidden = true;
284
+ }
285
+
286
+ this.classList.add('error');
287
+ this.inputbox_el.classList.add('error');
288
+
289
+ if (this.activate_el) {
290
+ this.activate_el.classList.remove(this.activate_class);
291
+ }
292
+ });
293
+
294
+ /**
295
+ * Add a success message
296
+ *
297
+ * @author Jelle De Loecker <jelle@elevenways.be>
298
+ * @since 0.1.3
299
+ * @version 0.1.3
300
+ */
301
+ FeedbackInput.setMethod(function addSuccess(message, parameters, clear_first, add_friendly) {
302
+
303
+ var p = this.createElement('p');
304
+
305
+ message = this.convertMessage(message, parameters);
306
+
307
+ p.classList.add('successlabel');
308
+ p.append(message);
309
+
310
+ this.success_el.append(p);
311
+
312
+ this.classList.add('valid');
313
+ this.inputbox_el.classList.add('valid');
314
+
315
+ if (this.activate_el) {
316
+ this.activate_el.classList.add(this.activate_class);
317
+ }
318
+ });
@@ -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.0
6
+ * @version 0.1.4
7
7
  */
8
- var Field = Function.inherits('Alchemy.Element.Form.Base', function Field() {
9
- Field.super.call(this);
10
- });
8
+ const Field = Function.inherits('Alchemy.Element.Form.Base', 'Field');
11
9
 
12
10
  /**
13
11
  * The template to use for the content of this element
@@ -45,6 +43,15 @@ Field.setStatic('use_new_renderer_scope', true);
45
43
  */
46
44
  Field.setAttribute('field-name');
47
45
 
46
+ /**
47
+ * The type of the field
48
+ *
49
+ * @author Jelle De Loecker <jelle@elevenways.be>
50
+ * @since 0.1.4
51
+ * @version 0.1.4
52
+ */
53
+ Field.setAttribute('field-type');
54
+
48
55
  /**
49
56
  * The view override
50
57
  *
@@ -54,14 +61,47 @@ Field.setAttribute('field-name');
54
61
  */
55
62
  Field.setAttribute('field-view');
56
63
 
64
+ /**
65
+ * Is this a read only field?
66
+ *
67
+ * @author Jelle De Loecker <jelle@elevenways.be>
68
+ * @since 0.1.2
69
+ * @version 0.1.2
70
+ */
71
+ Field.setAttribute('readonly', {boolean: true});
72
+
73
+ /**
74
+ * Widget settings for use in the views
75
+ *
76
+ * @author Jelle De Loecker <jelle@elevenways.be>
77
+ * @since 0.1.2
78
+ * @version 0.1.2
79
+ */
80
+ Field.setAssignedProperty('widget_settings');
81
+
57
82
  /**
58
83
  * Get the parent alchemy-form element
59
84
  *
60
85
  * @author Jelle De Loecker <jelle@elevenways.be>
61
86
  * @since 0.1.0
62
- * @version 0.1.0
87
+ * @version 0.1.4
63
88
  */
64
- Field.addParentTypeGetter('alchemy_form', 'alchemy-form');
89
+ Field.enforceProperty(function alchemy_form(new_value) {
90
+
91
+ if (new_value == null) {
92
+ new_value = this.queryUp('alchemy-form');
93
+
94
+ if (!new_value && this.field_context) {
95
+ new_value = this.field_context.queryUp('alchemy-form');
96
+ }
97
+
98
+ if (!new_value && this.alchemy_field_schema && this.alchemy_field_schema.alchemy_field) {
99
+ new_value = this.alchemy_field_schema.alchemy_field.alchemy_form;
100
+ }
101
+ }
102
+
103
+ return new_value;
104
+ });
65
105
 
66
106
  /**
67
107
  * Get the error area
@@ -93,7 +133,7 @@ Field.enforceProperty(function alchemy_field_schema(new_value, old_value) {
93
133
  *
94
134
  * @author Jelle De Loecker <jelle@elevenways.be>
95
135
  * @since 0.1.0
96
- * @version 0.1.0
136
+ * @version 0.1.4
97
137
  */
98
138
  Field.enforceProperty(function config(new_value, old_value) {
99
139
 
@@ -106,6 +146,12 @@ Field.enforceProperty(function config(new_value, old_value) {
106
146
  }
107
147
  }
108
148
 
149
+ if (new_value && new_value.constructor && new_value.constructor.type_name) {
150
+ this.field_type = new_value.constructor.type_name;
151
+ } else {
152
+ this.field_type = null;
153
+ }
154
+
109
155
  return new_value;
110
156
  });
111
157
 
@@ -169,6 +215,24 @@ Field.setProperty(function is_array() {
169
215
  return false;
170
216
  });
171
217
 
218
+ /**
219
+ * Is this a schema field?
220
+ *
221
+ * @author Jelle De Loecker <jelle@elevenways.be>
222
+ * @since 0.1.3
223
+ * @version 0.1.3
224
+ */
225
+ Field.setProperty(function contains_schema() {
226
+
227
+ let config = this.config;
228
+
229
+ if (config) {
230
+ return config instanceof Classes.Alchemy.Field.Schema;
231
+ }
232
+
233
+ return false;
234
+ });
235
+
172
236
  /**
173
237
  * Is this a translatable field?
174
238
  *
@@ -229,6 +293,35 @@ Field.setProperty(function field_description() {
229
293
  return result;
230
294
  });
231
295
 
296
+ /**
297
+ * Get the path of this field in the schema
298
+ *
299
+ * @author Jelle De Loecker <jelle@elevenways.be>
300
+ * @since 0.1.3
301
+ * @version 0.1.3
302
+ */
303
+ Field.setProperty(function field_path_in_schema() {
304
+ return this.config && this.config.getPath();
305
+ });
306
+
307
+ /**
308
+ * Get the name of this entry for use in a record path
309
+ *
310
+ * @author Jelle De Loecker <jelle@elevenways.be>
311
+ * @since 0.1.3
312
+ * @version 0.1.3
313
+ *
314
+ * @return {String}
315
+ */
316
+ Field.setMethod(function getPathEntryName() {
317
+
318
+ if (this.config && this.config.name) {
319
+ return this.config.name;
320
+ }
321
+
322
+ return '';
323
+ });
324
+
232
325
  /**
233
326
  * Get the name of the model this field belongs to
234
327
  *
@@ -400,17 +493,20 @@ Field.setProperty(function wrapper_files() {
400
493
  *
401
494
  * @author Jelle De Loecker <jelle@elevenways.be>
402
495
  * @since 0.1.0
403
- * @version 0.1.0
496
+ * @version 0.1.4
404
497
  */
405
498
  Field.setProperty(function original_value() {
406
499
 
407
- let alchemy_field_schema = this.alchemy_field_schema;
500
+ let alchemy_field_schema = this.alchemy_field_schema,
501
+ path = this.field_path_in_current_schema;
408
502
 
409
503
  if (alchemy_field_schema) {
410
504
  let original_schema_value = alchemy_field_schema.original_value;
411
505
 
412
506
  if (original_schema_value) {
413
- return original_schema_value[this.field_name];
507
+ if (path) {
508
+ return Object.path(original_schema_value, path);
509
+ }
414
510
  }
415
511
 
416
512
  return;
@@ -419,9 +515,8 @@ Field.setProperty(function original_value() {
419
515
  let form = this.alchemy_form;
420
516
 
421
517
  if (form && form.document) {
422
- return form.document[this.field_name];
518
+ return Object.path(form.document, path);
423
519
  }
424
-
425
520
  });
426
521
 
427
522
  /**
@@ -429,7 +524,7 @@ Field.setProperty(function original_value() {
429
524
  *
430
525
  * @author Jelle De Loecker <jelle@elevenways.be>
431
526
  * @since 0.1.0
432
- * @version 0.1.0
527
+ * @version 0.1.4
433
528
  */
434
529
  Field.setProperty(function value_element() {
435
530
 
@@ -440,7 +535,11 @@ Field.setProperty(function value_element() {
440
535
  input = this.querySelector('alchemy-field-translatable');
441
536
  } else if (this.is_array) {
442
537
  input = this.querySelector('alchemy-field-array');
443
- } else {
538
+ } else if (this.contains_schema) {
539
+ input = this.querySelector('alchemy-field-schema');
540
+ }
541
+
542
+ if (!input) {
444
543
  input = this.querySelector('.alchemy-field-value');
445
544
  }
446
545
 
@@ -452,7 +551,7 @@ Field.setProperty(function value_element() {
452
551
  *
453
552
  * @author Jelle De Loecker <jelle@elevenways.be>
454
553
  * @since 0.1.0
455
- * @version 0.1.0
554
+ * @version 0.1.3
456
555
  */
457
556
  Field.setProperty(function value() {
458
557
 
@@ -460,6 +559,8 @@ Field.setProperty(function value() {
460
559
 
461
560
  if (element) {
462
561
  return element.value;
562
+ } else {
563
+ return this.original_value;
463
564
  }
464
565
 
465
566
  }, function setValue(value) {
@@ -575,7 +676,7 @@ Field.setMethod(function removeErrors() {
575
676
  *
576
677
  * @author Jelle De Loecker <jelle@elevenways.be>
577
678
  * @since 0.1.0
578
- * @version 0.1.0
679
+ * @version 0.1.3
579
680
  */
580
681
  Field.setMethod(function retained() {
581
682
 
@@ -589,15 +690,15 @@ Field.setMethod(function retained() {
589
690
  id += this.field_name.slug();
590
691
 
591
692
  this.id = id;
693
+ }
592
694
 
593
- let label = this.querySelector('.form-field-info alchemy-label');
695
+ let label = this.querySelector('.form-field-info alchemy-label');
594
696
 
595
- if (label && this.value_element) {
596
- let v_id = id + '_fv';
697
+ if (label && this.value_element) {
698
+ let v_id = this.id + '_fv';
597
699
 
598
- label.setAttribute('for', v_id);
599
- this.value_element.setAttribute('id', v_id);
600
- }
700
+ label.setAttribute('for', v_id);
701
+ this.value_element.setAttribute('id', v_id);
601
702
  }
602
703
 
603
704
  });