Adds initial grouping capability
This commit is contained in:
parent
dfef74cd27
commit
105cae1a78
@ -7,12 +7,14 @@
|
|||||||
help="Fields can be grouped"
|
help="Fields can be grouped"
|
||||||
>
|
>
|
||||||
<FormulateInput
|
<FormulateInput
|
||||||
|
label="First and last name"
|
||||||
name="Name"
|
name="Name"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="User’s name"
|
placeholder="User’s name"
|
||||||
/>
|
/>
|
||||||
<FormulateInput
|
<FormulateInput
|
||||||
name="Email"
|
name="Email"
|
||||||
|
label="Email address"
|
||||||
type="email"
|
type="email"
|
||||||
placeholder="User’s email"
|
placeholder="User’s email"
|
||||||
validation="required|email"
|
validation="required|email"
|
||||||
|
5222
package-lock.json
generated
5222
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -7,12 +7,13 @@ import isPlainObject from 'is-plain-object'
|
|||||||
import { en } from '@braid/vue-formulate-i18n'
|
import { en } from '@braid/vue-formulate-i18n'
|
||||||
import fauxUploader from './libs/faux-uploader'
|
import fauxUploader from './libs/faux-uploader'
|
||||||
import FormulateSlot from './FormulateSlot'
|
import FormulateSlot from './FormulateSlot'
|
||||||
import FormulateInput from './FormulateInput.vue'
|
|
||||||
import FormulateForm from './FormulateForm.vue'
|
import FormulateForm from './FormulateForm.vue'
|
||||||
|
import FormulateInput from './FormulateInput.vue'
|
||||||
import FormulateErrors from './FormulateErrors.vue'
|
import FormulateErrors from './FormulateErrors.vue'
|
||||||
import FormulateHelp from './slots/FormulateHelp.vue'
|
import FormulateHelp from './slots/FormulateHelp.vue'
|
||||||
import FormulateGrouping from './FormulateGrouping.vue'
|
import FormulateGrouping from './FormulateGrouping.vue'
|
||||||
import FormulateLabel from './slots/FormulateLabel.vue'
|
import FormulateLabel from './slots/FormulateLabel.vue'
|
||||||
|
import FormulateAddMore from './slots/FormulateAddMore.vue'
|
||||||
import FormulateInputBox from './inputs/FormulateInputBox.vue'
|
import FormulateInputBox from './inputs/FormulateInputBox.vue'
|
||||||
import FormulateInputText from './inputs/FormulateInputText.vue'
|
import FormulateInputText from './inputs/FormulateInputText.vue'
|
||||||
import FormulateInputFile from './inputs/FormulateInputFile.vue'
|
import FormulateInputFile from './inputs/FormulateInputFile.vue'
|
||||||
@ -40,6 +41,7 @@ class Formulate {
|
|||||||
FormulateLabel,
|
FormulateLabel,
|
||||||
FormulateInput,
|
FormulateInput,
|
||||||
FormulateErrors,
|
FormulateErrors,
|
||||||
|
FormulateAddMore,
|
||||||
FormulateGrouping,
|
FormulateGrouping,
|
||||||
FormulateInputBox,
|
FormulateInputBox,
|
||||||
FormulateInputText,
|
FormulateInputText,
|
||||||
@ -54,7 +56,10 @@ class Formulate {
|
|||||||
slotDefaults: {
|
slotDefaults: {
|
||||||
label: 'FormulateLabel',
|
label: 'FormulateLabel',
|
||||||
help: 'FormulateHelp',
|
help: 'FormulateHelp',
|
||||||
errors: 'FormulateErrors'
|
errors: 'FormulateErrors',
|
||||||
|
grouping: 'FormulateGrouping',
|
||||||
|
repeatable: 'FormulateRepeatable',
|
||||||
|
addMore: 'FormulateAddMore'
|
||||||
},
|
},
|
||||||
library,
|
library,
|
||||||
rules,
|
rules,
|
||||||
@ -160,8 +165,8 @@ class Formulate {
|
|||||||
*/
|
*/
|
||||||
slotComponent (type, slot) {
|
slotComponent (type, slot) {
|
||||||
const def = this.options.library[type]
|
const def = this.options.library[type]
|
||||||
if (def.slots && def.slots[slot]) {
|
if (def.slotComponents && def.slotComponents[slot]) {
|
||||||
return def.slots[slot]
|
return def.slotComponents[slot]
|
||||||
}
|
}
|
||||||
return this.options.slotDefaults[slot]
|
return this.options.slotDefaults[slot]
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<FormulateSlot
|
<FormulateSlot
|
||||||
name="repeatable"
|
name="grouping"
|
||||||
|
:context="context"
|
||||||
>
|
>
|
||||||
<FormulateRepeatable
|
<component
|
||||||
v-for="item in items"
|
:is="context.slotComponents.repeatable"
|
||||||
:key="item.id"
|
v-for="(item, index) in items"
|
||||||
|
:key="index"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</FormulateRepeatable>
|
</component>
|
||||||
|
<FormulateSlot
|
||||||
|
v-if="canAddMore"
|
||||||
|
name="addmore"
|
||||||
|
>
|
||||||
|
<component
|
||||||
|
:is="context.slotComponents.addMore"
|
||||||
|
@add="addItem"
|
||||||
|
/>
|
||||||
|
</FormulateSlot>
|
||||||
</FormulateSlot>
|
</FormulateSlot>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -20,8 +31,21 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
canAddMore () {
|
||||||
|
return (this.context.repeatable && this.items.length < this.context.limit)
|
||||||
|
},
|
||||||
items () {
|
items () {
|
||||||
return [{ id: 1 }, { id: 2 }]
|
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)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.context.model = [item]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,6 +122,10 @@ export default {
|
|||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
limit: {
|
||||||
|
type: Number,
|
||||||
|
default: Infinity
|
||||||
|
},
|
||||||
help: {
|
help: {
|
||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: false
|
default: false
|
||||||
@ -134,6 +138,10 @@ export default {
|
|||||||
type: [String, Array, Boolean],
|
type: [String, Array, Boolean],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
repeatable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
validation: {
|
validation: {
|
||||||
type: [String, Boolean, Array],
|
type: [String, Boolean, Array],
|
||||||
default: false
|
default: false
|
||||||
|
@ -7,7 +7,7 @@ export default {
|
|||||||
p = p.$parent
|
p = p.$parent
|
||||||
}
|
}
|
||||||
if (p.$scopedSlots && p.$scopedSlots[props.name]) {
|
if (p.$scopedSlots && p.$scopedSlots[props.name]) {
|
||||||
return p.$scopedSlots[props.name](props)
|
return p.$scopedSlots[props.name](props.context || props)
|
||||||
}
|
}
|
||||||
return h('div', data, children)
|
return h('div', data, children)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import nanoid from 'nanoid/non-secure'
|
|
||||||
import { map, arrayify, shallowEqualObjects } from './utils'
|
import { map, arrayify, shallowEqualObjects } from './utils'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,9 +22,11 @@ export default {
|
|||||||
imageBehavior: this.imageBehavior,
|
imageBehavior: this.imageBehavior,
|
||||||
label: this.label,
|
label: this.label,
|
||||||
labelPosition: this.logicalLabelPosition,
|
labelPosition: this.logicalLabelPosition,
|
||||||
|
limit: this.limit,
|
||||||
name: this.nameOrFallback,
|
name: this.nameOrFallback,
|
||||||
performValidation: this.performValidation.bind(this),
|
performValidation: this.performValidation.bind(this),
|
||||||
preventWindowDrops: this.preventWindowDrops,
|
preventWindowDrops: this.preventWindowDrops,
|
||||||
|
repeatable: this.repeatable,
|
||||||
setErrors: this.setErrors.bind(this),
|
setErrors: this.setErrors.bind(this),
|
||||||
showValidationErrors: this.showValidationErrors,
|
showValidationErrors: this.showValidationErrors,
|
||||||
slotComponents: this.slotComponents,
|
slotComponents: this.slotComponents,
|
||||||
@ -238,7 +239,10 @@ function slotComponents () {
|
|||||||
return {
|
return {
|
||||||
label: this.$formulate.slotComponent(this.type, 'label'),
|
label: this.$formulate.slotComponent(this.type, 'label'),
|
||||||
help: this.$formulate.slotComponent(this.type, 'help'),
|
help: this.$formulate.slotComponent(this.type, 'help'),
|
||||||
errors: this.$formulate.slotComponent(this.type, 'errors')
|
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')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
src/slots/FormulateAddMore.vue
Normal file
13
src/slots/FormulateAddMore.vue
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div class="formulate-input-group-add-more">
|
||||||
|
<button @click="$emit('add')">
|
||||||
|
Add more
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="formulate-group-row"
|
class="formulate-input-group-item"
|
||||||
>
|
>
|
||||||
<FormulateSlot
|
<FormulateSlot
|
||||||
name="default"
|
name="default"
|
||||||
|
@ -68,6 +68,7 @@ describe('Formulate', () => {
|
|||||||
'FormulateLabel',
|
'FormulateLabel',
|
||||||
'FormulateInput',
|
'FormulateInput',
|
||||||
'FormulateErrors',
|
'FormulateErrors',
|
||||||
|
'FormulateAddMore',
|
||||||
'FormulateGrouping',
|
'FormulateGrouping',
|
||||||
'FormulateInputBox',
|
'FormulateInputBox',
|
||||||
'FormulateInputText',
|
'FormulateInputText',
|
||||||
|
@ -42,7 +42,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.formulate-input-group-item {
|
.formulate-input-group-item {
|
||||||
margin-bottom: .5em;
|
padding-bottom: 1.5em;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
border-bottom: 1px solid $formulate-gray;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
border-bottom: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user