alchemy-form 0.1.4 → 0.1.7

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/assets/stylesheets/form/alchemy_field_array.scss +4 -0
  3. package/assets/stylesheets/form/alchemy_toggle.scss +2 -0
  4. package/assets/stylesheets/form/query_builder.scss +185 -0
  5. package/config/routes.js +8 -0
  6. package/controller/form_api_controller.js +51 -2
  7. package/element/20_query_builder_base.js +82 -0
  8. package/element/25_query_builder_data.js +139 -0
  9. package/element/alchemy_field.js +19 -2
  10. package/element/alchemy_select.js +40 -2
  11. package/element/alchemy_select_item.js +42 -1
  12. package/element/alchemy_table.js +123 -21
  13. package/element/query_builder.js +90 -0
  14. package/element/query_builder_entry.js +388 -0
  15. package/element/query_builder_group.js +248 -0
  16. package/element/query_builder_value.js +316 -0
  17. package/element/query_builder_variable.js +103 -0
  18. package/helper/form_actions/00_form_action.js +328 -0
  19. package/helper/form_actions/url_action.js +69 -0
  20. package/helper/query_builder_variable_definition/00_variable_definition.js +371 -0
  21. package/helper/query_builder_variable_definition/boolean_variable_definition.js +24 -0
  22. package/helper/query_builder_variable_definition/list_variable_definition.js +38 -0
  23. package/helper/query_builder_variable_definition/number_variable_definition.js +106 -0
  24. package/helper/query_builder_variable_definition/string_variable_definition.js +46 -0
  25. package/helper_field/query_builder_assignment.js +11 -0
  26. package/helper_field/query_builder_field.js +91 -0
  27. package/helper_field/query_builder_value.js +56 -0
  28. package/helper_field/query_builder_variable.js +56 -0
  29. package/package.json +1 -1
  30. package/view/form/elements/alchemy_field_array.hwk +3 -1
  31. package/view/form/elements/alchemy_field_array_entry.hwk +3 -1
  32. package/view/form/elements/alchemy_select_item.hwk +6 -1
  33. package/view/form/elements/query_builder.hwk +1 -0
  34. package/view/form/elements/query_builder_entry.hwk +33 -0
  35. package/view/form/elements/query_builder_group.hwk +64 -0
  36. package/view/form/elements/query_builder_value.hwk +10 -0
  37. package/view/form/elements/query_builder_variable.hwk +6 -0
  38. package/view/form/inputs/edit/query_builder.hwk +5 -0
  39. package/view/form/inputs/edit/query_builder_assignment.hwk +6 -0
  40. package/view/form/inputs/edit/query_builder_value.hwk +11 -0
  41. package/view/form/inputs/edit/query_builder_variable.hwk +10 -0
  42. package/view/form/select/qb_item.hwk +7 -0
