Reputation: 125
I am learning vue.js. I am trying to build a form dynamically from data. The form is condition based. If I select some field from the select field the specific content related to that option has to show.
Here is the data
If the model of "id: 2" object is "germany", the show from "id: 3" has to become true and the show from 'id:4" and "id: 5" has to become false.
Similarly, If the model of "id: 2" object is "us", the show from the id: 4 has to become true and the show from "id:3" and "id: 5" has to become false.
data(){
return{
fields: [
{
id: 1,
type: "text",
placeholder: "Name",
model: "",
show: true
},
{
id: 2,
type: "select",
placeholder: "Select",
model: "",
show: true,
options: [
{value: "germany", text: "Gemany", id: "germany"},
{value: "us", text: "United States", id: "us"},
{value: "uk", text: "United Kingdom", id: "uk"}
],
events: "onChange"
},
{
id: 3,
type: "paragraph",
text: "Berlin",
show: false
},
{
id: 4,
type: "paragraph",
text: "New York",
show: false
},
{
id: 5,
type: "paragraph",
text: "London",
show: false
}
]
}
}
Here is template
<template>
<div>
<div class="" v-for="field in fields" :key="field.id">
<input :type="field.type" :placeholder="field.placeholder" v-model="field.model" :id="field.id" v-if="field.type == 'text' && field.show">
<select v-model="field.model" :id="field.id" v-if="field.type == 'select' && field.show" @change="onChange(field.id)">
<option v-for="option in field.options" :key="option.id" :value="option.value" :id="option.id">{{option.text}}</option>
</select>
<p v-if="field.type == 'paragraph' && field.show" :id="field.id">{{field.text}}</p>
</div>
<button @click="submit">Submit</button>
</div>
</template>
methods
onChange(e){
console.log(e)
}
How can I achieve this? Thank you.
Upvotes: 1
Views: 1251
Reputation: 5609
v-model
on select does the job to find the selected value.
First, you can add an new property (option_id
for example) to create a link between your option field id
and your paragraph field option_id
.
Then add a selectedOptionId
data used for v-model
to reach the right selected field.
You can now put this selected field out of the v-for
loop and remove the show
and model
properties:
new Vue({
el: "#app",
data(){
return{
selectedOptionId: '',
fields: [
{
id: 1,
type: "text",
placeholder: "Name",
model: "",
},
{
id: 2,
type: "select",
placeholder: "Select",
options: [
{value: "germany", text: "Gemany", id: "germany"},
{value: "us", text: "United States", id: "us"},
{value: "uk", text: "United Kingdom", id: "uk"}
]
},
{
id: 3,
option_id: "germany",
type: "paragraph",
text: "Berlin",
},
{
id: 4,
option_id: "us",
type: "paragraph",
text: "New York",
},
{
id: 5,
option_id: "uk",
type: "paragraph",
text: "London",
}
]
}
},
computed: {
selectedField(){
return this.fields.find(field => field.option_id == this.selectedOptionId)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
<div v-for="field in fields" :key="field.id">
<input :type="field.type" :placeholder="field.placeholder" v-model="field.model" :id="field.id" v-if="field.type == 'text'">
<select v-model="selectedOptionId" :id="field.id" v-if="field.type == 'select'">
<option v-for="option in field.options" :key="option.id" :value="option.id" :id="option.id">{{option.text}}</option>
</select>
</div>
<p v-if="selectedField" :id="selectedField.id">{{selectedField.text}}</p>
</div>
Upvotes: 1
Reputation: 4657
This could be a solution: in your data you could add a variable idToShowMain
, which is an array of id you want to show. You will initialize it with the default visualization:
idToShowMain: [ 1,2 ],
Then in your options you will add a property for each item with the array related to that option. When the value changes you will replace the main array with the one selected.
options: [
{value: "germany", text: "Gemany", id: "germany", idToShow: [ 1,2,3 ] },
{value: "us", text: "United States", id: "us", idToShow: [ 1,2,4 ] },
{value: "uk", text: "United Kingdom", id: "uk", idToShow: [ 1,2 ] }
],
At the end you will change your template in this way:
<div class="" v-for="field in fields" :key="field.id" v-if="idToShowMain.includes(field.id)">
In this way you could remove the show
property from each field.
Hope this helps you.
Upvotes: 0