Search code examples
validationvue.jsrepeatervee-validate

Multiple Text Field Repeater with VueJS Vee Validate


I have a multiple text fields repeater with veevalidate. The problem is that, when the first field has errors, the other field will be affected. And, will inherit that error when adding new field.

-> https://prnt.sc/h75byu

here's my html

<div id="app">
  <form class="ui form" @submit.prevent="onSubmit">

    <div class="repeater" v-for="(field, index) in fieldsRepeater">
      <div class="field" :class="{error: errors.has('fname')}">
        <label>First Name</label>
        <input type="text" name="fname" placeholder="First name" v-validate="'required'" v-model="fname">
        <span class="error" v-if="errors.has('fname')">{{errors.first('fname')}}</span>
      </div>

      <div class="field" :class="{error: errors.has('lname')}">
        <label>Last Name</label>
        <input type="text" name="lname" placeholder="Last name" v-validate="'required'" v-model="lname">
        <span class="error" v-if="errors.has('lname')">{{errors.first('lname')}}</span>
      </div>

    </div>
  <button type="button" class="ui button" @click="AddField">Add Field</button>

  <button type="submit" class="ui submit button">Submit</button>
  </form>
</div>

here's my vuejs

Vue.use(VeeValidate)

new Vue({
  el: '#app',
  data() {
    return {
      fieldsRepeater: [{
        fname: '',
        lname: '',
      }],
    }
  },
  methods: {
    AddField() {
      this.fieldsRepeater.push({
        fname: '',
        lname: '',
      });
    },
    onSubmit() {
      this.$validator.validateAll()

      if (!this.errors.any()) {
        alert('submit')
      }
    }
  }
})

here's my jsfiddle -> https://jsfiddle.net/m67d8f4x/66/

how can we apply different validation to every group of fields?

How can I solve that problem?


Solution

  • your names are the same, so the veeValidate plugin can't tell them apart.

    try the following code. Note that the names are dynamically added using :name="'fname'+index" and refernced using errors.has('lname'+index)

    <div id="app">
      <form class="ui form" @submit.prevent="onSubmit">
    
        <div class="repeater" v-for="(field, index) in fieldsRepeater" :key="index">
          <div class="field" :class="{error: errors.has('fname'+index)}">
            <label>First Name</label>
            <input type="text" :name="'fname'+index" placeholder="First name" v-validate="'required'" v-model="field.fname">
            <span class="error" v-if="errors.has('fname'+index)">{{errors.first('fname'+index)}}</span>
          </div>
    
          <div class="field" :class="{error: errors.has('lname'+index)}">
            <label>Last Name</label>
            <input type="text" :name="'lname'+index" placeholder="Last name" v-validate="'required'" v-model="field.lname">
            <span class="error" v-if="errors.has('lname'+index)">{{errors.first('lname'+index)}}</span>
          </div>
    
        </div>
      <button type="button" class="ui button" @click="AddField">Add Field</button>
    
      <button type="submit" class="ui submit button">Submit</button>
      </form>
    </div>
    

    also, you should get into the habit of ALWAYS defining a key

    fiddle: https://jsfiddle.net/m67d8f4x/67/