How can I validate, using VeeValidate v3 and VueJs-DatePicker, if a date is before or after a certain date?
I am using: https://www.npmjs.com/package/vuejs-datepicker (latest) and https://baianat.github.io/vee-validate/ (Version 3, not 2)
VeeValidate removed its date validation capabilities, stating that the rules were fragile, didn't work great, etc.
So I am assuming I need to create custom rules but I don't really know where to start with this and could use help.
I am using the VueJS-DatePicker package as a datepicker and I am using a custom format via the "format" attribute.
My datepicker code
<datepicker
v-model="inputVal"
:class="{ 'has-errors': !!errors[0] }"
:placeholder="placeholder"
calendar-button
calendar-button-icon="fal fa-calendar-alt"
bootstrapStyling
:typeable="true"
:disabled-dates="disabledDates"
:format="customFormatter"
></datepicker>
Using Moment to format the date
customFormatter(date) {
return moment(date).format('MM/DD/YYYY');
},
expanding on @Barabas answer to specifically include a) before a given date b) the momentJS library c) the strict date format 'MM/DD/YYYY'
import { extend } from "vee-validate";
import * as moment from 'moment';
const dateFormat = 'MM/DD/YYYY';
extend("before", {
params: ["limit", "included"],
validate: (value, { limit, included }) => {
limit = moment(limit, dateFormat);
value = moment(value, dateFormat);
return included
? value.isSameOrBefore(limit)
: value.isBefore(limit);
},
message: (fieldName, placeholders) => {
let limit = moment(placeholders.limit).format(dateFormat);
return `The ${fieldName} field must come before ${limit}`;
}});
}
and without moment (with the caveat that different localization setting in the users browser could result in funkiness when using strings for either a Vue data property or the limit
parameter - I would strongly suggest using 'YYYY-MM-DD' format if using strings - this does not have to be what is shown to the user of course)
extend("before", {
params: ["limit", "included", "displayTime"],
validate: (value, { limit, included }) => {
value = isNaN(value)
? Date.parse(value)
: +value;
limit = isNaN(limit)
? Date.parse(limit)
: +limit;
return included
? value <= limit
: value < limit;
},
message: (fieldName, placeholders) => {
let limit = placeholders.limit instanceof Date
? placeholders.limit
: new Date(placeholders.limit);
limit = placeholders.displayTime
? limit.toLocaleString()
: limit.toLocaleDateString();
return `The ${fieldName} field must come before ${limit}`
}});
}
extend
For example, this is my own custom rule to check if it is enough items in collection:
value
below is a value from input
(unfortunately, vee-validate
works only with input
)min
is a value after semicolon in rules
prop of ValidationProvider
extend('minAmountItems', {
validate: (value, { min }) => {
return value >= min;
},
params: ['min'],
message: '{_field_} should contains at least {min} items'
});
datepicker
by ValidationProvider
For example, I wrapped my own component by ValidationProvider
:
HTML
<ValidationProvider
ref="editableListProvider"
tag="div"
rules="minAmountItems:2"
v-slot="{errors,invalid}"
name="Collection"
>
<!-- LINE BELOW IS VERY IMPORTANT. -->
<!-- THIS INPUT VALUE GOES TO VALIDATE FUNCTION OR CUSTOM RULE -->
<input type="text" :value="items.length" disabled v-show="false" />
<div class="column add-item-column">
<button @click="addItem">Add item</button>
</div>
<div class="column alert alert-danger" v-show="invalid">{{ errors[0] }}</div>
<div class="column" v-for="(item, i) in items" :key="i">
<div class="row as-row row-no-padding">
<slot name="data" :data="{item, index: i}"></slot>
<div class="column column-clear">
<button class="button-outline button-icon" @click="removeItem(i)">
<i class="la la-close"></i>
</button>
</div>
</div>
</div>
</ValidationProvider>
JS
// another part of my component
methods: {
addItem() {
this.$emit('editableList:itemAdded');
this.$nextTick(async () => {
// LINE BELOW IS IMPORTANT, BECAUSE AUTOMATIC VALIDATE WORKS
// ONLY ONCHANGE EVENT OF INPUT
this.$refs.editableListProvider.validate();
});
},
removeItem(index) {
this.$emit('editableList:itemRemoved', { index });
this.$nextTick(async () => {
// LINE BELOW IS IMPORTANT, BECAUSE AUTOMATIC VALIDATE WORKS
// ONLY ONCHANGE EVENT OF INPUT
this.$refs.editableListProvider.validate();
});
}
// other my methods
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With