matestack-ui-core 2.1.1 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +15 -478
  4. data/lib/matestack/ui/core/base.rb +21 -7
  5. data/lib/matestack/ui/core/context.rb +2 -2
  6. data/lib/matestack/ui/core/helper.rb +29 -29
  7. data/lib/matestack/ui/core/{app.rb → layout.rb} +6 -17
  8. data/lib/matestack/ui/core/page.rb +0 -44
  9. data/lib/matestack/ui/core/tag_helper.rb +17 -10
  10. data/lib/matestack/ui/core/version.rb +1 -1
  11. data/lib/matestack/ui/core.rb +2 -47
  12. data/lib/matestack/ui/layout.rb +1 -0
  13. data/lib/matestack/ui/page.rb +1 -1
  14. metadata +6 -69
  15. data/lib/matestack/ui/app.rb +0 -1
  16. data/lib/matestack/ui/core/vue_attributes.rb +0 -13
  17. data/lib/matestack/ui/vue_js/app/app.js +0 -40
  18. data/lib/matestack/ui/vue_js/app/location.js +0 -9
  19. data/lib/matestack/ui/vue_js/app/store.js +0 -103
  20. data/lib/matestack/ui/vue_js/components/action.js +0 -151
  21. data/lib/matestack/ui/vue_js/components/action.rb +0 -46
  22. data/lib/matestack/ui/vue_js/components/async.js +0 -110
  23. data/lib/matestack/ui/vue_js/components/async.rb +0 -84
  24. data/lib/matestack/ui/vue_js/components/cable.js +0 -100
  25. data/lib/matestack/ui/vue_js/components/cable.rb +0 -69
  26. data/lib/matestack/ui/vue_js/components/collection/content.js +0 -97
  27. data/lib/matestack/ui/vue_js/components/collection/content.rb +0 -32
  28. data/lib/matestack/ui/vue_js/components/collection/filter.js +0 -46
  29. data/lib/matestack/ui/vue_js/components/collection/filter.rb +0 -29
  30. data/lib/matestack/ui/vue_js/components/collection/filter_reset.rb +0 -19
  31. data/lib/matestack/ui/vue_js/components/collection/helper.rb +0 -128
  32. data/lib/matestack/ui/vue_js/components/collection/next.rb +0 -19
  33. data/lib/matestack/ui/vue_js/components/collection/order.js +0 -46
  34. data/lib/matestack/ui/vue_js/components/collection/order.rb +0 -28
  35. data/lib/matestack/ui/vue_js/components/collection/order_toggle.rb +0 -21
  36. data/lib/matestack/ui/vue_js/components/collection/order_toggle_indicator.rb +0 -30
  37. data/lib/matestack/ui/vue_js/components/collection/page.rb +0 -21
  38. data/lib/matestack/ui/vue_js/components/collection/previous.rb +0 -19
  39. data/lib/matestack/ui/vue_js/components/form/base.rb +0 -171
  40. data/lib/matestack/ui/vue_js/components/form/checkbox.js +0 -15
  41. data/lib/matestack/ui/vue_js/components/form/checkbox.rb +0 -105
  42. data/lib/matestack/ui/vue_js/components/form/checkbox_mixin.js +0 -70
  43. data/lib/matestack/ui/vue_js/components/form/context.rb +0 -15
  44. data/lib/matestack/ui/vue_js/components/form/fields_for_add_item.rb +0 -35
  45. data/lib/matestack/ui/vue_js/components/form/fields_for_remove_item.rb +0 -19
  46. data/lib/matestack/ui/vue_js/components/form/form.js +0 -473
  47. data/lib/matestack/ui/vue_js/components/form/form.rb +0 -84
  48. data/lib/matestack/ui/vue_js/components/form/input.js +0 -15
  49. data/lib/matestack/ui/vue_js/components/form/input.rb +0 -42
  50. data/lib/matestack/ui/vue_js/components/form/input_mixin.js +0 -53
  51. data/lib/matestack/ui/vue_js/components/form/radio.js +0 -15
  52. data/lib/matestack/ui/vue_js/components/form/radio.rb +0 -76
  53. data/lib/matestack/ui/vue_js/components/form/radio_mixin.js +0 -55
  54. data/lib/matestack/ui/vue_js/components/form/select.js +0 -15
  55. data/lib/matestack/ui/vue_js/components/form/select.rb +0 -88
  56. data/lib/matestack/ui/vue_js/components/form/select_mixin.js +0 -55
  57. data/lib/matestack/ui/vue_js/components/form/textarea.js +0 -15
  58. data/lib/matestack/ui/vue_js/components/form/textarea.rb +0 -37
  59. data/lib/matestack/ui/vue_js/components/form/textarea_mixin.js +0 -37
  60. data/lib/matestack/ui/vue_js/components/isolated.js +0 -108
  61. data/lib/matestack/ui/vue_js/components/isolated.rb +0 -86
  62. data/lib/matestack/ui/vue_js/components/mixin.js +0 -22
  63. data/lib/matestack/ui/vue_js/components/onclick.js +0 -19
  64. data/lib/matestack/ui/vue_js/components/onclick.rb +0 -37
  65. data/lib/matestack/ui/vue_js/components/toggle.js +0 -71
  66. data/lib/matestack/ui/vue_js/components/toggle.rb +0 -38
  67. data/lib/matestack/ui/vue_js/components/transition.js +0 -42
  68. data/lib/matestack/ui/vue_js/components/transition.rb +0 -40
  69. data/lib/matestack/ui/vue_js/components.rb +0 -111
  70. data/lib/matestack/ui/vue_js/event_hub.js +0 -5
  71. data/lib/matestack/ui/vue_js/helpers/query_params_helper.js +0 -56
  72. data/lib/matestack/ui/vue_js/index.js +0 -52
  73. data/lib/matestack/ui/vue_js/initialize.rb +0 -5
  74. data/lib/matestack/ui/vue_js/page/content.js +0 -23
  75. data/lib/matestack/ui/vue_js/vue.rb +0 -63
  76. data/lib/matestack/ui/vue_js_component.rb +0 -2
