I have two fields "price" and "max_price". I want a validator, which calls every time I change the "price" field my lessThanMaxPrice validator rule.
With this setup everything is working:
<script setup lang="ts">
const lessThanMaxPrice = (price: number) => {
const maxPrice = editItemForm.max_price;
let isValid = true;
if (price || maxPrice) {
if (!maxPrice) {
isValid = false;
} else if (price && price >= maxPrice) {
isValid = false;
}
}
return isValid;
};
const editItemRules = computed(() => {
return {
price: {
lessThanMaxPrice: helpers.withMessage(t('validation_errors.price_error'), lessThanMaxPrice),
},
}
});
let editItemForm = reactive({
price: number|null,
max_price: number|null
});
const editItemV$ = useVuelidate(editItemRules, editItemForm);
</script>
<template>
<v-text-field variant="outlined" hide-details="auto" id="p" type="number"
:valid="editItemV$.price.$error" :color="editItemV$.price.$error ? 'success' : ''"
:error-messages="editItemV$.price.$error ? editItemV$.price.$errors[0].$message.toString() : ''"
step="0.01" @change="editItemV$.price.$touch" v-model="editItemForm.price" />
<v-text-field variant="outlined" hide-details="auto" id="max_price" type="number"
:valid="editItemV$.max_price.$error" :color="editItemV$.max_price.$error ? 'success' : ''"
:error-messages="editItemV$.max_price.$error ? editItemV$.max_price.$errors[0].$message.toString() : ''"
step="0.01" @change="editItemV$.max_price.$touch" v-model="editItemForm.max_price" />
</template>
No I want to extract the lessThanMaxPrice-Function to an ValidationHelpers class, because I need this kind of validation in some other components:
export class ValidationHelpers {
static lessThanMaxPrice(price: number | null, maxPrice: number | null) {
let isValid = true;
if (price || maxPrice) {
if (!maxPrice) {
isValid = false;
} else if (price && price >= maxPrice) {
isValid = false;
}
}
return isValid;
};
}
I dont know how to call the ValidationHelpers.lessThanMaxPrice function with parameters. This approach is not working:
const editItemRules = computed(() => {
return {
price: {
lessThanMaxPrice: (value) => helpers.withMessage(t('validation_errors.price_error'), ValidationHelpers.lessThanMaxPriceTest(value, editItemForm.max_price)),
}
}
});
and VSCode throws the error:
Argument of type 'boolean' is not assignable to parameter of type 'ValidationRule<unknown>'.ts(2345)
I'm new to Vue / Vuelidate / Vuetify / TypeScript, so please be understanding :)
Of course, as always, once you ask the question, you come up with the answer.
First I changed the @change handler to @input and @blur
<v-text-field variant="outlined" hide-details="auto" id="price" type="number"
:valid="editItemV$.price.$error" :color="editItemV$.price.$error ? 'success' : ''"
:error-messages="editItemV$.price.$error ? editItemV$.price.$errors[0].$message.toString() : ''"
step="0.01" @input="editItemV$.price.$touch" @blur="editItemV$.price.$touch"
v-model="editItemForm.price" />
However, the main problem was in my rules. With the following change everything works now:
const editItemRules = computed(() => {
return {
price: {
lessThanMaxPrice: helpers.withMessage(t('validation_errors.price_error'), (value: number | null) => ValidationHelpers.lessThanMaxPrice(value, editItemForm.max_price)),
},
}
});