Skip to content

Commit 8e3ca76

Browse files
Adds initial grouping tests and first functional, repeatable, modelable grouped fields
1 parent 430f27f commit 8e3ca76

11 files changed

+309
-102
lines changed

examples/specimens/SpecimenGroup.vue

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
<template>
22
<div class="specimens specimens--group">
33
<FormulateForm
4-
v-model="formResult"
4+
v-model="formData"
55
@submit="save"
66
>
77
<FormulateInput
8+
v-model="users"
89
name="users"
910
label="Invite some new users"
1011
type="group"
1112
placeholder="users"
1213
help="Fields can be grouped"
14+
:repeatable="true"
1315
>
1416
<FormulateInput
1517
label="First and last name"
@@ -18,6 +20,7 @@
1820
placeholder="User’s name"
1921
/>
2022
<FormulateInput
23+
v-model="email"
2124
name="email"
2225
label="Email address"
2326
type="email"
@@ -30,17 +33,25 @@
3033
/>
3134
</FormulateForm>
3235
<span>Form Values</span>
33-
<pre>{{ formResult }}</pre>
36+
<pre>{{ formData }}</pre>
3437
<span>Save Values</span>
3538
<pre>{{ saveValues }}</pre>
39+
<pre>{{ email }}</pre>
40+
<pre>{{ users }}</pre>
3641
</div>
3742
</template>
3843

