use v-model inside a v-for loop
I am rendering an input field inside v-for loop and using v-model in that input to get the value of the input but when i type in any one of the input , the value is typed in every text field.
I have replicated my issue here in this fiddle
<div id="app">
<h2>Todos:</h2>
<ol>
<li v-for="todo in todos">
<label>
<input type="text" v-model="score">
<del v-if="todo.done">
{{ todo.text }}
</del>
<span v-else>
{{ todo.text }}
</span>
</label>
</li>
</ol>
</div>
new Vue({
el: "#app",
data: {
score: [],
todos: [
{ text: "Learn JavaScript", done: false },
{ text: "Learn Vue", done: false },
{ text: "Play around in JSFiddle", done: true },
{ text: "Build something awesome", done: true }
]
},
})
Solution 1:
Yes obviously that happens because you bind X Input fields on 1 Value. What you probably want is your score[] to get put in as an Array, for that use
new Vue({
el: "#app",
data: {
score: [],
todos: [
{ text: "Learn JavaScript", done: false },
{ text: "Learn Vue", done: false },
{ text: "Play around in JSFiddle", done: true },
{ text: "Build something awesome", done: true }
]
},
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
del {
color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Todos:</h2>
<ol>
<li v-for="(todo,index) in todos">
<label>
<input type="text" v-model="score[index]">
<del v-if="todo.done">
{{ todo.text }}
</del>
<span v-else>
{{ todo.text }}
</span>
</label>
</li>
</ol>
</div>
https://jsfiddle.net/o9awn47v/
Solution 2:
Score is treated as a single variable, when in it used in v-model="score".
You can add the score in the todo items and v-model it on the input, so you can easily reference to the score value of each todo item.
<div id="app">
<h2>Todos:</h2>
<ol>
<li v-for="todo in todos">
<label>
<input type="text" v-model="todo.score">
<del v-if="todo.done">
{{ todo.text }}
</del>
<span v-else>
{{ todo.text }}
</span>
</label>
</li>
</ol>
</div>
new Vue({
el: "#app",
data: {
todos: [
{ text: "Learn JavaScript", done: false, score: '' },
{ text: "Learn Vue", done: false, score: '' },
{ text: "Play around in JSFiddle", done: true, score: '' },
{ text: "Build something awesome", done: true, score: '' }
]
},
})
Solution 3:
Encountered a similar issue where I needed to input formdData for each table fields(form-input) but using a v-for to render all the table questions resulted in all the fields being field whenever I enter something in any of the fields. Checked your the above solutions tried it out but it didn't work for me.
<div class="option-section" v-if="question.type === 'TABLE'">
<table class="table b-table table-bordered">
<thead>
<tr>
<th v-for="(column, index) in question.columns" :key="index">
{{column.body}}
</th>
</tr>
</thead>
<tbody>
<tr>
<td v-for="(column, colindex) in question.columns" :key="colindex">
<b-form-input size="sm" id="colindex" autocomplete="off"
class="readonly" readonly disabled></b-form-input>
</td>
</tr>
</tbody>
</table>
</div>
finally I discovered how to go about it and want to share should in case anyone face a similar situation.
<div class="option-section" v-if="question.type === 'TABLE'">
<table class="table b-table table-bordered">
<thead>
<tr>
<th v-for="(column, index) in question.columns" :key="index">
{{column.body}}
</th>
</tr>
</thead>
<tbody>
<tr>
<td v-for="(column, colindex) in question.columns" :key="colindex">
<b-form-input v-model="question.columns[colindex].response" id="colindex" :disabled="readOnly" size="sm" autocomplete="off" class="readonly" >
</b-form-input>
</td>
</tr>
</tbody>
</table>
</div>