@@ -1,473 +0,0 @@
1
- import Vue from "vue/dist/vue.esm";
2
- import Vuex from "vuex";
3
- import VRuntimeTemplate from "v-runtime-template"
4
-
5
- import axios from "axios";
6
-
7
- import matestackEventHub from "../../event_hub";
8
- import componentMixin from "../mixin";
9
-
10
- const componentDef = {
11
- mixins: [componentMixin],
12
- data: function () {
13
- return {
14
- data: {},
15
- errors: {},
16
- loading: false,
17
- nestedForms: {},
18
- isNestedForm: false,
19
- hideNestedForm: false,
20
- nestedFormRuntimeTemplates: {},
21
- nestedFormRuntimeTemplateDomElements: {},
22
- deletedNestedForms: {},
23
- nestedFormRuntimeId: "",
24
- nestedFormServerErrorIndex: "",
25
- };
26
- },
27
- methods: {
28
- initDataKey: function (key, initValue) {
29
- this.data[key] = initValue;
30
- },
31
- updateFormValue: function (key, value) {
32
- this.data[key] = value;
33
- },
34
- hasErrors: function(){
35
- //https://stackoverflow.com/a/27709663/13886137
36
- for (var key in this.errors) {
37
- if (this.errors[key] !== null && this.errors[key] != ""){
38
- return true;
39
- }
40
- }
41
- return false;
42
- },
43
- resetErrors: function (key) {
44
- if (this.errors[key]) {
45
- delete this.errors[key];
46
- Vue.set(this.errors);
47
- }
48
- if (this.isNestedForm){
49
- var serverErrorKey = this.props["fields_for"].replace("_attributes", "")+"["+this.nestedFormServerErrorIndex+"]."+key
50
- if (this.$parent.errors[serverErrorKey]) {
51
- delete this.$parent.errors[serverErrorKey];
52
- Vue.set(this.$parent.errors);
53
- }
54
- }
55
- },
56
- setErrors: function(errors){
57
- this.errors = errors;
58
- },
59
- setNestedFormServerErrorIndex: function(value){
60
- this.nestedFormServerErrorIndex = value;
61
- },
62
- setErrorKey: function(key, value){
63
- Vue.set(this.errors, key, value);
64
- },
65
- flushErrors: function(key, value){
66
- this.errors = {};
67
- },
68
- setNestedFormsError: function(errors){
69
- let self = this;
70
- Object.keys(errors).forEach(function(errorKey){
71
- if (errorKey.includes(".")){
72
- let childErrorKey = errorKey.split(".")[1]
73
- let childModelName = errorKey.split(".")[0].split("[")[0]
74
- let childModelIndex = errorKey.split(".")[0].split("[")[1].split("]")[0]
75
- let mappedChildModelIndex = self.mapToNestedForms(parseInt(childModelIndex), childModelName+"_attributes")
76
- self.nestedForms[childModelName+"_attributes"][mappedChildModelIndex].setNestedFormServerErrorIndex(parseInt(childModelIndex))
77
- self.nestedForms[childModelName+"_attributes"][mappedChildModelIndex].setErrorKey(childErrorKey, errors[errorKey])
78
- }
79
- })
80
- },
81
- mapToNestedForms: function(serverIndex, nestedFormKey){
82
- var primaryKey;
83
- if(this.props["primary_key"] != undefined){
84
- primaryKey = this.props["primary_key"];
85
- }else{
86
- primaryKey = "id";
87
- }
88
-
89
- var formIdMap = []
90
- var childModelKey = 0;
91
- while(this.data[nestedFormKey].length > childModelKey){
92
- var ignore = this.data[nestedFormKey][childModelKey]["_destroy"] == true && this.data[nestedFormKey][childModelKey][primaryKey] == null
93
- if(!ignore){
94
- formIdMap.push(childModelKey)
95
- }
96
- childModelKey++;
97
- }
98
-
99
- return formIdMap[serverIndex];
100
- },
101
- resetNestedForms: function(){
102
- var self = this;
103
- Object.keys(self.nestedForms).forEach(function(childModelKey){
104
- self.nestedForms[childModelKey].forEach(function(nestedFormInstance){
105
- if(nestedFormInstance.data["_destroy"] == true){
106
- var destroyed = true;
107
- }
108
- nestedFormInstance.initValues()
109
- Vue.set(nestedFormInstance.data)
110
- if(destroyed){
111
- nestedFormInstance.hideNestedForm = true
112
- Vue.set(nestedFormInstance.data, "_destroy", true)
113
- }
114
- })
115
- })
116
- },
117
- removeItem: function(){
118
- Vue.set(this.data, "_destroy", true)
119
- this.hideNestedForm = true;
120
- var id = parseInt(this.nestedFormRuntimeId.replace("_"+this.props["fields_for"]+"_child_", ""));
121
- this.$parent.deletedNestedForms[this.props["fields_for"]].push(id);
122
- var serverErrorKey = this.props["fields_for"].replace("_attributes", "")+"["+this.nestedFormServerErrorIndex+"]."
123
- var self = this;
124
- Object.keys(self.$parent.errors).forEach(function(errorKey){
125
- if (errorKey.lastIndexOf(serverErrorKey, 0) == 0) {
126
- delete self.$parent.errors[errorKey];
127
- Vue.set(self.$parent.errors)
128
- }
129
- });
130
- },
131
- addItem: function(key){
132
- var templateString = JSON.parse(this.$el.querySelector('#prototype-template-for-'+key).dataset[":template"])
133
- if (this.nestedFormRuntimeTemplateDomElements[key] == null){
134
- var dom_elem = document.createElement('div')
135
- dom_elem.innerHTML = templateString
136
- var existingItemsCount;
137
- if (this.nestedForms[key] == undefined){
138
- existingItemsCount = 0
139
- }else{
140
- existingItemsCount = this.nestedForms[key].length
141
- }
142
- dom_elem.querySelector('.matestack-form-fields-for').id = key+"_child_"+existingItemsCount
143
- Vue.set(this.nestedFormRuntimeTemplateDomElements, key, dom_elem)
144
- Vue.set(this.nestedFormRuntimeTemplates, key, this.nestedFormRuntimeTemplateDomElements[key].outerHTML)
145
- }else{
146
- var dom_elem = document.createElement('div')
147
- dom_elem.innerHTML = templateString
148
- var existingItemsCount = this.nestedForms[key].length
149
- dom_elem.querySelector('.matestack-form-fields-for').id = key+"_child_"+existingItemsCount
150
- this.nestedFormRuntimeTemplateDomElements[key].insertAdjacentHTML(
151
- 'beforeend',
152
- dom_elem.innerHTML
153
- )
154
- Vue.set(this.nestedFormRuntimeTemplates, key, this.nestedFormRuntimeTemplateDomElements[key].outerHTML)
155
- }
156
- },
157
- initValues: function () {
158
- let self = this;
159
- let data = {};
160
-
161
- for (let key in self.$refs) {
162
- if (key.startsWith("input-component")) {
163
- self.$refs[key].initialize()
164
- }
165
- if (key.startsWith("textarea-component")) {
166
- self.$refs[key].initialize()
167
- }
168
- if (key.startsWith("select-component")) {
169
- self.$refs[key].initialize()
170
- }
171
- if (key.startsWith("radio-component")) {
172
- self.$refs[key].initialize()
173
- }
174
- if (key.startsWith("checkbox-component")) {
175
- self.$refs[key].initialize()
176
- }
177
- }
178
- },
179
-
180
- shouldResetFormOnSuccessfulSubmit() {
181
- const self = this;
182
- if (self.props["success"] != undefined && self.props["success"]["reset"] != undefined) {
183
- return self.props["success"]["reset"];
184
- } else {
185
- return self.shouldResetFormOnSuccessfulSubmitByDefault();
186
- }
187
- },
188
- shouldResetFormOnSuccessfulSubmitByDefault() {
189
- const self = this;
190
- if (self.props["method"] == "put") {
191
- return false;
192
- } else {
193
- return true;
194
- }
195
- },
196
- perform: function(){
197
- const self = this
198
- if (self.props["fields_for"] != null) {
199
- return;
200
- }
201
- var form = self.$el.tagName == 'FORM' ? self.$el : self.$el.querySelector('form');
202
- if(form.checkValidity()){
203
- self.loading = true;
204
- if (self.props["emit"] != undefined) {
205
- matestackEventHub.$emit(self.props["emit"]);
206
- }
207
- if (self.props["delay"] != undefined) {
208
- setTimeout(function () {
209
- self.sendRequest()
210
- }, parseInt(self.props["delay"]));
211
- } else {
212
- self.sendRequest()
213
- }
214
- } else {
215
- matestackEventHub.$emit('static_form_errors');
216
- }
217
- },
218
- transformToFormData: function (formData, dataNode, parentKey=null) {
219
- var self = this;
220
- for (let key in dataNode) {
221
- if (key.endsWith("[]")) {
222
- for (let i in dataNode[key]) {
223
- let file = dataNode[key][i];
224
- if (parentKey != null) {
225
- formData.append(self.props["for"] + parentKey + "[" + key.slice(0, -2) + "][]", file);
226
- } else {
227
- formData.append(self.props["for"] + "[" + key.slice(0, -2) + "][]", file);
228
- }
229
- }
230
- } else {
231
- if (Array.isArray(dataNode[key])){
232
- dataNode[key].forEach(function(item, index){
233
- if (parentKey != null) {
234
- let _key = parentKey + "[" + key + "]" + "[]";
235
- formData = self.transformToFormData(formData, item, _key)
236
- } else {
237
- let _key = "[" + key + "]" + "[]";
238
- formData = self.transformToFormData(formData, item, _key)
239
- }
240
- })
241
- } else {
242
- if (dataNode[key] != null){
243
- if (parentKey != null) {
244
- formData.append(self.props["for"] + parentKey + "[" + key + "]", dataNode[key]);
245
- } else {
246
- formData.append(self.props["for"] + "[" + key + "]", dataNode[key]);
247
- }
248
- }
249
- }
250
- }
251
- }
252
-
253
- return formData;
254
- },
255
- sendRequest: function(){
256
- const self = this;
257
- let payload = {};
258
- payload[self.props["for"]] = self.data;
259
- let axios_config = {};
260
- if (self.props["multipart"] == true ) {
261
- let formData = new FormData();
262
- formData = this.transformToFormData(formData, this.data)
263
- axios_config = {
264
- method: self.props["method"],
265
- url: self.props["submit_path"],
266
- data: formData,
267
- headers: {
268
- "X-CSRF-Token": document.getElementsByName("csrf-token")[0].getAttribute("content"),
269
- "Content-Type": "multipart/form-data",
270
- },
271
- };
272
- } else {
273
- axios_config = {
274
- method: self.props["method"],
275
- url: self.props["submit_path"],
276
- data: payload,
277
- headers: {
278
- "X-CSRF-Token": document.getElementsByName("csrf-token")[0].getAttribute("content"),
279
- "Content-Type": "application/json",
280
- },
281
- };
282
- }
283
- axios(axios_config)
284
- .then(function (response) {
285
- self.loading = false;
286
- if (self.props["success"] != undefined && self.props["success"]["emit"] != undefined) {
287
- matestackEventHub.$emit(self.props["success"]["emit"], response.data);
288
- }
289
- // transition handling
290
- if (self.props["success"] != undefined
291
- && self.props["success"]["transition"] != undefined
292
- && (
293
- self.props["success"]["transition"]["follow_response"] == undefined
294
- ||
295
- self.props["success"]["transition"]["follow_response"] === false
296
- )
297
- && self.$store != undefined
298
- ) {
299
- let path = self.props["success"]["transition"]["path"]
300
- self.$store.dispatch('navigateTo', {url: path, backwards: false})
301
- return;
302
- }
303
- if (self.props["success"] != undefined
304
- && self.props["success"]["transition"] != undefined
305
- && self.props["success"]["transition"]["follow_response"] === true
306
- && self.$store != undefined
307
- ) {
308
- let path = response.data["transition_to"] || response.request.responseURL
309
- self.$store.dispatch('navigateTo', {url: path, backwards: false})
310
- return;
311
- }
312
- // redirect handling
313
- if (self.props["success"] != undefined
314
- && self.props["success"]["redirect"] != undefined
315
- && (
316
- self.props["success"]["redirect"]["follow_response"] == undefined
317
- ||
318
- self.props["success"]["redirect"]["follow_response"] === false
319
- )
320
- && self.$store != undefined
321
- ) {
322
- let path = self.props["success"]["redirect"]["path"]
323
- window.location.href = path
324
- return;
325
- }
326
- if (self.props["success"] != undefined
327
- && self.props["success"]["redirect"] != undefined
328
- && self.props["success"]["redirect"]["follow_response"] === true
329
- && self.$store != undefined
330
- ) {
331
- let path = response.data["redirect_to"] || response.request.responseURL
332
- window.location.href = path
333
- return;
334
- }
335
-
336
- self.flushErrors();
337
-
338
- if (self.shouldResetFormOnSuccessfulSubmit())
339
- {
340
- self.initValues();
341
- self.resetNestedForms();
342
- }
343
- })
344
- .catch(function (error) {
345
- self.loading = false;
346
- if (error.response && error.response.data && error.response.data.errors) {
347
- self.errors = error.response.data.errors;
348
- self.setErrors(error.response.data.errors);
349
- self.setNestedFormsError(error.response.data.errors);
350
- }
351
- if (self.props["failure"] != undefined && self.props["failure"]["emit"] != undefined) {
352
- matestackEventHub.$emit(self.props["failure"]["emit"], error.response.data);
353
- }
354
- // transition handling
355
- if (self.props["failure"] != undefined
356
- && self.props["failure"]["transition"] != undefined
357
- && (
358
- self.props["failure"]["transition"]["follow_response"] == undefined
359
- ||
360
- self.props["failure"]["transition"]["follow_response"] === false
361
- )
362
- && self.$store != undefined
363
- ) {
364
- let path = self.props["failure"]["transition"]["path"]
365
- self.$store.dispatch('navigateTo', {url: path, backwards: false})
366
- return;
367
- }
368
- if (self.props["failure"] != undefined
369
- && self.props["failure"]["transition"] != undefined
370
- && self.props["failure"]["transition"]["follow_response"] === true
371
- && self.$store != undefined
372
- ) {
373
- let path = error.response.data["transition_to"] || response.request.responseURL
374
- self.$store.dispatch('navigateTo', {url: path, backwards: false})
375
- return;
376
- }
377
- // redirect handling
378
- if (self.props["failure"] != undefined
379
- && self.props["failure"]["redirect"] != undefined
380
- && (
381
- self.props["failure"]["redirect"]["follow_response"] == undefined
382
- ||
383
- self.props["failure"]["redirect"]["follow_response"] === false
384
- )
385
- && self.$store != undefined
386
- ) {
387
- let path = self.props["failure"]["redirect"]["path"]
388
- window.location.href = path
389
- return;
390
- }
391
- if (self.props["failure"] != undefined
392
- && self.props["failure"]["redirect"] != undefined
393
- && self.props["failure"]["redirect"]["follow_response"] === true
394
- && self.$store != undefined
395
- ) {
396
- let path = error.response.data["redirect_to"] || response.request.responseURL
397
- window.location.href = path
398
- return;
399
- }
400
- });
401
- },
402
- },
403
- mounted: function () {
404
- var self = this;
405
- if (this.props["fields_for"] != undefined) {
406
- this.isNestedForm = true;
407
-
408
- this.data = { "_destroy": false };
409
-
410
- //initialize nestedForm data in parent form if required
411
- if(this.$parent.data[this.props["fields_for"]] == undefined){
412
- this.$set(this.$parent.data, this.props["fields_for"], []);
413
- }
414
- if(this.$parent.nestedForms[this.props["fields_for"]] == undefined){
415
- this.$set(this.$parent.nestedForms, this.props["fields_for"], []);
416
- }
417
- if(this.$parent.deletedNestedForms[this.props["fields_for"]] == undefined){
418
- this.$set(this.$parent.deletedNestedForms, this.props["fields_for"], []);
419
- }
420
-
421
- var id = parseInt(self.$el.id.replace(this.props["fields_for"]+"_child_", ""));
422
-
423
- //setup data binding for serverside rendered nested forms
424
- if (isNaN(id)){
425
- id = this.$parent.nestedForms[this.props["fields_for"]].length
426
- this.nestedFormRuntimeId = "_"+this.props["fields_for"]+"_child_"+id
427
- this.$el.id = this.props["fields_for"]+"_child_"+id
428
- this.initValues()
429
- this.$parent.data[this.props["fields_for"]].push(this.data);
430
- this.$parent.nestedForms[this.props["fields_for"]].push(this);
431
- }
432
-
433
- //setup data binding for runtime nested forms (dynamic add via v-runtime-template)
434
- if (!isNaN(id)){
435
- this.nestedFormRuntimeId = "_"+this.props["fields_for"]+"_child_"+id
436
- if(this.$parent.data[this.props["fields_for"]][id] == undefined){
437
- //new runtime form
438
- this.initValues()
439
- this.$parent.data[this.props["fields_for"]].push(this.data);
440
- this.$parent.nestedForms[this.props["fields_for"]].push(this);
441
- }else{
442
- //retreive state for existing runtime form (after remount for example)
443
- this.data = this.$parent.data[this.props["fields_for"]][id]
444
- if (this.data["_destroy"] == true){
445
- this.hideNestedForm = true;
446
- }
447
- this.$parent.nestedForms[this.props["fields_for"]][id] = this;
448
- Object.keys(this.$parent.errors).forEach(function(errorKey){
449
- if (errorKey.includes(".")){
450
- let childErrorKey = errorKey.split(".")[1]
451
- let childModelName = errorKey.split(".")[0].split("[")[0]
452
- let childModelIndex = errorKey.split(".")[0].split("[")[1].split("]")[0]
453
- let mappedChildModelIndex = self.$parent.mapToNestedForms(parseInt(childModelIndex), childModelName+"_attributes")
454
- if(childModelName+"_attributes" == self.props["fields_for"] && mappedChildModelIndex == id){
455
- self.setNestedFormServerErrorIndex(parseInt(childModelIndex))
456
- self.setErrorKey(childErrorKey, self.$parent.errors[errorKey])
457
- }
458
- }
459
- })
460
- }
461
- }
462
- } else {
463
- this.initValues();
464
- }
465
- },
466
- components: {
467
- VRuntimeTemplate: VRuntimeTemplate
468
- }
469
- };
470
-
471
- let component = Vue.component("matestack-ui-core-form", componentDef);
472
-
473
- export default componentDef;
@@ -1,84 +0,0 @@
1
- module Matestack
2
- module Ui
3
- module VueJs
4
- module Components
5
- module Form
6
- class Form < Matestack::Ui::VueJs::Vue
7
- vue_name 'matestack-ui-core-form'
8
-
9
- optional :for, :path, :success, :failure, :multipart, :emit, :delay, :errors
10
- optional :fields_for, :reject_blank
11
-
12
- attr_accessor :prototype_template
13
-
14
- # setup form context to allow child components like inputs to access the form configuration
15
- def initialize(html_tag = nil, text = nil, options = {}, &block)
16
- previous_form_context = Matestack::Ui::VueJs::Components::Form::Context.form_context
17
- Matestack::Ui::VueJs::Components::Form::Context.form_context = self
18
- super(html_tag, text, options, &block)
19
- Matestack::Ui::VueJs::Components::Form::Context.form_context = previous_form_context
20
- end
21
-
22
- def component_id
23
- "matestack-form-fields-for-#{context.fields_for}-#{SecureRandom.hex}" if context.fields_for
24
- end
25
-
26
- def response
27
- if context.fields_for
28
- div class: "matestack-form-fields-for", "v-show": "hideNestedForm != true", id: options[:id] do
29
- form_input key: context.for&.class&.primary_key, type: :hidden # required for existing model mapping
30
- form_input key: :_destroy, type: :hidden, init: true if context.reject_blank == true
31
- yield
32
- end
33
- else
34
- form attributes do
35
- yield
36
- end
37
- end
38
- end
39
-
40
- def attributes
41
- {
42
- class: 'matestack-form',
43
- 'v-bind:class': "{ 'has-errors': hasErrors(), loading: loading }",
44
- '@submit.prevent': 'perform',
45
- }
46
- end
47
-
48
- def vue_props
49
- {
50
- for: for_attribute,
51
- submit_path: ctx.path,
52
- method: form_method,
53
- success: ctx.success,
54
- failure: ctx.failure,
55
- multipart: !!ctx.multipart,
56
- emit: ctx.emit,
57
- delay: ctx.delay,
58
- fields_for: ctx.fields_for,
59
- primary_key: for_object_primary_key
60
- }
61
- end
62
-
63
- def for_attribute
64
- return for_option.model_name.singular if for_option.respond_to?(:model_name)
65
- for_option
66
- end
67
-
68
- def for_option
69
- @for_option ||= ctx.for
70
- end
71
-
72
- def for_object_primary_key
73
- context.for&.class&.primary_key rescue nil
74
- end
75
-
76
- def form_method
77
- @form_method ||= options.delete(:method)
78
- end
79
- end
80
- end
81
- end
82
- end
83
- end
84
- end
@@ -1,15 +0,0 @@
1
- import Vue from "vue/dist/vue.esm";
2
-
3
- import formInputMixin from "./input_mixin";
4
- import componentMixin from "../mixin";
5
-
6
- const componentDef = {
7
- mixins: [componentMixin, formInputMixin],
8
- data() {
9
- return {};
10
- }
11
- }
12
-
13
- let component = Vue.component("matestack-ui-core-form-input", componentDef);
14
-
15
- export default componentDef;
@@ -1,42 +0,0 @@
1
- module Matestack
2
- module Ui
3
- module VueJs
4
- module Components
5
- module Form
6
- class Input < Matestack::Ui::VueJs::Components::Form::Base
7
- vue_name 'matestack-ui-core-form-input'
8
-
9
- def response
10
- div class: 'matestack-ui-core-form-input' do
11
- label input_label, ":for": id if input_label
12
- input input_attributes
13
- render_errors
14
- end
15
- end
16
-
17
- def component_id
18
- "input-component-for-#{attribute_key}"
19
- end
20
-
21
- def input_attributes
22
- attributes
23
- end
24
-
25
- def init_value
26
- return nil if ctx.type.to_s == "file"
27
- super
28
- end
29
-
30
- def vue_props
31
- {
32
- init_value: init_value,
33
- key: key,
34
- }
35
- end
36
-
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,53 +0,0 @@
1
- const formInputMixin = {
2
- methods: {
3
- initialize: function(){
4
- const self = this
5
- let data = {};
6
-
7
- for (let key in this.$refs) {
8
- let initValue = this.$refs[key]["attributes"]["init-value"];
9
-
10
- self.$set(self.$parent.data, key.replace("input.", ""), null)
11
-
12
- if (initValue) {
13
- self.setValue(initValue["value"])
14
- self.afterInitialize(initValue["value"])
15
- } else {
16
- self.setValue(null)
17
- self.afterInitialize(null)
18
- }
19
- }
20
-
21
- },
22
- filesAdded: function (key) {
23
- const dataTransfer = event.dataTransfer || event.target;
24
- const files = dataTransfer.files;
25
- if (event.target.attributes.multiple) {
26
- this.$parent.data[key] = [];
27
- for (let index in files) {
28
- if (files[index] instanceof File) {
29
- this.$parent.data[key].push(files[index]);
30
- }
31
- }
32
- } else {
33
- this.$parent.data[key] = files[0];
34
- }
35
- },
36
- inputChanged: function (key) {
37
- if (this.$parent.isNestedForm){
38
- this.$parent.data["_destroy"] = false;
39
- }
40
- this.$parent.resetErrors(key);
41
-
42
- },
43
- afterInitialize: function(value){
44
- // can be used in the main component for further initialization steps
45
- },
46
- setValue: function (value){
47
- this.$parent.data[this.props["key"]] = value;
48
- }
49
- }
50
-
51
- }
52
-
53
- export default formInputMixin
@@ -1,15 +0,0 @@
1
- import Vue from "vue/dist/vue.esm";
2
-
3
- import formRadioMixin from "./radio_mixin";
4
- import componentMixin from "../mixin";
5
-
6
- const componentDef = {
7
- mixins: [componentMixin, formRadioMixin],
8
- data() {
9
- return {};
10
- }
11
- }
12
-
13
- let component = Vue.component("matestack-ui-core-form-radio", componentDef);
14
-
15
- export default componentDef;