I am trying to create a form in vuejs, where a group of inputs can be append onclick. It works fine, but the problem is, All inputs return the same value. I am sharing an image here :
I am sharing my code from template :
<div v-for="(input,k) in data.invoice_product" :key="k">
<div >
<div >
<select v-model="data.invoice_product.product_id"
@change="getProductCost">
<option v-for="(product, i) in products" :key="i" :value="product.id">{{
product.product_name }}</option>
</select>
</div>
<div >
<input type="text" placeholder="Quantity" v-
model="data.invoice_product.quantity" @keyup="getProductCost">
</div>
<div >
<input type="text" placeholder="Total" v-
model="data.invoice_product.total">
</div>
<div >
<span>
<i @click="removeElement(k)" v-show="k || ( !k
&& data.invoice_product.length > 1)">Remove</i>
<i @click="addElement(k)" v-show="k ==
data.invoice_product.length-1">Add fields</i>
</span>
</div>
</div>
</div>
from my script (I am excluding irrelevant code segments) :
export default {
data() {
return {
data : {
customer_id : '',
vat : ''
},
inputs: [{
product_id : '',
quantity : '',
total : ''
}],
input: {
product_id : '',
quantity : '',
total : ''
},
products : []
}
},
methods : {
getProductCost() {
axios.get('/api/product-cost?
product_id=' this.item.product_id '&&quantity=' this.item.quantity,
this.data).then(response => {
this.input.total = response.data
})
},
addElement() {
this.data.invoice_product.push({
product_id : '',
quantity : '',
total : ''
})
},
removeElement (index) {
this.data.invoice_product.splice(index, 1)
},
}
Input returns null if I use "input" instead :
CodePudding user response:
The problem is not providing correct data to v-model.
Here, you make an iteration, where you get "input" as an element.
<div v-for="(input,k) in data.invoice_product" :key="k">
But here, you are providing "data.invoice_product" instead of "input".
<select v-model="data.invoice_product.product_id"
@change="getProductCost">
Just change "data.invoice_product.product_id" to "input.product_id", and also do it for other inputs.
CodePudding user response:
You are already looping through data.invoice_product
with this
<div v-for="(input,k) in data.invoice_product"> .... </div>
so the v-model
on your select
tag should be
<select v-model="input.product_id"> .... </select>
instead of
<select v-model="data.invoice_product.product_id"> .... </select>
Similar case for your input
tags for Quantity
and Total
.
So, the code in your template should be something like this:
<div v-for="(input,k) in data.invoice_product" :key="k">
<div >
<div >
<select v-model="input.product_id"
@change="getProductCost">
<option v-for="(product, i) in products" :key="i" :value="product.id">{{
product.product_name }}</option>
</select>
</div>
<div >
<input type="text" placeholder="Quantity" v-
model="input.quantity" @keyup="getProductCost">
</div>
<div >
<input type="text" placeholder="Total" v-
model="input.total">
</div>
<div >
<span>
<i @click="removeElement(k)" v-show="k || ( !k
&& data.invoice_product.length > 1)">Remove</i>
<i @click="addElement(k)" v-show="k ==
data.invoice_product.length-1">Add fields</i>
</span>
</div>
</div>
</div>
[Updated]
Your scripts should be left as it was before:
export default {
data() {
return {
data : {
customer_id : '',
vat : '',
invoice_product: [{
product_id : '',
quantity : '',
total : ''
}],
},
input: {
product_id : '',
quantity : '',
total : ''
},
products : []
}
},
methods : {
addElement() {
this.data.invoice_product.push(this.input)
},
removeElement (index) {
this.data.invoice_product.splice(index, 1)
},
}