3944
<script>
4045
export default {
4146
data () {
4247
return {
43-
formResult: null,
48+
formData: {
49+
},
50+
users: [
51+
{ name: 'Justin' },
52+
{ name: 'Bob' }
53+
],
54+
4455
saveValues: null
4556
}
4657
},

src/FormSubmission.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ export default class FormSubmission {
2626
values () {
2727
return new Promise((resolve, reject) => {
2828
const pending = []
29-
const values = cloneDeep(this.form.internalFormModelProxy)
29+
const values = cloneDeep(this.form.proxy)
3030
for (const key in values) {
31-
if (typeof this.form.internalFormModelProxy[key] === 'object' && this.form.internalFormModelProxy[key] instanceof FileUpload) {
31+
if (typeof this.form.proxy[key] === 'object' && this.form.proxy[key] instanceof FileUpload) {
3232
pending.push(
33-
this.form.internalFormModelProxy[key].upload().then(data => Object.assign(values, { [key]: data }))
33+
this.form.proxy[key].upload().then(data => Object.assign(values, { [key]: data }))
3434
)
3535
}
3636
}

src/FormulateForm.vue

Lines changed: 7 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,13 @@
1313

1414
<script>
1515
import { shallowEqualObjects, arrayify, has } from './libs/utils'
16-
import Registry from './libs/registry'
16+
import useRegistry, { useRegistryComputed, useRegistryMethods, useRegistryProviders } from './libs/registry'
1717
import FormSubmission from './FormSubmission'
1818
1919
export default {
2020
provide () {
2121
return {
22-
formulateFormSetter: this.setFieldValue,
23-
formulateFormRegister: this.register,
24-
getFormValues: this.getFormValues,
22+
...useRegistryProviders(this),
2523
observeErrors: this.addErrorObserver,
2624
removeErrorObserver: this.removeErrorObserver,
2725
formulateFieldValidation: this.formulateFieldValidation
@@ -56,52 +54,20 @@ export default {
5654
},
5755
data () {
5856
return {
59-
registry: new Registry(),
60-
internalFormModelProxy: {},
57+
...useRegistry(this),
6158
formShouldShowErrors: false,
6259
errorObservers: [],
6360
namedErrors: [],
6461
namedFieldErrors: {}
6562
}
6663
},
6764
computed: {
68-
/**
69-
* @todo in 2.3.0 this will expand and be extracted to a separate module to
70-
* support better scoped slot interoperability.
71-
*/
65+
...useRegistryComputed(),
7266
formContext () {
7367
return {
7468
errors: this.mergedFormErrors
7569
}
7670
},
77-
hasInitialValue () {
78-
return (
79-
(this.formulateValue && typeof this.formulateValue === 'object') ||
80-
(this.values && typeof this.values === 'object')
81-
)
82-
},
83-
isVmodeled () {
84-
return !!(this.$options.propsData.hasOwnProperty('formulateValue') &&
85-
this._events &&
86-
Array.isArray(this._events.input) &&
87-
this._events.input.length)
88-
},
89-
initialValues () {
90-
if (
91-
has(this.$options.propsData, 'formulateValue') &&
92-
typeof this.formulateValue === 'object'
93-
) {
94-
// If there is a v-model on the form, use those values as first priority
95-
return Object.assign({}, this.formulateValue) // @todo - use a deep clone to detach reference types
96-
} else if (
97-
has(this.$options.propsData, 'values') &&
98-
typeof this.values === 'object'
99-
) {
100-
// If there are values, use them as secondary priority
101-
return Object.assign({}, this.values)
102-
}
103-
return {}
104-
},
10571
classes () {
10672
const classes = { 'formulate-form': true }
10773
if (this.name) {
@@ -137,11 +103,11 @@ export default {
137103
) {
138104
for (const field in newValue) {
139105
if (this.registry.has(field) &&
140-
!shallowEqualObjects(newValue[field], this.internalFormModelProxy[field]) &&
106+
!shallowEqualObjects(newValue[field], this.proxy[field]) &&
141107
!shallowEqualObjects(newValue[field], this.registry.get(field).internalModelProxy[field])
142108
) {
143109
this.setFieldValue(field, newValue[field])
144-
this.registry[field].context.model = newValue[field]
110+
this.registry.get(field).context.model = newValue[field]
145111
}
146112
}
147113
}
@@ -170,11 +136,7 @@ export default {
170136
this.$formulate.deregister(this)
171137
},
172138
methods: {
173-
applyInitialValues () {
174-
if (this.hasInitialValue) {
175-
this.internalFormModelProxy = this.initialValues
176-
}
177-
},
139+
...useRegistryMethods(),
178140
applyErrors ({ formErrors, inputErrors }) {
179141
// given an object of errors, apply them to this form
180142
this.namedErrors = formErrors
@@ -193,36 +155,6 @@ export default {
193155
removeErrorObserver (observer) {
194156
this.errorObservers = this.errorObservers.filter(obs => obs.callback !== observer)
195157
},
196-
setFieldValue (field, value) {
197-
Object.assign(this.internalFormModelProxy, { [field]: value })
198-
this.$emit('input', Object.assign({}, this.internalFormModelProxy))
199-
},
200-
register (field, component) {
201-
// Don't re-register fields... @todo come up with another way of handling this that doesn't break multi option
202-
if (this.registry.has(field)) {
203-
return false
204-
}
205-
this.registry.add(field, component)
206-
const hasVModelValue = has(component.$options.propsData, 'formulateValue')
207-
const hasValue = has(component.$options.propsData, 'value')
208-
if (
209-
!component.context.isSubField() &&
210-
!hasVModelValue &&
211-
this.hasInitialValue &&
212-
this.initialValues[field]
213-
) {
214-
// In the case that the form is carrying an initial value and the
215-
// element is not, set it directly.
216-
component.context.model = this.initialValues[field]
217-
} else if (
218-
(hasVModelValue || hasValue) &&
219-
!shallowEqualObjects(component.internalModelProxy, this.initialValues[field])
220-
) {
221-
// In this case, the field is v-modeled or has an initial value and the
222-
// form has no value or a different value, so use the field value
223-
this.setFieldValue(field, component.internalModelProxy)
224-
}
225-
},
226158
registerErrorComponent (component) {
227159
if (!this.errorComponents.includes(component)) {
228160
this.errorComponents.push(component)
@@ -248,9 +180,6 @@ export default {
248180
input.formShouldShowErrors = true
249181
})
250182
},
251-
getFormValues () {
252-
return this.internalFormModelProxy
253-
},
254183
formulateFieldValidation (errorObject) {
255184
this.$emit('validation', errorObject)
256185
},

src/FormulateGrouping.vue

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
</template>
2727

2828
<script>
29+
2930
export default {
31+
name: 'FormulateGrouping',
3032
props: {
3133
context: {
3234
type: Object,
@@ -35,8 +37,6 @@ export default {
3537
},
3638
provide () {
3739
return {
38-
formulateFormSetter: this.setFieldValue,
39-
formulateFormRegister: this.register,
4040
isSubField: () => true
4141
}
4242
},
@@ -64,9 +64,6 @@ export default {
6464
{ [field]: value }
6565
))
6666
this.context.model = values
67-
},
68-
register (field, component) {
69-
7067
}
7168
}
7269
}

src/FormulateInput.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ export default {
7474
name: 'FormulateInput',
7575
inheritAttrs: false,
7676
inject: {
77-
formulateFormSetter: { default: undefined },
77+
formulateSetter: { default: undefined },
7878
formulateFieldValidation: { default: () => () => ({}) },
79-
formulateFormRegister: { default: undefined },
79+
formulateRegister: { default: undefined },
8080
getFormValues: { default: () => () => ({}) },
8181
observeErrors: { default: undefined },
8282
removeErrorObserver: { default: undefined },
@@ -141,7 +141,7 @@ export default {
141141
},
142142
repeatable: {
143143
type: Boolean,
144-
default: true
144+
default: false
145145
},
146146
validation: {
147147
type: [String, Boolean, Array],
@@ -270,8 +270,8 @@ export default {
270270
},
271271
created () {
272272
this.applyInitialValue()
273-
if (this.formulateFormRegister && typeof this.formulateFormRegister === 'function') {
274-
this.formulateFormRegister(this.nameOrFallback, this)
273+
if (this.formulateRegister && typeof this.formulateRegister === 'function') {
274+
this.formulateRegister(this.nameOrFallback, this)
275275
}
276276
if (!this.disableErrors && typeof this.observeErrors === 'function') {
277277
this.observeErrors({ callback: this.setErrors, type: 'input', field: this.nameOrFallback })

src/libs/context.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ function modelSetter (value) {
289289
this.internalModelProxy = value
290290
}
291291
this.$emit('input', value)
292-
if (this.context.name && typeof this.formulateFormSetter === 'function') {
293-
this.formulateFormSetter(this.context.name, value)
292+
if (this.context.name && typeof this.formulateSetter === 'function') {
293+
this.formulateSetter(this.context.name, value)
294294
}
295295
}

0 commit comments

Comments
 (0)