1
votes

In @vue/cli 4.0.5 app I installed "vee-validate": "^3.0.11" and have problems with it, as trying to set common validation rules for email field:

<validation-provider rules="required|email" v-slot="{ errors }">
<input
        type='email'
        v-model="form.email"
        name="email"
        id="email"
        class="form-control editable_field" placeholder="Email Address"
>
<span>{{ errors[0] }}</span>
</validation-provider>

   ...
<script>
    import {ValidationProvider, extend} from 'vee-validate'
    import {required, email} from 'vee-validate'
    extend('required', value => !!value);
    extend('email', value => !!value);

validation does not at all, no error messages or console errors...

What is wrong ?

MODIFIED # 2 :

looking at docs and live example https://codesandbox.io/s/jdqzk I try to make form with validation and got error :

vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in v-on handler: "TypeError: handleSubmit is not a function"

found in ---> at src/views/auth/Login.vue

My src/views/auth/Login.vue :

<template>
   <div class="page_content_container">

      <div class="page_content_content col-xs-12 col-sm-10 col-md-6 mx-auto">

         <ValidationObserver v-slot="{ handleSubmit }">
            <form class="login" v-on:submit.prevent="handleSubmit(authenticate)">
               <div class="card">

                  <div class="card-body card-block">

                     <div class="block_2columns_md m-3"> <!-- email -->

                        <div class="key_values_rows_label_13 m-0 p-0">
                           <label class="col-form-label" for="email">Email:</label>
                        </div>
                        <div class="key_values_rows_value_13 m-0 p-0">
                           <div class="col-12">
                              <div class="input-group">
                                 <div class="input-group-addon">
                                    <i :class="'i_link '+getHeaderIcon('email')"></i>
                                 </div>
                                 <ValidationProvider
                                       rules="required"
                                       immediate
                                       v-slot="{ errors }"
                                 >
                                    <input
                                          v-model="form.email"
                                          name="email"
                                          id="email"
                                          class="form-control editable_field" placeholder="Email Address"
                                    >
                                 </ValidationProvider>
                              </div>
                           </div>
                        </div>

                     </div> <!-- <div class="block_2columns_md m-0"> email -->

                     <div class="block_2columns_md m-3"> <!-- password -->

                        <div class="key_values_rows_label_13 m-0 p-0">
                           <label class="col-form-label" for="password">Password:</label>
                        </div>
                        <div class="key_values_rows_value_13 m-0 p-0">
                           <div class="col-12">
                              <div class="input-group">
                                 <div class="input-group-addon">
                                    <i :class="'i_link '+getHeaderIcon('password')"></i>
                                 </div>
                                 <input type="password" v-model="form.password" id="password" name="password" class="form-control editable_field"
                                        placeholder="Password"
                                 >
                              </div>
                           </div>
                        </div>

                     </div> <!-- <div class="block_2columns_md m-0"> password -->

                  </div> <!-- <div class="card-body card-block"> -->

                  <div class="card-footer m-0 p-0">
                     <div class="form-row m-1" style="justify-content: flex-end;">
                        <button type="reset" class="btn btn-danger btn-sm m-2">
                           <i :class="'i_link '+getHeaderIcon('cancel')"></i>Home
                        </button>
                        <button type="submit" class="btn btn-success btn-sm m-2 ml-4 mr-4">
                           <i :class="'i_link '+getHeaderIcon('save')"></i>Submit
                        </button>
                     </div>
                  </div>

               </div> <!-- <div class="card"> -->

            </form>
         </ValidationObserver>

      </div> <!-- page_content_content -->

   </div> <!-- page_content_container -->
</template>

<script>
    import {bus} from '../../../src/main'
    import appMixin from '@/appMixin'

    import {ValidationObserver, ValidationProvider, localize, extend} from 'vee-validate'
    import en from 'vee-validate/dist/locale/en.json';
    import * as rules from 'vee-validate/dist/rules';

    localize('en', en);

    extend('required', {
        validate(value) {
            return {
                required: true,
                valid: ['', null, undefined].indexOf(value) === -1
            };
        },
        computesRequired: true
    });

    export default {
        name: 'loginPage',

        components: {
            ValidationObserver, ValidationProvider
        },

        data() {
            return {
                form: {
                    email: '',
                    password: ''
                },
                error: null,
                site_name: process.env.VUE_APP_SITE_NAME
            }
        },

        mixins: [appMixin],

        methods: {
            authenticate() {
                alert('authenticate::' + (-3))

                console.log('authenticate  this.form::')
                console.log(this.form)

                this.$store.dispatch('login', this.form)
                    .then(() => this.$router.push('/'))
                    .catch(err => console.log(err))
            }
        }, // methods: {

        computed: {
            authError() {
                return this.$store.getters.authError
            }
        } // computed: {
    }

</script>

I expected that handleSubmit is defined in vee-validate library... In the examples I do not see it imported additively. I tried to create my own handleSubmit method but error anyway...

How to fix it ?

MODIFIED # 3 :

I moved to 3.1 and my /package.json now :

{
  "name": "ctasks",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "axios": "^0.19.0",
    "core-js": "^3.3.2",
    "font-awesome": "^4.7.0",
    "moment": "^2.24.0",
    "moment-timezone": "^0.5.27",
    "vee-validate": "^3.1.0",
    "vue": "^2.6.10",
    "vue-focus": "^2.1.0",
    "vue-js-modal": "^1.3.31",
    "vue-notification": "^1.3.20",
    "vue-router": "^3.1.3",
    "vue-select": "^3.2.0",
    "vue2-filters": "^0.8.0",
    "vuex": "^3.0.1"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.0.0",
    "@vue/cli-plugin-router": "^4.0.0",
    "@vue/cli-plugin-vuex": "^4.0.0",
    "@vue/cli-service": "^4.0.0",
    "bootstrap": "^4.3.1",
    "jquery": "^3.4.1",
    "node-sass": "^4.12.0",
    "popper.js": "^1.16.0",
    "sass-loader": "^8.0.0",
    "vue-template-compiler": "^2.6.10"
  }
}

