0

I have a form, which has a vue componenet that allows users to create additional input lines in the form.

I am having an issue getting all of these input lines to submit for the axios request, currently it only outputs the last added rows input.

Typically, in a normal PHP form, I would just make the field an array (name="MultiRow[]"), however I am lost at doing this in Vue and struggling to find any doc that covers this.

Here is the component in my form:

<div class="mt-5 md:mt-0 md:col-span-2">
    <fieldset class="mt-6">
            <div class="mt-6">
                    <response-set-input v-model="fields.response"></response-set-input>
            </div>
    </fieldset>
</div>

Here is my Vue File for form submission:

<script>

import Switch from '../../components/StatusToggle';

export default {

  data() {
    return {
      fields: {},
      errors: {},
      statusToggle: false,
    }
  },
  methods: {
    toggled(toggleOn){
        statusToggle: toggleOn
    },
    submit() {
      this.errors = {};
      axios.post('/submit', this.fields).then(response => {
        alert('Message sent!');
      }).catch(error => {
        if (error.response.status === 422) {
          this.errors = error.response.data.errors || {};
        }
      });
    },
  },
   components: {
       statusToggle: Switch
   }
}
</script>

Here is my component code:

<template>
    <div>
    <div class="m-2"  v-for="(row, index) in rows" :key="index">

        <div class="col-span-12 sm:col-span-3 mb-1">
            <label for="responseTitle" class="block text-sm font-medium leading-5 text-gray-700">Response</label>
            <input 
            id="responseTitle" 
            class="mt-1 form-input block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:shadow-outline-blue focus:border-blue-300 transition duration-150 ease-in-out sm:text-sm sm:leading-5"
            type="text"
            name="fields.response[]"
            :value="responseInput"
            @input="onInput($event.target.value)"/>
        </div>
        <div class="mt-2">
            <button type="button" class="inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs leading-4 font-medium rounded text-gray-700 bg-green-100 hover:bg-indigo-50 focus:outline-none focus:border-indigo-300 focus:shadow-outline-indigo active:bg-indigo-200 transition ease-in-out duration-150"  @click="addRow">
                Add new Response
            </button>
            <button type="button" class="inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs leading-4 font-medium rounded text-gray-700 bg-red-100 hover:bg-indigo-50 focus:outline-none focus:border-indigo-300 focus:shadow-outline-indigo active:bg-indigo-200 transition ease-in-out duration-150" @click="removeRow(index)">
                Remove
            </button>
        </div>
    </div>
</div>
</template>


<script>
export default {
    props: ['responseInput'],
  data () {
    return {
      rows: [],
      stopRemoval: true,
    }
  },
  watch: {
    rows () {
      this.stopRemoval = this.rows.length <= 1
    }
  },
  methods: {
    onInput(responseInput){
        this.$emit('input', responseInput),
        console.log(responseInput)
    },
    addRow () {
      let checkEmptyRows = this.rows.filter(row => row.number === null)

      if (checkEmptyRows.length >= 1 && this.rows.length > 0) {
         return
      } 

      this.rows.push({
        responseTitle: null,
      })
    },

    removeRow (rowId) {
      if (!this.stopRemoval) {
         this.rows.splice(rowId, 1)
      }
    }
  },
  mounted () {
    this.addRow()
  }
}
</script>

How do I submit the multiple rows to the form submission with Vue?

1 Answer 1

1

There's a decent amount wrong with your code, I suggest that you read the documentation.

Just to name a few things:

  1. You shouldn't update a prop in a component as it will get overridden when the parent updates, props: ['responseInput'], and :value="responseInput"

  2. You're not passing any prop called responseInput, v-model passes a prop called value.

  3. Vue is only reactive on properties that processed during instance initialisation and that means it doesn't know about response on fields: {},

  4. You're using rows (which is good), but then you're only emitting the prop you passed in responseInput. I think :value="responseInput" is supposed to be :value="row"

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.