1
0
mirror of synced 2024-11-25 14:56:03 +03:00

Fixes bug where deeply nestsed formulate-elements would not properly register with parent formulate component

This commit is contained in:
Justin Schroeder 2018-02-01 12:14:19 -05:00
parent e962aaec62
commit b33e3692b0
6 changed files with 42 additions and 28 deletions

2
dist/index.js vendored

File diff suppressed because one or more lines are too long

View File

@ -58,7 +58,7 @@ export default {
return this.$store.getters[`${this.m}formValidationErrors`][this.name] || {}
},
fields () {
return this.$formulate.fields(this.$vnode)
return this.$store.getters[`${this.m}formMeta`][this.name] || []
},
shouldShowErrors () {
if (this.forceErrors === false || this.forceErrors === true) {
@ -74,6 +74,9 @@ export default {
this.hydrate(this.initial)
},
methods: {
registerField (field, data) {
this.$store.commit(`${this.m}setFieldMeta`, {form: this.name, field, data})
},
hydrate (values) {
for (let field of this.fields) {
this.$store.commit(`${this.m}setFieldValue`, {
@ -112,7 +115,6 @@ export default {
return errors
},
updateFormValidation () {
console.log(this.fields)
this.fields.map(async field => this.validateField({
field: field.name,
validation: field.validation,

View File

@ -279,6 +279,7 @@ export default {
}
},
created () {
this.form.registerField(this.name, this.$props)
if (this.initial !== false) {
this.form.hydrate({[this.name]: this.initial})
}

View File

@ -64,28 +64,6 @@ class Formulate {
return this.errors[rule] ? this.errors[rule] : this.errors['default']
}
/**
* Recursively find all instance of FormulateElement inside a given vnode.
*/
fields (vnode) {
let fields = []
let children = false
if (vnode && vnode.componentOptions && vnode.componentOptions.children && vnode.componentOptions.children.length) {
children = vnode.componentOptions.children
} else if (vnode && vnode.children && vnode.children.length) {
children = vnode.children
}
if (children) {
fields = fields.concat(children.reduce((names, child) => {
if (child.componentOptions && child.componentOptions.tag === this.options.tags.FormulateElement) {
names.push(child.componentOptions.propsData)
}
return names.concat(this.fields(child))
}, []))
}
return fields
}
/**
* Given a particular field, value, validation rules, and form values
* perform asynchronous field validation.
@ -96,7 +74,12 @@ class Formulate {
async validationErrors ({field, value, label}, rulesString, values) {
return rulesString ? Promise.all(
this.parseRules(rulesString)
.map(({rule, args}) => this.rules[rule]({field, value, label, error: this.errorFactory(rule), values}, ...args))
.map(({rule, args}) => {
if (typeof this.rules[rule] !== 'function') {
throw new Error(`Validation rule is invalid: ${rule}`)
}
return this.rules[rule]({field, value, label, error: this.errorFactory(rule), values}, ...args)
})
).then(responses => responses.reduce((errors, error) => {
return error ? (Array.isArray(errors) ? errors.concat(error) : [error]) : errors
}, false)) : false

View File

@ -7,7 +7,8 @@ import {map, reduce} from './utils'
export const formulateState = (options = {}) => () => Object.assign({
values: {},
errors: {},
validationErrors: {}
validationErrors: {},
meta: {}
}, options)
/**
@ -25,6 +26,9 @@ export const formulateGetters = (moduleName = '', getters = {}) => Object.assign
formValidationErrors (state) {
return state.validationErrors
},
formMeta (state) {
return map(state.meta, (form, fields) => Object.entries(fields).map(([key, value]) => value))
},
hasErrors (state) {
return map(state.errors, (form, errors) => {
return reduce(errors, (hasErrors, field, errors) => hasErrors || !!errors.length, false)
@ -59,6 +63,11 @@ export const formulateMutations = (mutations = {}) => Object.assign({
state.validationErrors = Object.assign({}, state.validationErrors, {
[form]: Object.assign({}, state.validationErrors[form] || {}, {[field]: errors})
})
},
setFieldMeta (state, {form, field, data}) {
state.meta = Object.assign({}, state.meta, {
[form]: Object.assign({}, state.meta[form] || {}, {[field]: data})
})
}
}, mutations)

View File

@ -5,7 +5,8 @@ test('initial store state', async t => {
t.deepEqual({
values: {},
errors: {},
validationErrors: {}
validationErrors: {},
meta: {}
}, formulateState()())
})
@ -14,6 +15,7 @@ test('extended initial store state', async t => {
values: {},
errors: {},
validationErrors: {},
meta: {},
additionalParam: 'test'
}, formulateState({
additionalParam: 'test'
@ -54,6 +56,23 @@ test('values getter', async t => {
t.is(formulateGetters().formValues(state), state.values)
})
test('formMeta getter', async t => {
let state = {
meta: {
form: {
name: {name: 'name', label: 'Name'},
flail: {name: 'email', label: 'Email'}
}
}
}
t.deepEqual(formulateGetters().formMeta(state), {
form: [
{name: 'name', label: 'Name'},
{name: 'email', label: 'Email'}
]
})
})
test('form has errors', async t => {
let state = {
errors: {