简体   繁体   中英

vue vee-validate issue capturing date-picker selection

Something is not working with the v-model bind on my date-picker field.

It will update live on the screen as you make selections, but it does not store the value in the formValues reactive object.

Since vee-validate does not have support for a date-picker field, how do i force this to update into the same reactive component that all my other input fields are mapping to just fine (formValues).

<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>


to solve this issue there is tow approach. note: you can use any date picker you prefer. First:

 <Field name="start_date":class="{'is-invalid': errors.start_date}" v-slot="{ field }" class="form-control" > <el-date-picker v-bind="field" type="date" placeholder="Pick a day" size="default" /> </Field>
II approach

 <Form @submit="onSubmit":validation-schema="schema" v-slot="{errors, values}"> <Field name="end_date":class="{'is-invalid': errors.end_date}" class="form-control" > {{values.end_date}} <el-date-picker v-model="values.end_date" type="date" placeholder="Pick a day" size="default" > </Field> </Form>

For more info check the vee-validate docs. here is the link: https://vee-validate.logaretm.com/v4/api/field/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM