The v-model binding on my date picker field is not working properly.
When you make a selection it will update live on the screen but it will not store the values in the formValues reactive object.
Since vee-validate does not support date picker fields, how do I force it to update to the same react component (formValues) that all my other input fields are mapped to.
<template> <img alt="Vue logo" src="./assets/logo.png"> <div v-if="showUnderAge.isVisible"> SORRY WE CANT HELP UNDER 18 </div> <div v-if="showOutOfCountry.isVisible"> SORRY WE CANT HELP OUT OF COUNTRY </div> <div v-if="showContainer.isVisible"> <h1>Create your Account</h1> Verify Entry values: <br /> {{ formValues }} <Form @submit="nextStep" :validation-schema="currentSchema" v-slot="{ handleSubmit }" > <template v-if="currentStep === 0"> <label for="name">Name</label> <Field name="name" id="name" v-model="formValues.name" /> <ErrorMessage name="name" /> <br /> <label for="email">Email</label> <Field name="email" id="email" type="email" v-model="formValues.email" /> <ErrorMessage name="email" /> <br /> <label for="country">Country</label> <Field as="select" name="country" v-model="formValues.country"> <option value="United States">United States</option> <option value="Canada">Canada</option> <option value="-" disabled>---------------</option> <option value="Afghanistan">Afghanistan</option> <option value="Åland Islands">Åland Islands</option> <option value="Albania">Albania</option> <option value="Algeria">Algeria</option> <option value="American Samoa">American Samoa</option> <option value="Andorra">Andorra</option> <option value="Angola">Angola</option> <option value="Anguilla">Anguilla</option> <option value="Antarctica">Antarctica</option> <option value="Antigua and Barbuda">Antigua and Barbuda</option> </Field> <br /> <label for="dob">Date of Birth</label> <Datepicker autoApply name="dob" v-model="formValues.date" :enableTimePicker="false" style="width: 20%"></Datepicker> <br /> </template> <template v-if="currentStep === 1"> <label for="password">Password</label> <Field name="password" type="password" id="password" v-model="formValues.password" /> <ErrorMessage name="password" /> <label for="confirmation">Confirm Password</label> <Field name="confirmPassword" type="password" id="confirmation" v-model="formValues.password" /> <ErrorMessage name="confirmPassword" /> </template> <template v-if="currentStep === 2"> <label for="address">Address</label> <Field as="textarea" name="address" id="address" v-model="formValues.address" /> <ErrorMessage name="address" /> <label for="postalCode">Postal Code</label> <Field name="postalCode" id="postalCode" v-model="formValues.postalCode" /> <ErrorMessage name="postalCode" /> </template> <template v-if="currentStep === 3"> <label for="terms">Agree to terms and conditions</label> <Field name="terms" type="checkbox" id="terms" :value="true" v-model="formValues.terms" /> <ErrorMessage name="terms" /> </template> <button v-if="currentStep !== 0" type="button" @click="prevStep"> Previous </button> <button v-if="currentStep !== 3" type="submit">Next</button> <button v-if="currentStep === 3" type="submit">Finish</button> </Form> </div> </template> <script> import { Form, Field, ErrorMessage } from "vee-validate"; import * as yup from "yup"; import { ref, reactive, computed } from "vue"; import Datepicker from 'vue3-date-time-picker'; import 'vue3-date-time-picker/dist/main.css'; import moment from 'moment'; export default { name: "App", components: { Form, Field, ErrorMessage, Datepicker }, setup: () => { const currentStep = ref(0); // since vee-validate removes values from the values object once the fields are unmounted // we would need to accumlate them manually const formValues = reactive({}); const showContainer = ref({isVisible: true}); const showOutOfCountry = ref({isVisible: false}); const showUnderAge = ref({isVisible: false}); const schemas = [ yup.object({ name: yup.string().required(), email: yup.string().required().email(), }), yup.object({ password: yup.string().required().min(6), confirmPassword: yup .string() .required() .min(6) .oneOf([yup.ref("password")], "Passwords must match"), }), yup.object({ address: yup.string().required(), postalCode: yup .string() .required() .matches(/^[0-9]+$/, "Must be numeric"), }), yup.object({ terms: yup.bool().required().equals([true]), }), ]; const currentSchema = computed(() => { return schemas[currentStep.value]; }); function getAge(dateString){ var today = new Date(); var birthDate = new Date(dateString); var age = today.getFullYear() - birthDate.getFullYear(); var m = today.getMonth() - birthDate.getMonth(); if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) { age--; } return age; } function nextStep(values) { console.log(currentStep.value) console.log(values) // Age kickout here for entire block let dobDt = moment(values.dob).format("YYYY-MM-DD"); console.log(dobDt) let age = getAge(dobDt) console.log(age) if(age < 18){ showUnderAge.value.isVisible = true; showContainer.value.isVisible = false; }else{ // Country Kick Out console.log(values.country) if(values.country !== "United States"){ showOutOfCountry.value.isVisible = true; showContainer.value.isVisible = false; console.log(showContainer) return; }else{ // Last Step if (currentStep.value === 3) { console.log("Done: ", JSON.stringify(formValues, null, 2)); return; } // accumlate the form values with the values from previous steps Object.assign(formValues, values); console.log("Current values: "); console.log(JSON.stringify(formValues, null, 2)); currentStep.value++; } } } function prevStep() { if (currentStep.value <= 0) { return; } currentStep.value--; } return { currentStep, currentSchema, prevStep, formValues, nextStep, showContainer, showOutOfCountry, showUnderAge }; }, }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } .appContainer{ max-width: 800px; margin: 30px auto; overflow: auto; min-height: 300px; padding: 30px; border-radius: 5px; border-style: solid; border-width: 1px; border-color: rgb(109, 109, 109); } label{ font-weight: bold; } .validationErrors{ color: red; font-weight: bold; } </style>
There are two ways to solve this problem. Note: You can use any date picker you like. First:
For more information, check out the vee-validate documentation. Here is the link: https://vee-validate.logaretm.com/v4/api/fields/