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",
|
||||
placeholder: "First Name",
|
||||
label: "First Name",
|
||||
name: "firstName"
|
||||
},
|
||||
{
|
||||
fieldType: "textInput",
|
||||
placeholder: "Last Name",
|
||||
label: "Last Name",
|
||||
name: "lastName"
|
||||
placeholder: "Name",
|
||||
label: "Name",
|
||||
name: "name",
|
||||
value: "Squidward"
|
||||
},
|
||||
{
|
||||
fieldType: "numberInput",
|
||||
|
|
@ -110,7 +105,35 @@ export default {
|
|||
name: "age",
|
||||
label: "Age",
|
||||
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>
|
||||
<div>
|
||||
<component v-for="(field, index) in schema"
|
||||
:key="index"
|
||||
:is="field.fieldType"
|
||||
v-model="formData[field.name]"
|
||||
v-bind="field">
|
||||
<div class="uk-form-stacked">
|
||||
<div v-for="(field, index) in schema" :key="index">
|
||||
|
||||
<div v-if="Array.isArray(field)" class="uk-grid-small" uk-grid>
|
||||
<div v-for="(subfield, subindex) in field" :key="subindex" class="uk-width-expand">
|
||||
<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>
|
||||
</template>
|
||||
|
||||
|
|
@ -16,6 +28,8 @@ import numberInput from "./fieldComponents/numberInput";
|
|||
import selectList from "./fieldComponents/selectList";
|
||||
import textInput from "./fieldComponents/textInput";
|
||||
import htmlBlock from "./fieldComponents/htmlBlock";
|
||||
import radioList from "./fieldComponents/radioList";
|
||||
import checkList from "./fieldComponents/checkList"
|
||||
|
||||
export default {
|
||||
name: 'JsonForm',
|
||||
|
|
@ -24,7 +38,9 @@ export default {
|
|||
numberInput,
|
||||
selectList,
|
||||
textInput,
|
||||
htmlBlock
|
||||
htmlBlock,
|
||||
radioList,
|
||||
checkList
|
||||
},
|
||||
|
||||
props: {
|
||||
|
|
@ -43,8 +59,24 @@ export default {
|
|||
created: function () {
|
||||
// `this` points to the vm instance
|
||||
console.log(this.schema)
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateForm(fieldName, value) {
|
||||
console.log(`${fieldName}: ${value}`)
|
||||
this.$set(this.formData, fieldName, value);
|
||||
this.$emit('input', this.formData)
|
||||
}
|
||||
}
|
||||
}
|
||||
</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>
|
||||
export default {
|
||||
name: 'textInput',
|
||||
|
||||
props: [
|
||||
'label',
|
||||
'name',
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
<template>
|
||||
<div>
|
||||
<label>{{label}}</label>
|
||||
<label class="uk-form-label">{{label}}</label>
|
||||
|
||||
<input
|
||||
class="uk-input uk-form-small"
|
||||
type="number"
|
||||
:name="name"
|
||||
:value="value"
|
||||
|
|
@ -17,7 +18,16 @@
|
|||
|
||||
export default {
|
||||
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>
|
||||
<div>
|
||||
<label>{{label}}</label>
|
||||
<select :multiple="multi"
|
||||
:value="value"
|
||||
@input="$emit('input',
|
||||
$event.target.value)">
|
||||
<option v-for="option in options"
|
||||
:key="option">
|
||||
<label class="uk-form-label">{{label}}</label>
|
||||
|
||||
<select
|
||||
class="uk-select uk-form-small"
|
||||
:multiple="multi"
|
||||
:value="value"
|
||||
@input="$emit('input', $event.target.value)"
|
||||
>
|
||||
<option v-for="option in options" :key="option">
|
||||
{{option}}
|
||||
</option>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -16,6 +19,7 @@
|
|||
<script>
|
||||
export default {
|
||||
name: 'selectList',
|
||||
|
||||
props: [
|
||||
'multi',
|
||||
'options',
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
<template>
|
||||
<div>
|
||||
<label>{{label}}</label>
|
||||
<label class="uk-form-label">{{label}}</label>
|
||||
|
||||
<input
|
||||
class="uk-input uk-form-small"
|
||||
type="text"
|
||||
:name="name"
|
||||
:value="value"
|
||||
v-bind:name="name"
|
||||
v-bind:value="value"
|
||||
v-bind:placeholder="placeholder"
|
||||
@input="$emit('input',$event.target.value)"
|
||||
:placeholder="placeholder"
|
||||
>
|
||||
|
||||
</div>
|
||||
|
|
@ -16,6 +17,7 @@
|
|||
<script>
|
||||
export default {
|
||||
name: 'textInput',
|
||||
|
||||
props: [
|
||||
'placeholder',
|
||||
'label',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue