danfo danfo - 3 months ago 20
Javascript Question

aUsing Vue JS to duplicate an input field, incrementing the index

I need to duplicate a text input field when user clicks a button "add another" and increment the index on the new field. It's similar to this other question but that solution didn't increment anything.

What I have duplicates the field and increments the index, but it affects all the indexes, not just the newest. (thanks Roy J for the tip)

Here's my template:

<div id="app">
<template v-for="slot in timeslots">
<div><input type="text" name="performances[@{{ count }}][timestamp]" v-model="slot.timestamp" placeholder="index @{{ count }}"></div>
</template>
<span class="add green btn" @click="addAnother"><i class="fa fa-plus-circle"></i> Add another</span>
<pre>@{{ timeslots | json }}</pre>
</div>


Here's what I have in my Vue JS:

new Vue({
el: '#app',

data: {
timeslots: [
{
timestamp: '',
count: 0
}
],
count: 0
},

methods: {
addAnother: function(){
this.timeslots.push({
timestamp: '',
count: this.count++
});
}
}
});

Answer

It works for me if I just qualify count++ with this. I made it pre-increment to avoid making the first elements duplicates.

I've changed the placeholder text to refer to slot.count (the current count, rather than the parent count).

new Vue({
  el: '#app',

  data: {
    timeslots: [{
      timestamp: '',
      count: 0
    }],
    count: 0
  },

  methods: {
    addAnother: function() {
      this.timeslots.push({
        timestamp: '',
        count: ++this.count
      });
    }
  }
});
.green.btn {
  background-color: green;
  color: white;
  padding: 5px;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
<div id="app">
  <template v-for="slot in timeslots">
    <div>
      <input type="text" name="performances[@{{ slot.count }}][timestamp]" v-model="slot.timestamp" placeholder="index {{ slot.count }}">
    </div>
  </template>
  <span class="add green btn" @click="addAnother"><i class="fa fa-plus-circle"></i> Add another</span>
  <pre>@{{ timeslots | json }}</pre>
</div>