alchemy-form 0.1.2 → 0.1.5

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
  *
@@ -77,9 +84,24 @@ Field.setAssignedProperty('widget_settings');
77
84
  *
78
85
  * @author Jelle De Loecker <jelle@elevenways.be>
79
86
  * @since 0.1.0
80
- * @version 0.1.0
87
+ * @version 0.1.4
81
88
  */
82
- 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
+ });
83
105
 
84
106
  /**
85
107
  * Get the error area
@@ -111,7 +133,7 @@ Field.enforceProperty(function alchemy_field_schema(new_value, old_value) {
111
133
  *
112
134
  * @author Jelle De Loecker <jelle@elevenways.be>
113
135
  * @since 0.1.0
114
- * @version 0.1.0
136
+ * @version 0.1.4
115
137
  */
116
138
  Field.enforceProperty(function config(new_value, old_value) {
117
139
 
@@ -124,6 +146,12 @@ Field.enforceProperty(function config(new_value, old_value) {
124
146
  }
125
147
  }
126
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
+
127
155
  return new_value;
128
156
  });
129
157
 
@@ -187,6 +215,24 @@ Field.setProperty(function is_array() {
187
215
  return false;
188
216
  });
189
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
+
190
236
  /**
191
237
  * Is this a translatable field?
192
238
  *
@@ -247,6 +293,35 @@ Field.setProperty(function field_description() {
247
293
  return result;
248
294
  });
249
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
+
250
325
  /**
251
326
  * Get the name of the model this field belongs to
252
327
  *
@@ -418,17 +493,20 @@ Field.setProperty(function wrapper_files() {
418
493
  *
419
494
  * @author Jelle De Loecker <jelle@elevenways.be>
420
495
  * @since 0.1.0
421
- * @version 0.1.0
496
+ * @version 0.1.4
422
497
  */
423
498
  Field.setProperty(function original_value() {
424
499
 
425
- 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;
426
502
 
427
503
  if (alchemy_field_schema) {
428
504
  let original_schema_value = alchemy_field_schema.original_value;
429
505
 
430
506
  if (original_schema_value) {
431
- return original_schema_value[this.field_name];
507
+ if (path) {
508
+ return Object.path(original_schema_value, path);
509
+ }
432
510
  }
433
511
 
434
512
  return;
@@ -437,9 +515,8 @@ Field.setProperty(function original_value() {
437
515
  let form = this.alchemy_form;
438
516
 
439
517
  if (form && form.document) {
440
- return form.document[this.field_name];
518
+ return Object.path(form.document, path);
441
519
  }
442
-
443
520
  });
444
521
 
445
522
  /**
@@ -447,7 +524,7 @@ Field.setProperty(function original_value() {
447
524
  *
448
525
  * @author Jelle De Loecker <jelle@elevenways.be>
449
526
  * @since 0.1.0
450
- * @version 0.1.0
527
+ * @version 0.1.4
451
528
  */
452
529
  Field.setProperty(function value_element() {
453
530
 
@@ -458,7 +535,11 @@ Field.setProperty(function value_element() {
458
535
  input = this.querySelector('alchemy-field-translatable');
459
536
  } else if (this.is_array) {
460
537
  input = this.querySelector('alchemy-field-array');
461
- } else {
538
+ } else if (this.contains_schema) {
539
+ input = this.querySelector('alchemy-field-schema');
540
+ }
541
+
542
+ if (!input) {
462
543
  input = this.querySelector('.alchemy-field-value');
463
544
  }
464
545
 
@@ -470,7 +551,7 @@ Field.setProperty(function value_element() {
470
551
  *
471
552
  * @author Jelle De Loecker <jelle@elevenways.be>
472
553
  * @since 0.1.0
473
- * @version 0.1.0
554
+ * @version 0.1.3
474
555
  */
475
556
  Field.setProperty(function value() {
476
557
 
@@ -478,6 +559,8 @@ Field.setProperty(function value() {
478
559
 
479
560
  if (element) {
480
561
  return element.value;
562
+ } else {
563
+ return this.original_value;
481
564
  }
482
565
 
483
566
  }, function setValue(value) {
@@ -593,7 +676,7 @@ Field.setMethod(function removeErrors() {
593
676
  *
594
677
  * @author Jelle De Loecker <jelle@elevenways.be>
595
678
  * @since 0.1.0
596
- * @version 0.1.0
679
+ * @version 0.1.3
597
680
  */
598
681
  Field.setMethod(function retained() {
599
682
 
@@ -607,15 +690,15 @@ Field.setMethod(function retained() {
607
690
  id += this.field_name.slug();
608
691
 
609
692
  this.id = id;
693
+ }
610
694
 
611
- let label = this.querySelector('.form-field-info alchemy-label');
695
+ let label = this.querySelector('.form-field-info alchemy-label');
612
696
 
613
- if (label && this.value_element) {
614
- let v_id = id + '_fv';
697
+ if (label && this.value_element) {
698
+ let v_id = this.id + '_fv';
615
699
 
616
- label.setAttribute('for', v_id);
617
- this.value_element.setAttribute('id', v_id);
618
- }
700
+ label.setAttribute('for', v_id);
701
+ this.value_element.setAttribute('id', v_id);
619
702
  }
620
703
 
621
704
  });