@@ -0,0 +1,371 @@
1
+ /**
2
+ * ValueType
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 0.1.6
8
+ * @version 0.1.6
9
+ *
10
+ * @param {Object} config
11
+ */
12
+ const VariableDefinition = Function.inherits('Alchemy.Base', 'Alchemy.QueryBuilder.VariableDefinition', function VariableDefinition(config) {
13
+ this.applyConfig(config);
14
+ });
15
+
16
+ /**
17
+ * Make this an abtract class
18
+ */
19
+ VariableDefinition.makeAbstractClass();
20
+
21
+ /**
22
+ * This class starts a new group
23
+ */
24
+ VariableDefinition.startNewGroup('qb_variable_definitions');
25
+
26
+ /**
27
+ * The machine-readable name of the variable
28
+ *
29
+ * @author Jelle De Loecker <jelle@elevenways.be>
30
+ * @since 0.1.6
31
+ * @version 0.1.6
32
+ */
33
+ VariableDefinition.setProperty('name');
34
+
35
+ /**
36
+ * The human-readable title of the variable
37
+ *
38
+ * @author Jelle De Loecker <jelle@elevenways.be>
39
+ * @since 0.1.6
40
+ * @version 0.1.6
41
+ */
42
+ VariableDefinition.setProperty('title');
43
+
44
+ /**
45
+ * The description of the variable
46
+ *
47
+ * @author Jelle De Loecker <jelle@elevenways.be>
48
+ * @since 0.1.6
49
+ * @version 0.1.6
50
+ */
51
+ VariableDefinition.setProperty('description');
52
+
53
+ /**
54
+ * Is this variable readonly? (Mainly used for assignments)
55
+ *
56
+ * @author Jelle De Loecker <jelle@elevenways.be>
57
+ * @since 0.1.6
58
+ * @version 0.1.6
59
+ */
60
+ VariableDefinition.setProperty('readonly', false);
61
+
62
+ /**
63
+ * The flags of this variable
64
+ *
65
+ * @author Jelle De Loecker <jelle@elevenways.be>
66
+ * @since 0.1.6
67
+ * @version 0.1.6
68
+ */
69
+ VariableDefinition.setProperty('flags');
70
+
71
+ /**
72
+ * Get the type_name from the constructor
73
+ *
74
+ * @author Jelle De Loecker <jelle@elevenways.be>
75
+ * @since 0.1.6
76
+ * @version 0.1.6
77
+ */
78
+ VariableDefinition.setProperty(function type_name() {
79
+ return this.constructor.type_name;
80
+ });
81
+
82
+ /**
83
+ * The `id` property just refers to the `name`
84
+ *
85
+ * @author Jelle De Loecker <jelle@elevenways.be>
86
+ * @since 0.1.6
87
+ * @version 0.1.6
88
+ */
89
+ VariableDefinition.setProperty(function id() {
90
+ return this.name;
91
+ });
92
+
93
+ /**
94
+ * Make sure this definition has operators
95
+ *
96
+ * @author Jelle De Loecker <jelle@elevenways.be>
97
+ * @since 0.1.6
98
+ * @version 0.1.6
99
+ */
100
+ VariableDefinition.constitute(function prepareOperators() {
101
+ this.logical_operators = {};
102
+ this.assignment_operators = {};
103
+ });
104
+
105
+ /**
106
+ * Create the correct variable definition
107
+ *
108
+ * @author Jelle De Loecker <jelle@elevenways.be>
109
+ * @since 0.1.6
110
+ * @version 0.1.6
111
+ */
112
+ VariableDefinition.setStatic(function cast(entry) {
113
+
114
+ if (!entry) {
115
+ return null;
116
+ }
117
+
118
+ if (entry instanceof VariableDefinition) {
119
+ return entry;
120
+ }
121
+
122
+ if (!entry.type) {
123
+ return null;
124
+ }
125
+
126
+ let constructor = VariableDefinition.getMember(entry.type);
127
+
128
+ if (!constructor) {
129
+ return null;
130
+ }
131
+
132
+ let result = new constructor(entry);
133
+
134
+ return result;
135
+ });
136
+
137
+ /**
138
+ * Add a logical operator
139
+ *
140
+ * @author Jelle De Loecker <jelle@elevenways.be>
141
+ * @since 0.1.6
142
+ * @version 0.1.6
143
+ *
144
+ * @param {String} name
145
+ * @param {Object} config
146
+ */
147
+ VariableDefinition.setStatic(function addLogicalOperator(name, config) {
148
+
149
+ if (typeof config == 'string') {
150
+ config = {
151
+ title : config
152
+ };
153
+ } else if (!config) {
154
+ config = {};
155
+ }
156
+
157
+ if (!config.title) {
158
+ config.title = name.titleize();
159
+ }
160
+
161
+ // By default logical operators have a binary arity:
162
+ // they take 2 operands. The value of the variable + another value.
163
+ if (!config.arity) {
164
+ config.arity = 'binary';
165
+ }
166
+
167
+ if (config.arity != 'unary' && config.arity != 'binary' && config.arity != 'ternary') {
168
+ throw new Error('Unable to add Logical operator "' + name + '" to ' + this.name + ', unknown arity: "' + config.arity);
169
+ }
170
+
171
+ config.id = name;
172
+
173
+ this.constitute(function _addOperator() {
174
+ this.logical_operators[name] = config;
175
+ });
176
+ });
177
+
178
+ /**
179
+ * Add an assignment operator
180
+ *
181
+ * @author Jelle De Loecker <jelle@elevenways.be>
182
+ * @since 0.1.6
183
+ * @version 0.1.6
184
+ *
185
+ * @param {String} name
186
+ * @param {Object} config
187
+ */
188
+ VariableDefinition.setStatic(function addAssignmentOperator(name, config) {
189
+
190
+ if (typeof config == 'string') {
191
+ config = {
192
+ title : config
193
+ };
194
+ } else if (!config) {
195
+ config = {};
196
+ }
197
+
198
+ if (!config.title) {
199
+ config.title = name.titleize();
200
+ }
201
+
202
+ // By default assignment operators have a binary arity:
203
+ // they take 2 operands. The value of the variable + another value
204
+ if (!config.arity) {
205
+ config.arity = 'binary';
206
+ }
207
+
208
+ if (config.arity != 'unary' && config.arity != 'binary' && config.arity != 'ternary') {
209
+ throw new Error('Unable to add Assignment operator "' + name + '" to ' + this.name + ', unknown arity: "' + config.arity);
210
+ }
211
+
212
+ config.id = name;
213
+
214
+ this.constitute(function _addOperator() {
215
+ this.assignment_operators[name] = config;
216
+ });
217
+ });
218
+
219
+ /**
220
+ * Apply configuration
221
+ *
222
+ * @author Jelle De Loecker <jelle@elevenways.be>
223
+ * @since 0.1.6
224
+ * @version 0.1.6
225
+ */
226
+ VariableDefinition.setMethod(function applyConfig(config) {
227
+
228
+ if (!config) {
229
+ return;
230
+ }
231
+
232
+ if (config.name != null) {
233
+ this.name = config.name;
234
+ }
235
+
236
+ if (config.title != null) {
237
+ this.title = config.title;
238
+ }
239
+
240
+ if (config.description != null) {
241
+ this.description = config.description;
242
+ }
243
+ });
244
+
245
+ /**
246
+ * Return an simple object for JSON-ifying
247
+ *
248
+ * @author Jelle De Loecker <jelle@elevenways.be>
249
+ * @since 0.1.6
250
+ * @version 0.1.6
251
+ *
252
+ * @return {Object}
253
+ */
254
+ VariableDefinition.setMethod(function toJSON() {
255
+ return {
256
+ name : this.name,
257
+ title : this.title,
258
+ description : this.description,
259
+ type : this.type_name,
260
+ };
261
+ });
262
+
263
+ /**
264
+ * Return an object for json-drying this object
265
+ *
266
+ * @author Jelle De Loecker <jelle@elevenways.be>
267
+ * @since 0.1.6
268
+ * @version 0.1.6
269
+ *
270
+ * @return {Object}
271
+ */
272
+ VariableDefinition.setMethod(function toDry() {
273
+ return {
274
+ value : this.toJSON(),
275
+ };
276
+ });
277
+
278
+ /**
279
+ * unDry an object
280
+ *
281
+ * @author Jelle De Loecker <jelle@elevenways.be>
282
+ * @since 0.1.6
283
+ * @version 0.1.6
284
+ *
285
+ * @return {VariableDefinition}
286
+ */
287
+ VariableDefinition.setStatic(function unDry(obj) {
288
+ return new this(obj);
289
+ });
290
+
291
+ /**
292
+ * Get all available logical operators
293
+ *
294
+ * @author Jelle De Loecker <jelle@elevenways.be>
295
+ * @since 0.1.6
296
+ * @version 0.1.6
297
+ */
298
+ VariableDefinition.setMethod(function getLogicalOperators(value) {
299
+ return Object.values(this.constructor.logical_operators);
300
+ });
301
+
302
+ /**
303
+ * Get all available logical operators
304
+ *
305
+ * @author Jelle De Loecker <jelle@elevenways.be>
306
+ * @since 0.1.6
307
+ * @version 0.1.6
308
+ */
309
+ VariableDefinition.setMethod(function getAssignmentOperators(value) {
310
+ return Object.values(this.constructor.assignment_operators);
311
+ });
312
+
313
+ /**
314
+ * Create a value input element
315
+ *
316
+ * @author Jelle De Loecker <jelle@elevenways.be>
317
+ * @since 0.1.6
318
+ * @version 0.1.6
319
+ */
320
+ VariableDefinition.setMethod(function createValueInput(renderer, value_data) {
321
+
322
+ let input = renderer.createElement('input');
323
+ input.setAttribute('type', 'text');
324
+
325
+ return input;
326
+ });
327
+
328
+ /**
329
+ * The `equals` operator
330
+ *
331
+ * @author Jelle De Loecker <jelle@elevenways.be>
332
+ * @since 0.1.6
333
+ * @version 0.1.6
334
+ */
335
+ VariableDefinition.addLogicalOperator('equals');
336
+
337
+ /**
338
+ * The `not_equals` operator
339
+ *
340
+ * @author Jelle De Loecker <jelle@elevenways.be>
341
+ * @since 0.1.6
342
+ * @version 0.1.6
343
+ */
344
+ VariableDefinition.addLogicalOperator('not_equals');
345
+
346
+ /**
347
+ * The `is_empty` operator
348
+ *
349
+ * @author Jelle De Loecker <jelle@elevenways.be>
350
+ * @since 0.1.6
351
+ * @version 0.1.6
352
+ */
353
+ VariableDefinition.addLogicalOperator('is_empty', {arity: 'unary'});
354
+
355
+ /**
356
+ * The `is_null` operator
357
+ *
358
+ * @author Jelle De Loecker <jelle@elevenways.be>
359
+ * @since 0.1.6
360
+ * @version 0.1.6
361
+ */
362
+ VariableDefinition.addLogicalOperator('is_null', {arity: 'unary'});
363
+
364
+ /**
365
+ * The `set` operator sets a value
366
+ *
367
+ * @author Jelle De Loecker <jelle@elevenways.be>
368
+ * @since 0.1.6
369
+ * @version 0.1.6
370
+ */
371
+ VariableDefinition.addAssignmentOperator('set', 'Set');
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The Boolean Value Type
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 0.1.6
8
+ * @version 0.1.6
9
+ */
10
+ const BooleanDefinition = Function.inherits('Alchemy.QueryBuilder.VariableDefinition', 'Boolean');
11
+
12
+ /**
13
+ * Create a value input element
14
+ *
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
+ * @since 0.1.6
17
+ * @version 0.1.6
18
+ *
19
+ * @param {Hawkejs.Renderer}
20
+ */
21
+ BooleanDefinition.setMethod(function createValueInput(renderer) {
22
+ let toggle = renderer.createElement('alchemy-toggle');
23
+ return toggle;
24
+ });
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The List Value Type:
3
+ * Can contain other value types.
4
+ *
5
+ * @constructor
6
+ *
7
+ * @author Jelle De Loecker <jelle@elevenways.be>
8
+ * @since 0.1.7
9
+ * @version 0.1.7
10
+ */
11
+ const ListDefinition = Function.inherits('Alchemy.QueryBuilder.VariableDefinition', 'List');
12
+
13
+ /**
14
+ * The optional type this list holds
15
+ *
16
+ * @author Jelle De Loecker <jelle@elevenways.be>
17
+ * @since 0.1.7
18
+ * @version 0.1.7
19
+ */
20
+ ListDefinition.setProperty('content_type');
21
+
22
+ /**
23
+ * The `contains` operator
24
+ *
25
+ * @author Jelle De Loecker <jelle@elevenways.be>
26
+ * @since 0.1.7
27
+ * @version 0.1.7
28
+ */
29
+ ListDefinition.addLogicalOperator('contains');
30
+
31
+ /**
32
+ * The `add` assignment operator adds an entry
33
+ *
34
+ * @author Jelle De Loecker <jelle@elevenways.be>
35
+ * @since 0.1.7
36
+ * @version 0.1.7
37
+ */
38
+ ListDefinition.addAssignmentOperator('add');
@@ -0,0 +1,106 @@
1
+ /**
2
+ * The Number Value Type
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 0.1.6
8
+ * @version 0.1.6
9
+ */
10
+ const NumberDefinition = Function.inherits('Alchemy.QueryBuilder.VariableDefinition', 'Number');
11
+
12
+ /**
13
+ * The `<` operator
14
+ *
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
+ * @since 0.1.6
17
+ * @version 0.1.6
18
+ */
19
+ NumberDefinition.addLogicalOperator('lt', 'Is Less Than');
20
+
21
+ /**
22
+ * The `<=` operator
23
+ *
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
25
+ * @since 0.1.6
26
+ * @version 0.1.6
27
+ */
28
+ NumberDefinition.addLogicalOperator('lte', 'Is Less Or Equal Than');
29
+
30
+ /**
31
+ * The `>` operator
32
+ *
33
+ * @author Jelle De Loecker <jelle@elevenways.be>
34
+ * @since 0.1.6
35
+ * @version 0.1.6
36
+ */
37
+ NumberDefinition.addLogicalOperator('gt', 'Is Greater Than');
38
+
39
+ /**
40
+ * The `>=` operator
41
+ *
42
+ * @author Jelle De Loecker <jelle@elevenways.be>
43
+ * @since 0.1.6
44
+ * @version 0.1.6
45
+ */
46
+ NumberDefinition.addLogicalOperator('gte', 'Is Greater Or Equal Than');
47
+
48
+ /**
49
+ * The `add` assignment operator adds a value
50
+ *
51
+ * @author Jelle De Loecker <jelle@elevenways.be>
52
+ * @since 0.1.6
53
+ * @version 0.1.6
54
+ */
55
+ NumberDefinition.addAssignmentOperator('add');
56
+
57
+ /**
58
+ * The `subtract` assignment operator subtracts a value
59
+ *
60
+ * @author Jelle De Loecker <jelle@elevenways.be>
61
+ * @since 0.1.6
62
+ * @version 0.1.6
63
+ */
64
+ NumberDefinition.addAssignmentOperator('subtract');
65
+
66
+ /**
67
+ * The `multiply` assignment operator multiplies a value
68
+ *
69
+ * @author Jelle De Loecker <jelle@elevenways.be>
70
+ * @since 0.1.6
71
+ * @version 0.1.6
72
+ */
73
+ NumberDefinition.addAssignmentOperator('multiply');
74
+
75
+ /**
76
+ * The `divide` assignment operator divides a value
77
+ *
78
+ * @author Jelle De Loecker <jelle@elevenways.be>
79
+ * @since 0.1.6
80
+ * @version 0.1.6
81
+ */
82
+ NumberDefinition.addAssignmentOperator('divide');
83
+
84
+ /**
85
+ * The `module` assignment operator leaves the rest
86
+ *
87
+ * @author Jelle De Loecker <jelle@elevenways.be>
88
+ * @since 0.1.6
89
+ * @version 0.1.6
90
+ */
91
+ NumberDefinition.addAssignmentOperator('modulo');
92
+
93
+ /**
94
+ * Create a value input element
95
+ *
96
+ * @author Jelle De Loecker <jelle@elevenways.be>
97
+ * @since 0.1.6
98
+ * @version 0.1.6
99
+ */
100
+ NumberDefinition.setMethod(function createValueInput(renderer, value_data) {
101
+
102
+ let input = renderer.createElement('input');
103
+ input.setAttribute('type', 'number');
104
+
105
+ return input;
106
+ });
@@ -0,0 +1,46 @@
1
+ /**
2
+ * The String Value Type
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 0.1.6
8
+ * @version 0.1.6
9
+ */
10
+ const StringDefinition = Function.inherits('Alchemy.QueryBuilder.VariableDefinition', 'String');
11
+
12
+ /**
13
+ * The `contains` operator
14
+ *
15
+ * @author Jelle De Loecker <jelle@elevenways.be>
16
+ * @since 0.1.6
17
+ * @version 0.1.6
18
+ */
19
+ StringDefinition.addLogicalOperator('contains');
20
+
21
+ /**
22
+ * The `starts_with` operator
23
+ *
24
+ * @author Jelle De Loecker <jelle@elevenways.be>
25
+ * @since 0.1.6
26
+ * @version 0.1.6
27
+ */
28
+ StringDefinition.addLogicalOperator('starts_with');
29
+
30
+ /**
31
+ * The `ends_with` operator
32
+ *
33
+ * @author Jelle De Loecker <jelle@elevenways.be>
34
+ * @since 0.1.6
35
+ * @version 0.1.6
36
+ */
37
+ StringDefinition.addLogicalOperator('ends_with');
38
+
39
+ /**
40
+ * The `append` assignment operator adds text
41
+ *
42
+ * @author Jelle De Loecker <jelle@elevenways.be>
43
+ * @since 0.1.6
44
+ * @version 0.1.6
45
+ */
46
+ StringDefinition.addAssignmentOperator('append');
@@ -0,0 +1,11 @@
1
+ /**
2
+ * A QueryBuilderAssignment field lets you set variable values
3
+ * using the QueryBuilder logic
4
+ *
5
+ * @constructor
6
+ *
7
+ * @author Jelle De Loecker <jelle@elevenways.be>
8
+ * @since 0.1.6
9
+ * @version 0.1.6
10
+ */
11
+ const QueryBuilderAssignment = Function.inherits('Alchemy.Field.QueryBuilder', 'QueryBuilderAssignment');
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Schema fields are nested schema's
3
+ *
4
+ * @constructor
5
+ *
6
+ * @author Jelle De Loecker <jelle@elevenways.be>
7
+ * @since 0.1.6
8
+ * @version 0.1.6
9
+ */
10
+ const QueryBuilderField = Function.inherits('Alchemy.Field', function QueryBuilder(schema, name, options) {
11
+
12
+ if (!options) {
13
+ options = {};
14
+ }
15
+
16
+ QueryBuilder.super.call(this, schema, name, options);
17
+ });
18
+
19
+ /**
20
+ * Set the datatype name
21
+ *
22
+ * @author Jelle De Loecker <jelle@develry.be>
23
+ * @since 0.1.6
24
+ * @version 0.1.6
25
+ */
26
+ QueryBuilderField.setDatatype('object');
27
+
28
+ /**
29
+ * This field value is self-contained
30
+ *
31
+ * @author Jelle De Loecker <jelle@develry.be>
32
+ * @since 0.1.6
33
+ * @version 0.1.6
34
+ */
35
+ QueryBuilderField.setSelfContained(true);
36
+
37
+ /**
38
+ * Cast the given value to this field's type
39
+ *
40
+ * @author Jelle De Loecker <jelle@elevenways.be>
41
+ * @since 0.1.6
42
+ * @version 0.1.6
43
+ */
44
+ QueryBuilderField.setMethod(function cast(value, to_datasource) {
45
+ return value;
46
+ });
47
+
48
+ /**
49
+ * Load remote data
50
+ *
51
+ * @author Jelle De Loecker <jelle@elevenways.be>
52
+ * @since 0.1.6
53
+ * @version 0.1.6
54
+ *
55
+ * @param {Object} config
56
+ * @param {HTMLElement} element
57
+ */
58
+ QueryBuilderField.setMethod(function loadData(config, element) {
59
+
60
+ if (element) {
61
+ let form = element.queryParents('alchemy-form');
62
+
63
+ if (form) {
64
+ let doc = form.document;
65
+
66
+ if (doc && doc.root_document) {
67
+ doc = doc.root_document;
68
+ }
69
+
70
+ let model_name,
71
+ $pk;
72
+
73
+ if (doc) {
74
+ model_name = doc.$model_name;
75
+ $pk = doc.$pk;
76
+ }
77
+
78
+ return element.hawkejs_helpers.Alchemy.getResource({
79
+ name : 'FormApi#queryBuilderData',
80
+ post : true,
81
+ body : {
82
+ model : model_name,
83
+ $pk : $pk,
84
+ config : config,
85
+ }
86
+ });
87
+ }
88
+ }
89
+
90
+ return [];
91
+ });