Reputation: 1257
I'm using VUE and Vuelidate for validating form input. In this case.. It's a modal popup which gets data through ...mapGetters from the store.
If i set static values like this, it works :
validations: {
refundAmount: {
between: between(0, 40)
}
},
but when using a value from the store like this, it doesn't map against the value :
validations: {
refundAmount: {
between: between(0, this.selectedOrder ? this.selectedOrder.totalprice : 0)
}
},
My hard guess... this.selectedOrder.totalprice is not existing before the vuelidate component needs it ? Not sure how to actually handle that one...
The current validation (between) accepts only from 0 to 0 (zero to zero) so clearly... the value from this.selectedOrder.totalprice is not existant...
Here is my code :
import bus from '../global/bus.js'
import {
mapGetters
} from "vuex"
import {
required,
minLength,
between
} from 'vuelidate/lib/validators'
var moment = require('moment')
var alertify = require('../assets/alertify.js')
export default {
name: "modal",
data() {
return {
comment: null,
refundAmount: null,
paymentOptionsAgreementId: null,
moveToAppId: null
}
},
validations: {
refundAmount: {
between: between(0, this.selectedOrder ? this.selectedOrder.totalprice : 0)
}
},
mounted() {
this.$v.$touch()
},
computed: {
...mapGetters(["visibleModalComponent", "selectedOrder", "loggedInUser", "accessToken", "paymentoptions"])
}
}
<template>
<div class="form-group">
<label class="col-sm-5">Refundér beløp</label>
<div class="col-sm-7">
<input
v-model.trim="refundAmount"
v-on:input="$v.refundAmount.$touch"
v-bind:class="{error: $v.refundAmount.$error,
valid: $v.refundAmount.$dirty &&
!$v.refundAmount.$invalid}"
type="text"
class="form-control">
</input>
<pre>{{ $v }}</pre>
</div>
</div>
</template
Updated with computed value (sat correctly), but still not working :
Computed code :
computed: {
...mapGetters(["visibleModalComponent", "selectedOrder", "loggedInUser", "accessToken", "paymentoptions"]),
totalPrice() {
return this.selectedOrder ? this.selectedOrder.totalprice : 0
}
},
Validation :
validations: {
refundAmount: {
between: between(0, this.totalPrice)
}
},
Screenshot :
Upvotes: 4
Views: 9109
Reputation: 71
Change the Validation scheme to be dynamic as explained here https://vuelidate.js.org/#sub-dynamic-validation-schema
For example, validations are usually defined like this:
validations: {
refundAmount: {
between: between(0, this.selectedOrder ?
this.selectedOrder.totalprice : 0)
}
}
Change validations object to a function as follows:
validations () {
return {
refundAmount: {
between: between(0, this.selectedOrder ?
this.selectedOrder.totalprice : 0)
}
}
}
This makes the validation schema dynamic, thereby allowing the component's data, including Vuex store data, to be accessible to built-in Vuelidate validators such as minLength, maxLength etc. , as well as custom validators using the this keyword.
Upvotes: 1
Reputation: 23483
Try a computed value for totalPrice.
export default {
name: "modal",
data() {
return {
comment: null,
refundAmount: null,
paymentOptionsAgreementId: null,
moveToAppId: null
}
},
validations: {
refundAmount: {
between: between(0, this.totalprice)
}
},
computed: {
...mapGetters(["visibleModalComponent", "selectedOrder", "loggedInUser", "accessToken", "paymentoptions"]),
totalPrice() {
return this.selectedOrder ? this.selectedOrder.totalprice : 0
}
}
Edit After collaborative effort with Terje, we have the following fix:
Vuelidate requires a function to be able to use variables as parameters to it's validations, so the working code is
validations: {
refundAmount: {
// between: between(0, this.totalPrice)
between (value) {
return between(0, this.totalPrice)(value)
}
}
},
Ref: Is it possible to use a variable for validation? #55
Upvotes: 4