Skip to content

Commit de6b323

Browse files
Merge pull request #509 from qduc/fix-fieldsubmit-validation
Fix fieldSubmit not calling validate method
2 parents 0593b87 + c82c44b commit de6b323

File tree

5 files changed

+86
-28
lines changed

5 files changed

+86
-28
lines changed

src/fields/abstractField.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function attributesDirective(el, binding, vnode) {
2525
}
2626

2727
export default {
28-
props: ["model", "schema", "formOptions", "disabled"],
28+
props: ["vfg", "model", "schema", "formOptions", "disabled"],
2929

3030
data() {
3131
return {

src/fields/core/fieldSubmit.vue

+7-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<script>
66
import abstractField from "../abstractField";
7-
import { isFunction, isEmpty } from "lodash";
7+
import { get as objGet, isFunction, isEmpty } from "lodash";
88
99
export default {
1010
mixins: [abstractField],
@@ -15,10 +15,13 @@ export default {
1515
// prevent a <form /> from having it's submit event triggered
1616
// when we have to validate data first
1717
$event.preventDefault();
18-
let errors = this.$parent.validate();
18+
let validateAsync = objGet(this.formOptions, "validateAsync", false);
19+
let errors = this.vfg.validate();
1920
let handleErrors = errors => {
20-
if (!isEmpty(errors) && isFunction(this.schema.onValidationError)) {
21-
this.schema.onValidationError(this.model, this.schema, errors, $event);
21+
if ((validateAsync && !isEmpty(errors)) || (!validateAsync && !errors)) {
22+
if (isFunction(this.schema.onValidationError)) {
23+
this.schema.onValidationError(this.model, this.schema, errors, $event);
24+
}
2225
} else if (isFunction(this.schema.onSubmit)) {
2326
this.schema.onSubmit(this.model, this.schema, $event);
2427
}

src/formGenerator.vue

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
div.vue-form-generator(v-if='schema != null')
33
fieldset(v-if="schema.fields", :is='tag')
44
template(v-for='field in fields')
5-
form-group(v-if='fieldVisible(field)', :field="field", :errors="errors", :model="model", :options="options", @validated="onFieldValidated")
5+
form-group(v-if='fieldVisible(field)', :vfg="vfg", :field="field", :errors="errors", :model="model", :options="options", @validated="onFieldValidated")
66

77
template(v-for='group in groups')
88
fieldset(:is='tag', :class='getFieldRowClasses(group)')
99
legend(v-if='group.legend') {{ group.legend }}
1010
template(v-for='field in group.fields')
11-
form-group(v-if='fieldVisible(field)', :field="field", :errors="errors", :model="model", :options="options", @validated="onFieldValidated", @model-updated="onModelUpdated")
11+
form-group(v-if='fieldVisible(field)', :vfg="vfg", :field="field", :errors="errors", :model="model", :options="options", @validated="onFieldValidated", @model-updated="onModelUpdated")
1212
</template>
1313

1414
<script>
@@ -59,6 +59,7 @@ export default {
5959
6060
data() {
6161
return {
62+
vfg: this,
6263
errors: [] // Validation errors
6364
};
6465
},

src/formGroup.vue

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</label>
1010

1111
<div class="field-wrap">
12-
<component ref="child" :is="getFieldType(field)" :disabled="fieldDisabled(field)" :model="model" :schema="field" :formOptions="options" @model-updated="onModelUpdated" @validated="onFieldValidated"></component>
12+
<component ref="child" :is="getFieldType(field)" :vfg="vfg" :disabled="fieldDisabled(field)" :model="model" :schema="field" :formOptions="options" @model-updated="onModelUpdated" @validated="onFieldValidated"></component>
1313
<div v-if="buttonVisibility(field)" class="buttons">
1414
<button v-for="(btn, index) in field.buttons" @click="buttonClickHandler(btn, field, $event)" :class="btn.classes" :key="index" v-text="btn.label"></button>
1515
</div>
@@ -33,6 +33,10 @@ export default {
3333
components: fieldComponents,
3434
mixins: [formMixin],
3535
props: {
36+
vfg: {
37+
type: Object,
38+
required: true
39+
},
3640
model: Object,
3741
options: {
3842
type: Object

test/unit/specs/fields/fieldSubmit.spec.js

+70-20
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,23 @@ function createField2(data, methods) {
1919

2020
describe("fieldSubmit.vue", () => {
2121
describe("check template", () => {
22+
let vfg = {};
2223
let schema = {
2324
type: "submit",
2425
buttonText: "Submit form",
2526
inputName: "",
2627
validateBeforeSubmit: false,
27-
onSubmit() {},
28+
onSubmit: sinon.spy(),
2829
fieldClasses: ["applied-class", "another-class"]
2930
};
31+
let formOptions = {
32+
validateAsync: false
33+
};
3034
let model = { name: "John Doe" };
3135
let input;
3236

3337
before(() => {
34-
createField2({ schema, model, disabled: false });
38+
createField2({ vfg, schema, formOptions, model, disabled: false });
3539
input = wrapper.find("input");
3640
});
3741

@@ -43,43 +47,89 @@ describe("fieldSubmit.vue", () => {
4347
});
4448

4549
describe("valid form", () => {
46-
it.skip("should not call validate if validateBeforeSubmit is false", () => {
47-
schema.onSubmit = sinon.spy();
48-
let cb = sinon.spy();
49-
wrapper.vm.$parent.validate = cb;
50+
before(() => {
51+
vfg.validate = () => true;
52+
sinon.spy(vfg, "validate");
53+
});
54+
55+
afterEach(() => {
56+
schema.onSubmit.resetHistory();
57+
vfg.validate.resetHistory();
58+
});
59+
60+
it("should not call validate but should call onSubmit if validateBeforeSubmit is false", () => {
61+
input.trigger("click");
5062

51-
input.click();
52-
expect(cb.called).to.be.false;
63+
expect(vfg.validate.notCalled).to.be.true;
5364
expect(schema.onSubmit.calledOnce).to.be.true;
5465
expect(schema.onSubmit.calledWith(model, schema)).to.be.true;
5566
});
5667

57-
it.skip("should call validate if validateBeforeSubmit is true", () => {
68+
it("should call validate and onSubmit if validateBeforeSubmit is true", () => {
5869
schema.validateBeforeSubmit = true;
59-
schema.onSubmit = sinon.spy();
60-
let cb = sinon.spy();
61-
wrapper.vm.$parent.validate = cb;
6270

6371
input.trigger("click");
6472

65-
expect(cb.called).to.be.true;
73+
expect(vfg.validate.called).to.be.true;
6674
expect(schema.onSubmit.called).to.be.true;
6775
});
6876
});
6977

7078
describe("invalid form", () => {
71-
it.skip("should not call onSubmit if validateBeforeSubmit is true", () => {
79+
before(() => {
80+
vfg.validate = () => false;
81+
sinon.spy(vfg, "validate");
82+
});
83+
84+
afterEach(() => {
85+
schema.onSubmit.resetHistory();
86+
vfg.validate.resetHistory();
87+
});
88+
89+
it("should call validate but should not call onSubmit if validateBeforeSubmit is true", () => {
7290
schema.validateBeforeSubmit = true;
91+
92+
input.trigger("click");
93+
94+
expect(vfg.validate.called).to.be.true;
95+
expect(schema.onSubmit.notCalled).to.be.true;
96+
});
97+
});
98+
99+
describe("async validate", () => {
100+
before(() => {
101+
formOptions.validateAsync = true;
102+
vfg.validate = sinon.stub();
73103
schema.onSubmit = sinon.spy();
74-
let cb = sinon.spy(() => {
75-
return ["an error occurred"];
104+
});
105+
106+
afterEach(() => {
107+
vfg.validate.reset();
108+
schema.onSubmit.resetHistory();
109+
});
110+
111+
describe("valid form", () => {
112+
it("should call validate and onSubmit if validateBeforeSubmit is true", async function () {
113+
schema.validateBeforeSubmit = true;
114+
vfg.validate.resolves([]);
115+
116+
await input.trigger("click");
117+
118+
expect(vfg.validate.called).to.be.true;
119+
expect(schema.onSubmit.called).to.be.true;
76120
});
77-
wrapper.vm.$parent.validate = cb;
121+
});
78122

79-
input.trigger("click");
123+
describe("invalid form", () => {
124+
it("should call validate but should not call onSubmit if validateBeforeSubmit is true", async function () {
125+
schema.validateBeforeSubmit = true;
126+
vfg.validate.resolves(["Error"]);
80127

81-
expect(cb.called).to.be.true;
82-
expect(schema.onSubmit.called).to.be.true;
128+
await input.trigger("click");
129+
130+
expect(vfg.validate.called).to.be.true;
131+
expect(schema.onSubmit.notCalled).to.be.true;
132+
});
83133
});
84134
});
85135

0 commit comments

Comments
 (0)