1
0
mirror of synced 2025-01-19 00:41:43 +03:00

Basic grouping inheritance working

This commit is contained in:
Justin Schroeder 2020-04-18 23:57:43 -04:00
parent 105cae1a78
commit 8b25eee634
7 changed files with 79 additions and 13 deletions

View File

@ -1,6 +1,7 @@
<template>
<div class="specimens specimens--group">
<FormulateInput
v-model="groupValue"
label="Invite some new users"
type="group"
placeholder="users"
@ -20,5 +21,16 @@
validation="required|email"
/>
</FormulateInput>
{{ groupValue }}
</div>
</template>
<script>
export default {
data () {
return {
groupValue: null
}
}
}
</script>

View File

@ -23,6 +23,7 @@ import FormulateInputButton from './inputs/FormulateInputButton.vue'
import FormulateInputSelect from './inputs/FormulateInputSelect.vue'
import FormulateInputSlider from './inputs/FormulateInputSlider.vue'
import FormulateInputTextArea from './inputs/FormulateInputTextArea.vue'
import FormulateRepeatableProvider from './slots/FormulateRepeatableProvider.vue'
/**
* The base formulate library.
@ -51,13 +52,13 @@ class Formulate {
FormulateInputButton,
FormulateInputSelect,
FormulateInputSlider,
FormulateInputTextArea
FormulateInputTextArea,
FormulateRepeatableProvider
},
slotDefaults: {
label: 'FormulateLabel',
help: 'FormulateHelp',
errors: 'FormulateErrors',
grouping: 'FormulateGrouping',
repeatable: 'FormulateRepeatable',
addMore: 'FormulateAddMore'
},

View File

@ -3,13 +3,15 @@
name="grouping"
:context="context"
>
<component
:is="context.slotComponents.repeatable"
<FormulateRepeatableProvider
v-for="(item, index) in items"
:key="index"
:index="index"
:set-field-value="setFieldValue"
:context="context"
>
<slot />
</component>
</FormulateRepeatableProvider>
<FormulateSlot
v-if="canAddMore"
name="addmore"
@ -30,22 +32,39 @@ export default {
required: true
}
},
provide () {
return {
formulateFormSetter: this.setFieldValue,
formulateFormRegister: this.register
}
},
computed: {
canAddMore () {
return (this.context.repeatable && this.items.length < this.context.limit)
},
items () {
return Array.isArray(this.context.model) ? this.context.model : []
return Array.isArray(this.context.model) ? this.context.model : [{}]
}
},
methods: {
addItem () {
const item = { id: this.items.length }
if (Array.isArray(this.context.model)) {
this.context.model.push(item)
this.context.model.push({})
return
}
this.context.model = [item]
this.context.model = this.items.concat([{}])
},
setFieldValue (index, field, value) {
const values = Array.isArray(this.context.model) ? this.context.model : []
values.splice(index, 1, Object.assign(
{},
typeof this.context.model[index] === 'object' ? this.context.model[index] : {},
{ [field]: value }
))
this.context.model = values
},
register () {
}
}
}

View File

@ -240,7 +240,6 @@ function slotComponents () {
label: this.$formulate.slotComponent(this.type, 'label'),
help: this.$formulate.slotComponent(this.type, 'help'),
errors: this.$formulate.slotComponent(this.type, 'errors'),
grouping: this.$formulate.slotComponent(this.type, 'grouping'),
repeatable: this.$formulate.slotComponent(this.type, 'repeatable'),
addMore: this.$formulate.slotComponent(this.type, 'addMore')
}

View File

@ -0,0 +1,33 @@
<template>
<FormulateSlot
name="repeatable"
>
<FormulateRepeatable>
<slot />
</FormulateRepeatable>
</FormulateSlot>
</template>
<script>
export default {
provide () {
return {
formulateFormSetter: (field, value) => this.setFieldValue(this.index, field, value)
}
},
props: {
index: {
type: Number,
required: true
},
context: {
type: Object,
required: true
},
setFieldValue: {
type: Function,
required: true
}
}
}
</script>

View File

@ -78,7 +78,8 @@ describe('Formulate', () => {
'FormulateInputButton',
'FormulateInputSelect',
'FormulateInputSlider',
'FormulateInputTextArea'
'FormulateInputTextArea',
'FormulateRepeatableProvider'
]
const registry = []
function Vue () {}

View File

@ -42,9 +42,10 @@
}
.formulate-input-group-item {
padding-bottom: 1.5em;
margin-bottom: 1.5em;
border-bottom: 1px solid $formulate-gray;
padding: 1.5em;
border: 1px solid $formulate-gray;
border-radius: .25em;
&:last-child {
margin-bottom: 1.5em;