1

I have a group of fields that are generated in a loop an indefinite number of times. Basically 2 input fields, a label, and a delete button. Then another button that says Add More.

Every time they hit that, one more set of the above-mentioned appears. They can do this as many times as they want. It looks like this. (I'm using quasar, hence why the q-"" elements)

// Click more button
<q-btn @click="onAddBarcodes" icon="add" no-caps color="primary">Add More</q-btn>


// Form
<div v-for="(barcode, index) in barcodes" :key="index">
    <div class="row q-pr-lg items-center">
        <div class="col-3">
             <label class="text-weight-medium">Starting Roll #:</label>
             <q-input v-model="barcode.start" :id="barcode.id"></q-input>
        </div>
        <div class="col-3">
             <label class="text-weight-medium">Ending Roll #:</label>
             <q-input v-model="barcode.end" :id="barcode.id"></q-input>
        </div>
        <div class="col-5">
             <label class="text-weight-medium">Agency Name:</label>
             <div v-if="barcode.agencyName">
                 {{ barcode.agencyName }}
             </div>
        </div>
        <div class="col-1">
             <q-btn @click="onDeleteBarcodes(barcode.id)" icon="close"/>
        </div>
    </div>
</div>


export default {
    data() {
        return {
            barcodes: []
        }
    },
    methods: {
        onAddBarcodes() {
            const newBarcode = {
                id: Math.random() * Math.random() * 1000,
                start: "",
                end: "",
                agencyName: ""
            };
            this.barcodes.push(newBarcode);
        },
        onDeleteBarcodes(id) {
            this.barcodes = this.barcodes.filter(barcode => barcode.id !== id);
        },
    }
 }

Now this works at its most basic form. What I want to do is to load the component with a set number of iterations already started. For example, 5 of them.

The Add More button will add the 6th on forward if they need more. The delete button should delete down to zero if they wanted to (not that they would) but it should definitely delete down to 1 at least.

How can I start the v-for at a specific number of iteration?

Anurag Srivastava
  • 14,077
  • 4
  • 33
  • 43
LOTUSMS
  • 10,317
  • 15
  • 71
  • 140

3 Answers3

3

You can add 5 items to barcodes on created() vue instance like:

created() {
    [...Array(5).keys()].forEach(() => this.onAddBarcodes())
}
tony19
  • 125,647
  • 18
  • 229
  • 307
palaѕн
  • 72,112
  • 17
  • 116
  • 136
  • 1
    At first, I thought Anurag had a very simple answer, but this one is much simpler plus I am already using onAddBarcodes in my created lifecycle, so this will work even simpler, cleaner and more efficient for me – LOTUSMS Apr 15 '20 at 15:38
  • You can also checkout [Difference between the created and mounted events in Vue.js](https://stackoverflow.com/questions/45813347/difference-between-the-created-and-mounted-events-in-vue-js). Its always got to bookmark these great content for future refrences. – palaѕн Apr 15 '20 at 15:39
  • 2
    Nice, and I thought mine was the shortest :) – Anurag Srivastava Apr 15 '20 at 16:13
  • I have not tested this, but I think we can make it even shorter like: `[...Array(5).keys()].forEach(this.onAddBarcodes)`. @LOTUSMS could you please verify this once. – palaѕн Apr 15 '20 at 16:18
  • This one also works for OP's purpose because they don't need values: `[...new Array(n)].forEach()` – Anurag Srivastava Apr 15 '20 at 16:24
  • 1
    @palaѕн Correct! The even shorter version also worked – LOTUSMS Apr 15 '20 at 17:21
1

You can add mounted hook and initialize collection with 5 elements here

export default {
    data() {
        return {
            barcodes: []
        }
    },
    mounted() {
     this.barcodes = Array(5).fill(0).map(pr => ({
                id: Math.random() * Math.random() * 1000,
                start: "",
                end: "",
                agencyName: ""
            }))
    },
    methods: {
        onAddBarcodes() {
            const newBarcode = {
                id: Math.random() * Math.random() * 1000,
                start: "",
                end: "",
                agencyName: ""
            };
            this.barcodes.push(newBarcode);
        },
        onDeleteBarcodes(id) {
            this.barcodes = this.barcodes.filter(barcode => barcode.id !== id);
        },
    }
 }
Józef Podlecki
  • 10,453
  • 5
  • 24
  • 50
1

You can call the onAddBarcodes n times in beforeMount:

beforeMount(){
   const n = 5; // Or any number
   Array.from(new Array(n)).forEach(el => this.onAddBarcodes());
}
Anurag Srivastava
  • 14,077
  • 4
  • 33
  • 43