2

Versions

VueJs: 2.3.3
Vee-Validate: 2.0.0-rc.25

Description

I have a custom component. It is a input with a characteres counter, and i tried to put vee-validate inside this input. I want to show errors when Form is Submited. I followed every step in vee-validate document, but it did not work. My form submits itself ignoring any input's error.

Steps To Reproduce:

Create a custom component using vee-validate

CODE:

Parent.vue

   <vue-input maxlength="20" minlength="3" placeholder="works"
    validate="required|numeric" v-model="dataItem.teste" name="teste"></vue-input>

Component.js

Vue.component('vue-input', {
    props: ['maxlength', 'minlength', 'placeholder', 'validate', 'value', 'name'],
    template: `<div>
              <div class="input-group">
                <input type="text" :name="name" :value="value" 
                @input="$emit('input', $event.target.value); 
                counter = $event.target.value.length" 
                :maxlength="maxlength" :placeholder="placeholder" 
                v-validate="validate" 
                :class="{'is-danger': errors.has(name), 'form-control' : true}">

                Erros: {{errors}}
                <span class="input-group-addon">
                    {{ maxlength - counter }}
                </span>

                <span v-show="errors.has(name)" class="text-danger m-t-xs">
                    {{ errors.first(name) }}
                </span>
             </div>
             </div>`,
             data: () => ({
                 counter: 0
             })
});
3
  • How does your form look like? Commented Dec 27, 2017 at 2:14
  • Like this first: jqueryscript.net/images/… Commented Dec 27, 2017 at 11:01
  • I mean the layout and component for your form. Commented Dec 27, 2017 at 11:05

1 Answer 1

5

You can use the parent $validator in the children component.

See created() hook in children component:

Children.vue

<template>
  <div>
    <div class="input-group">
      <input
          type="text"
          :name="name"
          :value="value"
          @input="handleInput"
          :maxlength="maxlength"
          :placeholder="placeholder"
          v-validate="validate"
          :class="{'is-danger': $errors.has(name), 'form-control' : true}"
      >

      Errors: {{ $errors }}
      <span class="input-group-addon">
        {{ maxlength - counter }}
      </span>

      <span v-show="$errors.has(name)" class="text-danger m-t-xs">
        {{ $errors.first(name) }}
      </span>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'Temp',

    props: ['maxlength', 'minlength', 'placeholder', 'validate', 'value', 'name'],

    data: () => ({
      counter: 0
    }),

    methods: {
      handleInput (event) {
        this.$emit('input', event.target.value)
        this.counter = event.target.value.length
      }
    },

    created () {
      this.$validator = this.$parent.$validator
    }
  }
</script>

Parent.vue

<children
    maxlength="20"
    minlength="3"
    placeholder="works"
    validate="required|numeric"
    v-model="dataItem.teste"
    name="teste"
></children>

There are 2 better supported solutions but you need to move the <span> with validation in the Parent.vue component, because errors/$validator will NOT be available in the Children.vue component.

Also, I was not able to have multiple input components with the same name in the same form, but you can look into them and test it out:

Solution 1

you can use Vue's provide/inject API:

Children.vue

export default {
  inject: ['$validator'],
  // ...
}

Solution 2

use VeeValidate's constructor options:

Children.vue

export default {
  $_veeValidate: {
    // value getter
    value () {
      return this.value
    },
    // component name getter
    name () {
      return 'children'
    }
  }
  // ...
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.