and

run npm install  

I remade my page according to https://codesandbox.io/s/rsmwq example with loginData defining as form data var:

<template>
    <div class="page_content_container">

        <div class="page_content_content col-xs-12 col-sm-10 col-md-6 mx-auto">

            <ValidationObserver ref="form">
                <form class="login" @submit.prevent="handleSubmit(onSubmit)">
                    <div class="card">

                        <div class="card-body card-block">

                            <div class="block_2columns_md m-3"> <!-- email -->

                                <div class="key_values_rows_label_13 m-0 p-0">
                                    <label class="col-form-label" for="email">Email:</label>
                                </div>
                                <div class="key_values_rows_value_13 m-0 p-0">
                                    <div class="col-12">
                                        <div class="input-group">
                                            <div class="input-group-addon">
                                                <i :class="'i_link '+getHeaderIcon('email')"></i>
                                            </div>
                                            <ValidationProvider
                                                    rules="required"
                                                    immediate
                                                    v-slot="{ errors }"
                                            >
                                                <input
                                                        v-model="loginData.email"
                                                        name="email"
                                                        id="email"
                                                        class="form-control editable_field" placeholder="Email Address"
                                                >
                                            </ValidationProvider>
                                        </div>
                                    </div>
                                </div>

                            </div> <!-- <div class="block_2columns_md m-0"> email -->

                            <div class="block_2columns_md m-3"> <!-- password -->

                                <div class="key_values_rows_label_13 m-0 p-0">
                                    <label class="col-form-label" for="password">Password:</label>
                                </div>
                                <div class="key_values_rows_value_13 m-0 p-0">
                                    <div class="col-12">
                                        <div class="input-group">
                                            <div class="input-group-addon">
                                                <i :class="'i_link '+getHeaderIcon('password')"></i>
                                            </div>
                                            <input type="password" v-model="loginData.password" id="password" name="password" class="form-control editable_field"
                                                   placeholder="Password"
                                            >
                                        </div>
                                    </div>
                                </div>

                            </div> <!-- <div class="block_2columns_md m-0"> password -->

                        </div> <!-- <div class="card-body card-block"> -->

                        <div class="card-footer m-0 p-0">
                            <div class="form-row m-1" style="justify-content: flex-end;">
                                <button type="reset" class="btn btn-danger btn-sm m-2">
                                    <i :class="'i_link '+getHeaderIcon('cancel')"></i>Home
                                </button>
                                <button type="submit" class="btn btn-success btn-sm m-2 ml-4 mr-4">
                                    <i :class="'i_link '+getHeaderIcon('save')"></i>Submit
                                </button>
                            </div>
                        </div>

                    </div> <!-- <div class="card"> -->

                </form>
            </ValidationObserver>

        </div> <!-- page_content_content -->

    </div> <!-- page_content_container -->
</template>

<script>
    import {bus} from '../../../src/main'
    import appMixin from '@/appMixin'

    import {ValidationObserver, ValidationProvider, localize, extend} from 'vee-validate'
    import en from 'vee-validate/dist/locale/en.json';
    import * as rules from 'vee-validate/dist/rules';

    localize('en', en);

    extend('required', {
        validate(value) {
            return {
                required: true,
                valid: ['', null, undefined].indexOf(value) === -1
            };
        },
        computesRequired: true
    });

    export default {
        name: 'loginPage',

        components: {
            ValidationObserver, ValidationProvider
        },

        data() {
            return {
                loginData: {
                    email: '',
                    password: ''
                },
                error: null,
                site_name: process.env.VUE_APP_SITE_NAME
            }
        },

        mixins: [appMixin],


        methods: {
            onSubmit() {

                    this.$refs.form.validate().then(success => {
                        if (!success) {
                            return;
                        }

                        alert('Form has been submitted!');

                        this.firstName = this.lastName = this.email = '';

                        this.$nextTick(() => {
                            this.$refs.form.reset();
                        });
                    });
            } // onSubmit

        }, // methods: {

        computed: {
            authError() {
                return this.$store.getters.authError
            }
        } // computed: {
    }

</script>

But clickinbg on Submit button I still got error:

vue.runtime.esm.js?2b0e:619 [Vue warn]: Property or method "handleSubmit" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

and I do not see what is wrong with my code ?

Thanks!

2

2 Answers

1
votes

You should read the guide on required fields, quoting from the docs:

vee-validate doesn't validate optional fields when they are empty. Which makes sense, if the user didn't input any value in an optional field, it is valid. Until they've entered a non-empty value, rules won't be run.

See Required fields.

0
votes

Thanks @Ryley! I remade my form as:

<ValidationObserver ref="form" v-slot="{handleSubmit}">
...
   <ValidationProvider
      name="Password"
      rules="required"
      v-slot="{ errors }"
   > 
      <div class="input-group">
         <div class="input-group-addon">
            <i :class="'i_link '+getHeaderIcon('users')"></i>
         </div>
         <input
              type='text'
              v-model="form.name"
              name="name"
              id="name"
              class="form-control editable_field" placeholder="Username"
         >
      </div>
       <div class="validation_error">{{ errors[0] }}</div>
   </ValidationProvider>

and validation works ok!