Skip to content

Commit a45588d

Browse files
committed
fixed error mapping and added specs for nested form support
1 parent a12f73d commit a45588d

File tree

5 files changed

+1124
-18
lines changed

5 files changed

+1124
-18
lines changed

lib/matestack/ui/vue_js/components/form/form.js

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const componentDef = {
1919
hideNestedForm: false,
2020
nestedFormRuntimeTemplates: {},
2121
nestedFormRuntimeTemplateDomElements: {},
22-
deletedNestedNewInstanceFormsCount: {},
22+
deletedNestedForms: {},
2323
nestedFormRuntimeId: ""
2424
};
2525
},
@@ -69,18 +69,28 @@ const componentDef = {
6969
setErrorKey: function(key, value){
7070
Vue.set(this.errors, key, value);
7171
},
72+
flushErrors: function(key, value){
73+
this.errors = {};
74+
},
7275
setNestedFormsError: function(errors){
7376
let self = this;
7477
Object.keys(errors).forEach(function(errorKey){
7578
if (errorKey.includes(".")){
7679
let childErrorKey = errorKey.split(".")[1]
7780
let childModelName = errorKey.split(".")[0].split("[")[0]
7881
let childModelIndex = errorKey.split(".")[0].split("[")[1].split("]")[0]
79-
childModelIndex = parseInt(childModelIndex) + parseInt(self.deletedNestedNewInstanceFormsCount[childModelName+"_attributes"])
80-
self.nestedForms[childModelName+"_attributes"][childModelIndex].setErrorKey(childErrorKey, errors[errorKey])
82+
let mappedChildModelIndex = self.mapToNestedForms(parseInt(childModelIndex), childModelName+"_attributes")
83+
self.nestedForms[childModelName+"_attributes"][mappedChildModelIndex].setErrorKey(childErrorKey, errors[errorKey])
8184
}
8285
})
8386
},
87+
mapToNestedForms: function(serverIndex, nestedFormKey){
88+
var index = serverIndex;
89+
while(this.deletedNestedForms[nestedFormKey].includes(index)){
90+
index++;
91+
}
92+
return index;
93+
},
8494
resetNestedForms: function(){
8595
var self = this;
8696
Object.keys(self.nestedForms).forEach(function(childModelKey){
@@ -89,6 +99,7 @@ const componentDef = {
8999
var destroyed = true;
90100
}
91101
nestedFormInstance.setProps(nestedFormInstance.data, null)
102+
nestedFormInstance.initValues()
92103
Vue.set(nestedFormInstance.data)
93104
if(destroyed){
94105
nestedFormInstance.hideNestedForm = true
@@ -106,9 +117,10 @@ const componentDef = {
106117
}else{
107118
primaryKey = id;
108119
}
109-
if(this.data[primaryKey] == null){
110-
this.$parent.deletedNestedNewInstanceFormsCount[this.props["fields_for"]]++;
111-
}
120+
// if(this.data[primaryKey] == null){
121+
var id = parseInt(this.nestedFormRuntimeId.replace("_"+this.props["fields_for"]+"_child_", ""));
122+
this.$parent.deletedNestedForms[this.props["fields_for"]].push(id);
123+
// }
112124
},
113125
addItem: function(key){
114126
var templateString = JSON.parse(this.$el.querySelector('#prototype-template-for-'+key).dataset[":template"])
@@ -121,14 +133,14 @@ const componentDef = {
121133
}else{
122134
existingItemsCount = this.nestedForms[key].length
123135
}
124-
dom_elem.querySelector('.matestack-form-fields-for').id = "child-"+existingItemsCount
136+
dom_elem.querySelector('.matestack-form-fields-for').id = key+"_child_"+existingItemsCount
125137
Vue.set(this.nestedFormRuntimeTemplateDomElements, key, dom_elem)
126138
Vue.set(this.nestedFormRuntimeTemplates, key, this.nestedFormRuntimeTemplateDomElements[key].outerHTML)
127139
}else{
128140
var dom_elem = document.createElement('div')
129141
dom_elem.innerHTML = templateString
130142
var existingItemsCount = this.nestedForms[key].length
131-
dom_elem.querySelector('.matestack-form-fields-for').id = "child-"+existingItemsCount
143+
dom_elem.querySelector('.matestack-form-fields-for').id = key+"_child_"+existingItemsCount
132144
this.nestedFormRuntimeTemplateDomElements[key].insertAdjacentHTML(
133145
'beforeend',
134146
dom_elem.innerHTML
@@ -289,6 +301,8 @@ const componentDef = {
289301
return;
290302
}
291303

304+
self.flushErrors();
305+
292306
if (self.shouldResetFormOnSuccessfulSubmit())
293307
{
294308
self.setProps(self.data, null);
@@ -360,9 +374,6 @@ const componentDef = {
360374
if (this.props["fields_for"] != undefined) {
361375
this.isNestedForm = true;
362376

363-
var id = parseInt(self.$el.id.replace("child-", ""));
364-
this.nestedFormRuntimeId = Math.floor(Math.random() * 1000);;
365-
366377
this.data = { "_destroy": false };
367378

368379
//initialize nestedForm data in parent form if required
@@ -372,19 +383,25 @@ const componentDef = {
372383
if(this.$parent.nestedForms[this.props["fields_for"]] == undefined){
373384
this.$parent.nestedForms[this.props["fields_for"]] = [];
374385
}
375-
if(this.$parent.deletedNestedNewInstanceFormsCount[this.props["fields_for"]] == undefined){
376-
this.$parent.deletedNestedNewInstanceFormsCount[this.props["fields_for"]] = 0
386+
if(this.$parent.deletedNestedForms[this.props["fields_for"]] == undefined){
387+
this.$parent.deletedNestedForms[this.props["fields_for"]] = []
377388
}
378389

390+
var id = parseInt(self.$el.id.replace(this.props["fields_for"]+"_child_", ""));
391+
379392
//setup data binding for serverside rendered nested forms
380393
if (isNaN(id)){
394+
id = this.$parent.nestedForms[this.props["fields_for"]].length
395+
this.nestedFormRuntimeId = "_"+this.props["fields_for"]+"_child_"+id
396+
this.$el.id = this.props["fields_for"]+"_child_"+id
381397
this.initValues()
382398
this.$parent.data[this.props["fields_for"]].push(this.data);
383399
this.$parent.nestedForms[this.props["fields_for"]].push(this);
384400
}
385401

386402
//setup data binding for runtime nested forms (dynamic add via v-runtime-template)
387403
if (!isNaN(id)){
404+
this.nestedFormRuntimeId = "_"+this.props["fields_for"]+"_child_"+id
388405
if(this.$parent.data[this.props["fields_for"]][id] == undefined){
389406
//new runtime form
390407
this.initValues()
@@ -402,8 +419,8 @@ const componentDef = {
402419
let childErrorKey = errorKey.split(".")[1]
403420
let childModelName = errorKey.split(".")[0].split("[")[0]
404421
let childModelIndex = errorKey.split(".")[0].split("[")[1].split("]")[0]
405-
childModelIndex = parseInt(childModelIndex) + parseInt(self.$parent.deletedNestedNewInstanceFormsCount[childModelName+"_attributes"])
406-
if(childModelName+"_attributes" == self.props["fields_for"] && childModelIndex == id){
422+
let mappedChildModelIndex = self.$parent.mapToNestedForms(parseInt(childModelIndex), childModelName+"_attributes")
423+
if(childModelName+"_attributes" == self.props["fields_for"] && mappedChildModelIndex == id){
407424
self.setErrorKey(childErrorKey, self.$parent.errors[errorKey])
408425
}
409426
}

spec/test/components/dynamic/form/checkbox/checkbox_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def self.hash_options
128128
end
129129

130130
class ExamplePage < Matestack::Ui::Page
131-
131+
132132
def response
133133
@test_model = TestModel.new
134134
@test_model.some_data = ["Array Option 2"]

spec/test/components/dynamic/form/input/input_spec.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ def test_model_params
103103

104104
specify do
105105
test_model = TestModel.create title: "Foo", description: "This is a very nice foo!"
106-
p test_model.id
107106
visit Rails.application.routes.url_helpers.some_test_model_path(test_model)
108107
expect(find_field(:title).value).to eq "Foo"
109108

0 commit comments

Comments
 (0)