Added strict one-way binding to all form components
This commit is contained in:
parent
4a0351f80c
commit
5e69e52bcd
8 changed files with 181 additions and 33 deletions
|
|
@ -94,15 +94,10 @@ export default {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldType: "textInput",
|
fieldType: "textInput",
|
||||||
placeholder: "First Name",
|
placeholder: "Name",
|
||||||
label: "First Name",
|
label: "Name",
|
||||||
name: "firstName"
|
name: "name",
|
||||||
},
|
value: "Squidward"
|
||||||
{
|
|
||||||
fieldType: "textInput",
|
|
||||||
placeholder: "Last Name",
|
|
||||||
label: "Last Name",
|
|
||||||
name: "lastName"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldType: "numberInput",
|
fieldType: "numberInput",
|
||||||
|
|
@ -110,7 +105,35 @@ export default {
|
||||||
name: "age",
|
name: "age",
|
||||||
label: "Age",
|
label: "Age",
|
||||||
minValue: 0
|
minValue: 0
|
||||||
}
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
fieldType: "numberInput",
|
||||||
|
placeholder: "Number",
|
||||||
|
name: "leftnum",
|
||||||
|
label: "Left"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldType: "numberInput",
|
||||||
|
placeholder: "Number",
|
||||||
|
name: "rightnum",
|
||||||
|
label: "Right"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{
|
||||||
|
fieldType: "radioList",
|
||||||
|
name: "coolness",
|
||||||
|
label: "Coolness",
|
||||||
|
options: ["None", "Some", "Very"],
|
||||||
|
value: "Some"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldType: "checkList",
|
||||||
|
name: "ingredients",
|
||||||
|
label: "Ingredients",
|
||||||
|
options: ["Pork", "Pie"],
|
||||||
|
value: ["Pork"]
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,24 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="uk-form-stacked">
|
||||||
<component v-for="(field, index) in schema"
|
<div v-for="(field, index) in schema" :key="index">
|
||||||
:key="index"
|
|
||||||
:is="field.fieldType"
|
<div v-if="Array.isArray(field)" class="uk-grid-small" uk-grid>
|
||||||
v-model="formData[field.name]"
|
<div v-for="(subfield, subindex) in field" :key="subindex" class="uk-width-expand">
|
||||||
v-bind="field">
|
<component
|
||||||
|
:is="subfield.fieldType"
|
||||||
|
@input="updateForm(subfield.name, $event)"
|
||||||
|
v-bind="subfield">
|
||||||
|
</component>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<component
|
||||||
|
:is="field.fieldType"
|
||||||
|
@input="updateForm(field.name, $event)"
|
||||||
|
v-bind="field">
|
||||||
|
</component>
|
||||||
|
|
||||||
</component>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -16,6 +28,8 @@ import numberInput from "./fieldComponents/numberInput";
|
||||||
import selectList from "./fieldComponents/selectList";
|
import selectList from "./fieldComponents/selectList";
|
||||||
import textInput from "./fieldComponents/textInput";
|
import textInput from "./fieldComponents/textInput";
|
||||||
import htmlBlock from "./fieldComponents/htmlBlock";
|
import htmlBlock from "./fieldComponents/htmlBlock";
|
||||||
|
import radioList from "./fieldComponents/radioList";
|
||||||
|
import checkList from "./fieldComponents/checkList"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'JsonForm',
|
name: 'JsonForm',
|
||||||
|
|
@ -24,7 +38,9 @@ export default {
|
||||||
numberInput,
|
numberInput,
|
||||||
selectList,
|
selectList,
|
||||||
textInput,
|
textInput,
|
||||||
htmlBlock
|
htmlBlock,
|
||||||
|
radioList,
|
||||||
|
checkList
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
|
|
@ -43,8 +59,24 @@ export default {
|
||||||
created: function () {
|
created: function () {
|
||||||
// `this` points to the vm instance
|
// `this` points to the vm instance
|
||||||
console.log(this.schema)
|
console.log(this.schema)
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
updateForm(fieldName, value) {
|
||||||
|
console.log(`${fieldName}: ${value}`)
|
||||||
|
this.$set(this.formData, fieldName, value);
|
||||||
|
this.$emit('input', this.formData)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
.flex-container {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-container > div {
|
||||||
|
flex-basis: 100%
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<label>{{label}}</label>
|
||||||
|
|
||||||
|
<div class="uk-form-controls">
|
||||||
|
|
||||||
|
<div v-for="option in options" :key="option">
|
||||||
|
<label><input class="uk-checkbox" type="checkbox" v-bind:value="option" v-model="computedChecked"> {{ option }}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'checkList',
|
||||||
|
|
||||||
|
props: [
|
||||||
|
'options',
|
||||||
|
'name',
|
||||||
|
'label',
|
||||||
|
'value'
|
||||||
|
],
|
||||||
|
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
itemsChecked: this.value || []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
computedChecked: {
|
||||||
|
get() {
|
||||||
|
return this.itemsChecked
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.itemsChecked = val
|
||||||
|
this.$emit('input', this.itemsChecked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'textInput',
|
name: 'textInput',
|
||||||
|
|
||||||
props: [
|
props: [
|
||||||
'label',
|
'label',
|
||||||
'name',
|
'name',
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<label>{{label}}</label>
|
<label class="uk-form-label">{{label}}</label>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
|
class="uk-input uk-form-small"
|
||||||
type="number"
|
type="number"
|
||||||
:name="name"
|
:name="name"
|
||||||
:value="value"
|
:value="value"
|
||||||
|
|
@ -17,7 +18,16 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'numberInput',
|
name: 'numberInput',
|
||||||
props: ['placeholder', 'label', 'name', 'value']
|
|
||||||
|
props: [
|
||||||
|
'placeholder',
|
||||||
|
'label',
|
||||||
|
'name',
|
||||||
|
'value'
|
||||||
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<label>{{label}}</label>
|
||||||
|
|
||||||
|
<div class="uk-form-controls">
|
||||||
|
|
||||||
|
<div v-for="option in options" :key="option">
|
||||||
|
<label><input class="uk-radio" type="radio" :name="name" :value="option" :checked="value==option" @input="$emit('input', $event.target.value)"> {{ option }}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'radioList',
|
||||||
|
|
||||||
|
props: [
|
||||||
|
'options',
|
||||||
|
'name',
|
||||||
|
'label',
|
||||||
|
'value'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<label>{{label}}</label>
|
<label class="uk-form-label">{{label}}</label>
|
||||||
<select :multiple="multi"
|
|
||||||
:value="value"
|
<select
|
||||||
@input="$emit('input',
|
class="uk-select uk-form-small"
|
||||||
$event.target.value)">
|
:multiple="multi"
|
||||||
<option v-for="option in options"
|
:value="value"
|
||||||
:key="option">
|
@input="$emit('input', $event.target.value)"
|
||||||
|
>
|
||||||
|
<option v-for="option in options" :key="option">
|
||||||
{{option}}
|
{{option}}
|
||||||
</option>
|
</option>
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -16,6 +19,7 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'selectList',
|
name: 'selectList',
|
||||||
|
|
||||||
props: [
|
props: [
|
||||||
'multi',
|
'multi',
|
||||||
'options',
|
'options',
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<label>{{label}}</label>
|
<label class="uk-form-label">{{label}}</label>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
|
class="uk-input uk-form-small"
|
||||||
type="text"
|
type="text"
|
||||||
:name="name"
|
v-bind:name="name"
|
||||||
:value="value"
|
v-bind:value="value"
|
||||||
|
v-bind:placeholder="placeholder"
|
||||||
@input="$emit('input',$event.target.value)"
|
@input="$emit('input',$event.target.value)"
|
||||||
:placeholder="placeholder"
|
|
||||||
>
|
>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -16,6 +17,7 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'textInput',
|
name: 'textInput',
|
||||||
|
|
||||||
props: [
|
props: [
|
||||||
'placeholder',
|
'placeholder',
|
||||||
'label',
|
'label',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue