1
votes

How can i validate a list of values across fields where at least one single value has to be set (not zero)

I need to validate that at least one field is entered (eg the total is not zero)

The issue I have is that the validator::total_cost does not re-evaluate all the fields under validation when any one of them changes.

Typing a correct value in "any" input needs to tell "all" the other inputs to revaluate against the new computed field !

Any help would be grateful.

eg (my set is much much larger)

 V1  V2  V3  V4  V5          Tot
[0] [0] [0] [0] [0] -------- [0] (invalid)  
[0] [0] [0] [0] [1] -------- [1] (valid)
[1] [0] [0] [0] [1] -------- [2] (valid)
[0] [0] [1] [0] [1] -------- [3] (valid)

The markup i am using

<input type="text" v-model.number="v1" data-vv-as="v1" v-validate="anyValue":name="v1"/>

<input type="text" v-model.number="v1" data-vv-as="v2" v-validate="anyValue":name="v2"/>

<input type="text" v-model.number="v2" data-vv-as="v3" v-validate="anyValue":name="v3"/>

<input type="text" v-model.number="v3" data-vv-as="v4" v-validate="anyValue":name="v4"/>

<input type="text" v-model.number="v4" data-vv-as="v5" v-validate="anyValue":name="v5"/>

AnyValue is a computed property

 computed: {
    anyValue: function () {
        return {
           // required: true,
            between: [0, 99999999],
            decimal: 2,
            total_cost: this.totalCost /* THIS IS COMPUTED */
        }
    },
    totalCost: function () {
        return this.v1 + this.v2 + this.v3 + this.v4 + this.v5;           
    }
 created: function () {
    this.$validator.extend('total_cost', {
        vTotalCost:0,
        getMessage: function (field) { 
         return 'At least one value must be supplied'; 
        },
        validate: function (value) {
            this.vTotalCost = value;
            console.log("the value is " + this.vTotalCost);
            return this.vTotalCost != 0;                
        }
    });
},
1
All your v-model are the same: v-model.number="v1"? - Sovalina
Edited question - corrected markup. - PingCrosby

1 Answers

0
votes

First, there is some errors in your snippet:
You create a new vee-validate rule called total_cost but you don't bind it to the v-validate directive (instead you try to pass a computed property).
Change your inputs with v-validate="'total_cost'" (note that total_cost is binded as a string)


Now you can use the any method provided by Vee-validate (source) to return a global error message:

Vue.use(VeeValidate)

new Vue({
  el: "#app",
  data () {
    return { v1: 0, v2: 0, v3: 0, v4: 0, v5: 0 }
  },
  computed: {
    errorMsg() {
      if (this.errors.any()) {
      	return 'At least one value must be supplied'
      }
    }
  },
  created: function () {
    this.$validator.extend('total_cost', {
      vTotalCost:0,
      getMessage: function (field) { 
        return 'At least one value must be supplied'; 
      },
      validate: function (value) {
        this.vTotalCost = value;
        return this.vTotalCost != 0;                
      }
    })
  }
})
.has-error {
  color: red;
  font-size: 12px;
}
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]"></script>
<div id="app">
  <input type="text" v-model.number="v1" data-vv-as="v1" v-validate="'total_cost'" name="v1"/>
  <input type="text" v-model.number="v2" data-vv-as="v2" v-validate="'total_cost'" name="v2"/>
  <input type="text" v-model.number="v3" data-vv-as="v3" v-validate="'total_cost'" name="v3"/>
  <input type="text" v-model.number="v4" data-vv-as="v4" v-validate="'total_cost'" name="v4"/>
  <input type="text" v-model.number="v5" data-vv-as="v5" v-validate="'total_cost'" name="v5"/>
  <p class="has-error">{{ errorMsg }}</p>
</div>