1
0
mirror of synced 2024-11-26 15:26:02 +03:00
vue-formulario/src/FormulateForm.vue

111 lines
3.0 KiB
Vue

<template>
<form
@submit.prevent="formSubmitted"
>
<slot />
</form>
</template>
<script>
import { shallowEqualObjects } from './libs/utils'
export default {
provide () {
return {
formulateFormSetter: this.setFieldValue,
formulateFormRegister: this.register,
getFormValues: this.getFormValues
}
},
name: 'FormulateForm',
model: {
prop: 'formulateValue',
event: 'input'
},
props: {
name: {
type: [String, Boolean],
default: false
},
formulateValue: {
type: Object,
default: () => ({})
}
},
data () {
return {
registry: {},
internalFormModelProxy: {},
formShouldShowErrors: false
}
},
computed: {
hasFormulateValue () {
return this.formulateValue && typeof this.formulateValue === 'object'
},
isVmodeled () {
return !!(this.$options.propsData.hasOwnProperty('formulateValue') &&
this._events &&
Array.isArray(this._events.input) &&
this._events.input.length)
}
},
watch: {
formulateValue: {
handler (newValue, oldValue) {
if (this.isVmodeled &&
newValue &&
typeof newValue === 'object'
) {
for (const field in newValue) {
if (this.registry.hasOwnProperty(field) &&
!shallowEqualObjects(newValue[field], this.internalFormModelProxy[field]) &&
!shallowEqualObjects(newValue[field], this.registry[field].internalModelProxy[field])
) {
this.setFieldValue(field, newValue[field])
this.registry[field].context.model = newValue[field]
}
}
}
},
deep: true,
immediate: false
}
},
created () {
if (this.$options.propsData.hasOwnProperty('formulateValue')) {
this.internalFormModelProxy = Object.assign({}, this.formulateValue)
}
},
methods: {
setFieldValue (field, value) {
Object.assign(this.internalFormModelProxy, { [field]: value })
this.$emit('input', Object.assign({}, this.internalFormModelProxy))
},
register (field, component) {
this.registry[field] = component
if (!component.$options.propsData.hasOwnProperty('formulateValue') && this.hasFormulateValue && this.formulateValue[field]) {
// In the case that the form is carrying an initial value and the
// element is not, set it directly.
component.context.model = this.formulateValue[field]
} else if (component.$options.propsData.hasOwnProperty('formulateValue') && !shallowEqualObjects(component.internalModelProxy, this.formulateValue[field])) {
this.setFieldValue(field, component.internalModelProxy)
}
},
formSubmitted () {
// perform validation here
this.showErrors()
this.$emit('submit', this.internalFormModelProxy)
},
showErrors () {
for (const fieldName in this.registry) {
this.registry[fieldName].formShouldShowErrors = true
}
},
getFormValues () {
return this.internalFormModelProxy
}
}
}
</script>