0
votes

Picture of interlinkage between forms and fields.

I have searched this forum for an answer, as I suspect this has been asked before, but I haven't managed to find an answer.

I just picked up using Vue and Laravel, where I am building a form. Right now I am building a test to learn how to do it before I add complexity. The right form consists of 1 select-box and 3 text fields. My requirements for the form are:

  1. One button to duplicate the entire form.
  2. One button in each form (also ones that are duplicated), which adds the 3 input-text fields in the form, by duplication the fields in the div called "registration_grid". One form may require the text-fields to be duplicated 10 times, others only 1 or 2...

I realize the code is a bit messy in its context, but it is put together by various pieces I found in tutorials along the way.

    var app = new Vue({
    el: '.container', 
    data: {
        workouts: [ 
            {
            workout_unit: '', 
            workout_weight: '',
            workout_comment: ''
            }
        ]
        },

    methods: {
        addNewEmployeeForm () {
            this.workouts.push({
                workout_unit: '', 
                workout_weight: '',
                workout_comment: ''
            })
        },
        deleteEmployeeForm (index) {
            this.workouts.splice(index, 1)
            }
        }
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
<div class="container">
  <button class="btn btn-primary" type="button" name="button" @click="addNewEmployeeForm">Add form fields</button>
  <div class="card" v-for="(workout, index) in workouts">
    <div class="card-body">
      <i class="far fa-trash-alt float-right" @click="deleteEmployeeForm(index)"></i>
      <h4 class="card-title">Test form - @{{index}}</h4>
      <div class="employee-form">
        <select class="form-select form-select-sm" aria-label=".form-select-sm example">
          <option selected>Open this select menu</option>
          <option value="1">One</option>
          <option value="2">Two</option>
          <option value="3">Three</option>
        </select>
        <div class="registration_grid">
          <input type="text" class="form-control" name="unit" placeholder="unit" v-model="workout.workout_unit">
          <input type="text" class="form-control" name="weight" placeholder="weight" v-model="workout.workout_weight">
          <input type="text" class="form-control" name="comment" placeholder="comment" v-model="workout.workout_comment">
        </div>
      </div>
    </div>
  </div>

Can this be done by Vue, and if so how?

1
So you need a separate form for each item in the workouts array, is that right? When you duplicate the text fields in an individual form, what properties should the new fields correspond to? E.g. should they become workout_unit_1, workout_unit_2 etc.Hannah
Hi Hannah, Yes I think that would be the way to go. My expectation is that I would somehow end up with a multidimensional array for each form that is created, which I will then manage through PHP. I don't know if that is the case or maybe I will end up with one big multidimensional array covering all the forms in one. I am still to new in Vue to have a clear idea of what is possible. However, if I can end up having a unique names for each input field in each form and the naming convention you are listing, then I can manage that as will through a loop. I have updated question with a drawingbngaard

1 Answers

0
votes

You need to access the form data with workouts[index].unit for the v-model instead of workout.workout_unit

var app = new Vue({
  el: '.container', 
  data: {
    workouts: [ 
      {
        unit: '', 
        weight: '',
        comment: ''
      }
    ]
  },

  methods: {
    addRow () {
      this.workouts.push({
        unit: '', 
        weight: '',
        comment: ''
      })
    },
    deleteRow (index) {
      this.workouts.splice(index, 1)
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>

<div class="container">
  <button class="btn btn-primary" type="button" name="button" @click="addRow">Add form fields</button>
  
  <div class="card" v-for="(workout, index) in workouts">
    <div class="card-body">
      <i class="far fa-trash-alt float-right" @click="deleteRow(index)"></i>
      <h4 class="card-title">Test form - {{index}}</h4>
      <div class="employee-form">
        <select class="form-select form-select-sm" aria-label=".form-select-sm example">
          <option selected>Open this select menu</option>
          <option value="1">One</option>
          <option value="2">Two</option>
          <option value="3">Three</option>
        </select>
        <div class="registration_grid">
          <input type="text" class="form-control" name="unit" placeholder="unit" v-model="workouts[index].unit">
          <input type="text" class="form-control" name="weight" placeholder="weight" v-model="workouts[index].weight">
          <input type="text" class="form-control" name="comment" placeholder="comment" v-model="workouts[index].comment">
        </div>
      </div>
    </div>
  </div>
</div>

Modified example to only duplicate the input fields

var app = new Vue({
  el: '.container', 
  data: {
    workouts: [ 
      {
        unit: '', 
        weight: '',
        comment: ''
      }
    ]
  },

  methods: {
    addRow () {
      this.workouts.push({
        unit: '', 
        weight: '',
        comment: ''
      })
    },
    deleteRow (index) {
      this.workouts.splice(index, 1)
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>

<div class="container">
  <button class="btn btn-primary" type="button" name="button" @click="addRow">Add form fields</button>
  
  <div class="card">
    <div class="card-body">
      <h4 class="card-title">Test form</h4>
      <div class="employee-form">
        <select class="form-select form-select-sm" aria-label=".form-select-sm example">
          <option selected>Open this select menu</option>
          <option value="1">One</option>
          <option value="2">Two</option>
          <option value="3">Three</option>
        </select>
        <div class="registration_grid" v-for="(workout, index) in workouts">
          <input type="text" class="form-control" name="unit" placeholder="unit" v-model="workouts[index].unit">
          <input type="text" class="form-control" name="weight" placeholder="weight" v-model="workouts[index].weight">
          <input type="text" class="form-control" name="comment" placeholder="comment" v-model="workouts[index].comment">
          <i class="far fa-trash-alt float-right" @click="deleteRow(index)"></i>
        </div>
      </div>
    </div>
  </div>
</div>