I have component FromTo that takes 2 Timepickers components and cross validate one Timepicker component (From) to another (To). To timepicker has a greater vee-validate cross-field rule applied to it that looks like this:
extend("greater", {
params:["target"],
validate(value, {target}){
let regex = new RegExp("\d{2}:\d{2}", "g");
console.log("from is "+target); // prints @from instead of @from value
console.log("value is "+value);
return regex.test(value)
&& regex.test(target)
&& value > target;
},
message: "To field must be greater that from field"
});
Component body looks like this
<ValidationObserver>
<div class="flex mb-16 flex-wrap w-full">
<div class="mr-1">
<label class="font-bold block">From</label>
<ValidationProvider name="from" rules="required|time" v-slot="{ errors }">
<VueTimepicker
v-model="val.from"
close-on-complete
:input-class="['px-3', 'py-2', 'border', 'rounded', (errors.length ? 'border-red-400' : 'border-gray-400')]"
/>
<span class="text-sm w-40 block mt-1 text-red-400" v-if="errors.length"> {{ errors[0] }} </span>
</ValidationProvider>
</div>
<div>
<label class="font-bold block">To</label>
<ValidationProvider name="to" rules="required|time|greater:@from" v-slot="{ errors }">
<VueTimepicker
v-model="val.to"
close-on-complete
:input-class="['px-3', 'py-2', 'border', 'rounded', (errors.length ? 'border-red-400' : 'border-gray-400')]"
/>
<span class="text-sm w-40 block mt-1 text-red-400" v-if="errors.length"> {{ errors[0] }} </span>
</ValidationProvider>
</div>
</div>
</ValidationObserver>
I can see my rule being targeted but console logs @from instead of @from value. According to vee-validate docs in order for cross-field validation rule to work following criteria must be met:
Wrap the fields within the same ValidationObserver component. The target field must have a name or vid prop. Properly reference the target field name or vid value in the rules of the other.
I have also properly referenced from field
To reference another field's value, add a @ at the beginning of a param to signal to vee-validate that it should substitute the param with the target field value. So instead of getting a static "confirm" string, you will get the field's value instead.
I know I could possibly target static value like this:
rules=`required|time|greater:${this.from}`
But I would really want to target field values using @ sign. I 've simplified this example as I could and all the inner v-model bindings are correct. (from, to and entire component). I've been breaking my head around this for quite some time and red documentation carefully and would really appreciate any help...