John Mulaney
John Mulaney

Reputation: 109

How to push data into an array from a v-form?

At the moment, I have the following code:

<template>
    <v-container>
    <v-form v-model="valid" ref="form" v-for="(resposta,index) in formData.body" :key="index">
            <v-row>
                <v-col cols="8">
                    <v-text-field
                    v-model="resposta.answer"
                    :rules="idRules"
                    :counter="200"
                    label="Texto da Resposta"
                    required
                ></v-text-field>
                </v-col>
            </v-row>

            <v-row>
                <v-col xl="2" lg="3" md="3" sm="4" class="mt-4">
                    <p class="grey--text text--darken-1">Resposta Correta:</p>
                 </v-col>
                <v-radio-group
                    v-model="resposta.correction"
                    row
                    mandatory     
                >
                    <v-col md="4" sm="4">
                        <v-radio
                        label="0"
                        value="0"
                        ></v-radio>
                    </v-col>
                    <v-col md="4" sm="4">
                        <v-radio
                        label="1"
                        value="1"
                        ></v-radio>
                    </v-col>
                </v-radio-group>
            </v-row>
                
            <v-row>
                <v-col xl="2" lg="3" md="3" sm="4" class="mt-4">
                    <p class="grey--text text--darken-1">Resposta Obrigatória:</p>
                 </v-col>
                <v-radio-group
                    v-model="resposta.mandatory"
                    row
                    mandatory     
                >
                    <v-col md="4" sm="4">
                        <v-radio
                        label="0"
                        value="0"
                        ></v-radio>
                    </v-col>
                    <v-col md="4" sm="4">
                        <v-radio
                        label="1"
                        value="1"
                        ></v-radio>
                    </v-col>
                </v-radio-group>
            </v-row>

            <v-row>
                <v-col xl="2" lg="3" md="3" sm="4" class="mt-4">
                    <p class="grey--text text--darken-1">Resposta Eliminatória:</p>
                 </v-col>
                <v-radio-group
                    v-model="resposta.eliminative"
                    row
                    mandatory     
                >
                    <v-col md="4" sm="4">
                        <v-radio
                        label="0"
                        value="0"
                        ></v-radio>
                    </v-col>
                    <v-col md="4" sm="4">
                        <v-radio
                        label="1"
                        value="1"
                        ></v-radio>
                    </v-col>
                </v-radio-group>
            </v-row>

            <v-row>
                <v-col cols="5">
                    <v-select :items="pontos"
                        v-model="resposta.points"
                        label="Pontos"
                        dense
                    ></v-select>
                </v-col>
                <v-col cols="7" align="center">
                    <v-btn @click="addAnswer" class="white--text" color="#2A3F54" grey--text>
                        Add Answer
                    </v-btn> {{formData.body}}
                </v-col>
            </v-row>
    </v-form>
    </v-container>
</template>

<script>

export default {
    data(){
        return{  
            formData:{
                body: [{
                    answer: '',
                    correction: '',
                    mandatory: '',
                    eliminative: '',
                    points:''
                }]
            }
        }   
    },
    methods: {
      addAnswer(){
        this.formData.body.push({answer: '',
            correction: '',
            mandatory: '',
            eliminative: '',
            points:''})
            alert("inserida")
      }
    },
    watch: {
        formData: {
            handler: function() {
              this.$emit('newdataRespostas', this.formData.body);
          },
            deep: true
        }
      },
}
</script>

The goal with this is to be able to get the information in the array in another component, which I'm being able to do. The problem here is that everytime I click on the Add Answer button, it creates a new identical form right under the previous one. The data is being pushed correctly into the array, the other component is being able to watch for the information inside that array, but I'm just not able to get rid of the new forms that get created. If I add 4 new answers, I'll have 5 forms by the end, which is clearly not optimal. Also any tips regarding any part of the code are welcome. I'm completely new to Vue.js and Vuetify.

Sorry for the long code, but almost all of it is just the different form components.

Upvotes: 0

Views: 1203

Answers (1)

tony19
tony19

Reputation: 138656

The form uses v-for on formData.body[], so each array element (each answer) renders a new form. It sounds like you want only the newest form to be shown, in which case you don't need v-for.

I would replace the v-for with a different data property (e.g., named resposta to match the current variable used in your template), and append that property to formData.body[] in addAnswer():

<template>
  <v-form v-model="valid" ref="form">
    <!--...-->
    <v-text-field v-model="resposta.answer" />
  </v-form>
</template>

<script>
export default {
  data() {
    return {
      formData: {
        body: [],
      },
      resposta: {},
    };
  },
  methods: {
    addAnswer() {
      this.formData.body.push(this.resposta)
      this.resposta = {}
    },
  },
}
</script>

demo

Upvotes: 1

Related Questions