1
1
import Vue from "vue/dist/vue.esm" ;
2
2
import Vuex from "vuex" ;
3
+ import VRuntimeTemplate from "v-runtime-template"
4
+
3
5
import axios from "axios" ;
4
6
5
7
import matestackEventHub from "../../event_hub" ;
@@ -11,11 +13,13 @@ const componentDef = {
11
13
return {
12
14
data : { } ,
13
15
errors : { } ,
14
- nestedForms : { } ,
15
16
loading : false ,
17
+ nestedForms : { } ,
16
18
isNestedForm : false ,
17
19
hideNestedForm : false ,
18
- positionInNestedForm : 0
20
+ nestedFormRuntimeTemplates : { } ,
21
+ nestedFormRuntimeTemplateDomElements : { } ,
22
+ deletedNestedNewInstanceFormsCount : { }
19
23
} ;
20
24
} ,
21
25
methods : {
@@ -71,17 +75,64 @@ const componentDef = {
71
75
let childErrorKey = errorKey . split ( "." ) [ 1 ]
72
76
let childModelName = errorKey . split ( "." ) [ 0 ] . split ( "[" ) [ 0 ]
73
77
let childModelIndex = errorKey . split ( "." ) [ 0 ] . split ( "[" ) [ 1 ] . split ( "]" ) [ 0 ]
78
+ childModelIndex = parseInt ( childModelIndex ) + parseInt ( self . deletedNestedNewInstanceFormsCount [ childModelName + "_attributes" ] )
74
79
self . nestedForms [ childModelName + "_attributes" ] [ childModelIndex ] . setErrorKey ( childErrorKey , errors [ errorKey ] )
75
80
}
76
81
} )
77
82
} ,
83
+ resetNestedForms : function ( ) {
84
+ var self = this ;
85
+ Object . keys ( self . nestedForms ) . forEach ( function ( childModelKey ) {
86
+ self . nestedForms [ childModelKey ] . forEach ( function ( nestedFormInstance ) {
87
+ if ( nestedFormInstance . data [ "_destroy" ] == true ) {
88
+ var destroyed = true ;
89
+ }
90
+ nestedFormInstance . setProps ( nestedFormInstance . data , null )
91
+ Vue . set ( nestedFormInstance . data )
92
+ if ( destroyed ) {
93
+ nestedFormInstance . hideNestedForm = true
94
+ Vue . set ( nestedFormInstance . data , "_destroy" , true )
95
+ }
96
+ } )
97
+ } )
98
+ } ,
78
99
removeItem : function ( ) {
79
100
Vue . set ( this . data , "_destroy" , true )
80
101
this . hideNestedForm = true ;
102
+ if ( this . data [ "id" ] == null ) {
103
+ this . $parent . deletedNestedNewInstanceFormsCount [ this . props [ "fields_for" ] ] ++ ;
104
+ }
105
+ } ,
106
+ addItem : function ( key ) {
107
+ var templateString = JSON . parse ( this . $el . querySelector ( '#prototype-template-for-' + key ) . dataset [ ":template" ] )
108
+ if ( this . nestedFormRuntimeTemplateDomElements [ key ] == null ) {
109
+ var dom_elem = document . createElement ( 'div' )
110
+ dom_elem . innerHTML = templateString
111
+ var existingItemsCount ;
112
+ if ( this . nestedForms [ key ] == undefined ) {
113
+ existingItemsCount = 0
114
+ } else {
115
+ existingItemsCount = this . nestedForms [ key ] . length
116
+ }
117
+ dom_elem . querySelector ( '.matestack-form-fields-for' ) . id = "child-" + existingItemsCount
118
+ Vue . set ( this . nestedFormRuntimeTemplateDomElements , key , dom_elem )
119
+ Vue . set ( this . nestedFormRuntimeTemplates , key , this . nestedFormRuntimeTemplateDomElements [ key ] . outerHTML )
120
+ } else {
121
+ var dom_elem = document . createElement ( 'div' )
122
+ dom_elem . innerHTML = templateString
123
+ var existingItemsCount = this . nestedForms [ key ] . length
124
+ dom_elem . querySelector ( '.matestack-form-fields-for' ) . id = "child-" + existingItemsCount
125
+ this . nestedFormRuntimeTemplateDomElements [ key ] . insertAdjacentHTML (
126
+ 'beforeend' ,
127
+ dom_elem . innerHTML
128
+ )
129
+ Vue . set ( this . nestedFormRuntimeTemplates , key , this . nestedFormRuntimeTemplateDomElements [ key ] . outerHTML )
130
+ }
81
131
} ,
82
132
initValues : function ( ) {
83
133
let self = this ;
84
134
let data = { } ;
135
+
85
136
for ( let key in self . $refs ) {
86
137
if ( key . startsWith ( "input-component" ) ) {
87
138
self . $refs [ key ] . initialize ( )
@@ -98,36 +149,9 @@ const componentDef = {
98
149
if ( key . startsWith ( "checkbox-component" ) ) {
99
150
self . $refs [ key ] . initialize ( )
100
151
}
101
- if ( key . startsWith ( "matestack-form-fields-for" ) ) {
102
- self . $refs [ key ] . initializeNestedForm ( )
103
- }
104
152
}
105
153
} ,
106
- initializeNestedForm ( ) {
107
- const self = this ;
108
- self . isNestedForm = true ;
109
- if ( this . props [ "fields_for" ] != undefined ) {
110
- this . data = { }
111
- this . initValues ( )
112
- if ( this . $parent . data [ this . props [ "fields_for" ] ] == undefined ) {
113
- this . $parent . data [ this . props [ "fields_for" ] ] = [ ] ;
114
- }
115
- this . $parent . data [ this . props [ "fields_for" ] ] . push ( this . data ) ;
116
-
117
- if ( this . $parent . nestedForms [ this . props [ "fields_for" ] ] == undefined ) {
118
- this . $parent . nestedForms [ this . props [ "fields_for" ] ] = [ ] ;
119
- }
120
- let existingItemsCount = this . $parent . nestedForms [ this . props [ "fields_for" ] ] . length
121
- this . $parent . nestedForms [ this . props [ "fields_for" ] ] . push ( this ) ;
122
- this . positionInNestedForm = existingItemsCount
123
154
124
- //without the timeout it's somehow not working
125
- setTimeout ( function ( ) {
126
- self . $parent . $forceUpdate ( ) ;
127
- self . $forceUpdate ( ) ;
128
- } , 1 ) ;
129
- }
130
- } ,
131
155
shouldResetFormOnSuccessfulSubmit ( ) {
132
156
const self = this ;
133
157
if ( self . props [ "success" ] != undefined && self . props [ "success" ] [ "reset" ] != undefined ) {
@@ -261,13 +285,14 @@ const componentDef = {
261
285
if ( self . shouldResetFormOnSuccessfulSubmit ( ) )
262
286
{
263
287
self . setProps ( self . data , null ) ;
288
+ self . resetNestedForms ( ) ;
264
289
self . initValues ( ) ;
265
290
}
266
291
} )
267
292
. catch ( function ( error ) {
268
293
self . loading = false ;
269
294
if ( error . response && error . response . data && error . response . data . errors ) {
270
- // self.errors = error.response.data.errors;
295
+ self . errors = error . response . data . errors ;
271
296
self . setErrors ( error . response . data . errors ) ;
272
297
self . setNestedFormsError ( error . response . data . errors ) ;
273
298
}
@@ -324,8 +349,72 @@ const componentDef = {
324
349
} ,
325
350
} ,
326
351
mounted : function ( ) {
327
- this . initValues ( ) ;
352
+ var self = this ;
353
+ if ( this . props [ "fields_for" ] != undefined ) {
354
+ this . isNestedForm = true ;
355
+
356
+ var id = parseInt ( self . $el . id . replace ( "child-" , "" ) )
357
+
358
+ this . data = { }
359
+
360
+ //initialize nestedForm data in parent form if required
361
+ if ( this . $parent . data [ this . props [ "fields_for" ] ] == undefined ) {
362
+ this . $parent . data [ this . props [ "fields_for" ] ] = [ ] ;
363
+ }
364
+ if ( this . $parent . nestedForms [ this . props [ "fields_for" ] ] == undefined ) {
365
+ this . $parent . nestedForms [ this . props [ "fields_for" ] ] = [ ] ;
366
+ }
367
+ if ( this . $parent . deletedNestedNewInstanceFormsCount [ this . props [ "fields_for" ] ] == undefined ) {
368
+ this . $parent . deletedNestedNewInstanceFormsCount [ this . props [ "fields_for" ] ] = 0
369
+ }
370
+
371
+ //setup data binding for serverside rendered nested forms
372
+ if ( isNaN ( id ) ) {
373
+ this . initValues ( )
374
+ this . $parent . data [ this . props [ "fields_for" ] ] . push ( this . data ) ;
375
+ this . $parent . nestedForms [ this . props [ "fields_for" ] ] . push ( this ) ;
376
+ }
377
+
378
+ //setup data binding for runtime nested forms (dynamic add via v-runtime-template)
379
+ if ( ! isNaN ( id ) ) {
380
+ if ( this . $parent . data [ this . props [ "fields_for" ] ] [ id ] == undefined ) {
381
+ //new runtime form
382
+ this . initValues ( )
383
+ this . $parent . data [ this . props [ "fields_for" ] ] . push ( this . data ) ;
384
+ this . $parent . nestedForms [ this . props [ "fields_for" ] ] . push ( this ) ;
385
+ } else {
386
+ //retreive state for existing runtime form (after remount for example)
387
+ this . data = this . $parent . data [ this . props [ "fields_for" ] ] [ id ]
388
+ if ( this . data [ "_destroy" ] == true ) {
389
+ this . hideNestedForm = true ;
390
+ }
391
+ this . $parent . nestedForms [ this . props [ "fields_for" ] ] [ id ] = this ;
392
+ Object . keys ( this . $parent . errors ) . forEach ( function ( errorKey ) {
393
+ if ( errorKey . includes ( "." ) ) {
394
+ let childErrorKey = errorKey . split ( "." ) [ 1 ]
395
+ let childModelName = errorKey . split ( "." ) [ 0 ] . split ( "[" ) [ 0 ]
396
+ let childModelIndex = errorKey . split ( "." ) [ 0 ] . split ( "[" ) [ 1 ] . split ( "]" ) [ 0 ]
397
+ childModelIndex = parseInt ( childModelIndex ) + parseInt ( self . $parent . deletedNestedNewInstanceFormsCount [ childModelName + "_attributes" ] )
398
+ if ( childModelName + "_attributes" == self . props [ "fields_for" ] && childModelIndex == id ) {
399
+ self . setErrorKey ( childErrorKey , self . $parent . errors [ errorKey ] )
400
+ }
401
+ }
402
+ } )
403
+ }
404
+ }
405
+
406
+ //without the timeout it's somehow not working
407
+ setTimeout ( function ( ) {
408
+ self . $parent . $forceUpdate ( ) ;
409
+ self . $forceUpdate ( ) ;
410
+ } , 1 ) ;
411
+ } else {
412
+ this . initValues ( ) ;
413
+ }
328
414
} ,
415
+ components : {
416
+ VRuntimeTemplate : VRuntimeTemplate
417
+ }
329
418
} ;
330
419
331
420
let component = Vue . component ( "matestack-ui-core-form" , componentDef ) ;
0 commit comments