Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dist/vfg-core.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/vfg.js

Large diffs are not rendered by default.

39 changes: 24 additions & 15 deletions src/formGenerator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
div.vue-form-generator(v-if='schema != null')
fieldset(v-if="schema.fields", :is='tag')
template(v-for='field in fields')
form-group(v-if='fieldVisible(field)', :vfg="vfg", :field="field", :errors="errors", :model="model", :options="options", @validated="onFieldValidated", @model-updated="onModelUpdated")
form-group(v-if='fieldVisible(field)', :vfg="vfg", :field="field", :errors="displayedErrors", :model="model", :options="options", @validated="onFieldValidated", @model-updated="onModelUpdated")

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

<script>
import { get as objGet, forEach, isFunction, isNil, isArray } from "lodash";
import { get as objGet, forEach, isFunction, isNil, isArray, clone } from "lodash";
import formMixin from "./formMixin.js";
import formGroup from "./formGroup.vue";

Expand Down Expand Up @@ -61,7 +61,8 @@ export default {
data() {
return {
vfg: this,
errors: [] // Validation errors
displayedErrors: [], // These are the errors currently being displayed
errors: [] // These are the errors of the form
};
},

Expand Down Expand Up @@ -98,9 +99,8 @@ export default {
if (newModel != null) {
this.$nextTick(() => {
// Model changed!
if (this.options.validateAfterLoad === true && this.isNewModel !== true) {
this.validate();
} else {
this.validate();
if (!this.options.validateAfterLoad || this.isNewModel) {
this.clearValidationErrors();
}
});
Expand All @@ -111,10 +111,9 @@ export default {
mounted() {
this.$nextTick(() => {
if (this.model) {
// First load, running validation if neccessary
if (this.options.validateAfterLoad === true && this.isNewModel !== true) {
this.validate();
} else {
this.validate();
if (!this.options.validateAfterLoad || this.isNewModel) {

this.clearValidationErrors();
}
}
Expand All @@ -134,11 +133,16 @@ export default {
// Child field executed validation
onFieldValidated(res, errors, field) {
// Remove old errors for this field
this.displayedErrors = this.displayedErrors.filter(e => e.field !== field.schema);
this.errors = this.errors.filter(e => e.field !== field.schema);

if (!res && errors && errors.length > 0) {
// Add errors with this field
forEach(errors, err => {
this.displayedErrors.push({
field: field.schema,
error: err
});
this.errors.push({
field: field.schema,
error: err
Expand Down Expand Up @@ -183,9 +187,10 @@ export default {
});
}
});
this.errors = formErrors;
let isValid = formErrors.length === 0;
this.$emit("validated", isValid, formErrors, this);
this.displayedErrors = formErrors;
this.errors = clone(formErrors);
let isValid = this.errors.length === 0;
this.$emit("validated", isValid, this.errors, this);
return isAsync ? formErrors : isValid;
};

Expand All @@ -198,7 +203,11 @@ export default {

// Clear validation errors
clearValidationErrors() {
this.errors.splice(0);
// TODO: Rename this function to cleanDisplayedValidationErrors, since
// it only removes the errors displayed on screen.
// Removing the errors must not make the form valid when raising a
// validated event
this.displayedErrors.splice(0);

forEach(this.$children, child => {
child.clearValidationErrors();
Expand Down
49 changes: 48 additions & 1 deletion test/unit/specs/VueFormGenerator.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const localVue = createLocalVue();
localVue.use(VueFormGenerator);

let wrapper;
const defaultTemplate = `<vue-form-generator :schema="schema" :model="model" :options="options" :multiple="multiple" ref="form"></vue-form-generator>`;
const defaultTemplate = `<vue-form-generator :schema="schema" :model="model" :options="options" :multiple="multiple" :is-new-model="isNewModel" ref="form"></vue-form-generator>`;

function createFormGenerator(data, methods, template) {
const Component = {
Expand Down Expand Up @@ -722,6 +722,53 @@ describe("VueFormGenerator.vue", () => {
});
});

describe("check isNewModel property", () => {
let schema = {
fields: [
{
type: "input",
inputType: "text",
label: "Name",
model: "name",
min: 3,
validator: VueFormGenerator.validators.string
}
]
};

let model = { name: "Me" };
let form;
let onValidated = sinon.spy();

before(() => {
onValidated.resetHistory();
createFormGenerator(
{ schema, model, isNewModel: true, options: { validateAfterLoad: true } },
{ onValidated: onValidated },
`<vue-form-generator :schema="schema" :model="model" :options="options" :multiple="false" :is-new-model="isNewModel" ref="form" @validated="onValidated"></vue-form-generator>`
);
wrapper.update();
});

it("there should be no errors on mounted, but the real errors should still be there()", () => {
form = wrapper.vm.$refs.form;
expect(form.displayedErrors).to.be.length(0);
expect(form.errors).to.be.length(1);
});

it("a validated event has been called, telling the form is not valid", () => {
expect(onValidated.callCount).to.be.equal(1);
expect(
onValidated.calledWith(false, [
{
field: schema.fields[0],
error: "The length of text is too small! Current: 2, Minimum: 3"
}
])
).to.be.true;
});
});

describe("check validateAfterLoad option", () => {
let schema = {
fields: [
Expand Down