Instantly share code, notes, and snippets.

Embed
What would you like to do?
Vee Validate - Child Component Example
import Vue from 'vue';
const bus = new Vue();
export default bus;
<template>
<div>
<input v-validate data-rules="required" :class="{'has-error': errors.has("textInput")}" id="textInput" name="textInput" type="text">
<span class="error" v-show="errors.has("textInput")">{{ errors.first("textInput") }}</span>
</div>
</template>
<script>
import { find, propEq } from 'ramda'
import bus from './bus'
export default {
mounted() {
//Listen on the bus for the parent component running validation
bus.$on('validate', this.onValidate)
//Watch for the changes to the childs error bag and pass back to the parent
this.$watch(() => this.errors.errors, (newValue, oldValue) => {
const newErrors = newValue.filter(error =>
find(propEq('field', error.field))(oldValue) === undefined
)
const oldErrors = oldValue.filter(error =>
find(propEq('field', error.field))(newValue) === undefined
)
bus.$emit('errors-changed', newErrors, oldErrors)
})
},
methods: {
onValidate() {
this.$validator.validateAll();
if (this.errors.any()) {
bus.$emit('errors-changed', this.errors.errors)
}
},
},
beforeDestroy() {
//When destroying the element remove the listeners on the bus.
//Useful for dynaically adding and removing child components
bus.$emit('errors-changed', [], this.errors.errors)
bus.$off('validate', this.onValidate)
},
}
</script>
<template>
<div>
<child-component></child-component>
<button :disabled="errors.any()" :click="submit()"></button>
</div>
</template>
<script>
import bus from './bus'
import ChildComponent from './ChildComponent'
export default {
mounted() {
//Emit that validation is required on the bus
this.$on('veeValidate', () => {
bus.$emit('validate');
})
//Listen on the bus for changers to the child components error bag and merge in/remove errors
bus.$on('errors-changed', (newErrors, oldErrors) => {
newErrors.forEach(error => {
if (!this.errors.has(error.field)) {
this.errors.add(error.field, error.msg)
}
})
if (oldErrors) {
oldErrors.forEach(error => {
this.errors.remove(error.field)
})
}
})
},
methods: {
submit() {
//On button pressed run validation
this.$validator.validateAll()
if (!this.errors.any()) {
//Do Sumbit
}
}
}
components: {
ChildComponent,
},
};
</script>
@sproogen

This comment has been minimized.

Show comment
Hide comment
@sproogen

sproogen Nov 9, 2016

This is an example of Child Component Validation for Vee Validate (https://github.com/logaretm/vee-validate).

For real use, all the methods in the child component could be added using a Vue Mixin (https://vuejs.org/v2/guide/mixins.html) to prevent duplicating it in every child component.

Owner

sproogen commented Nov 9, 2016

This is an example of Child Component Validation for Vee Validate (https://github.com/logaretm/vee-validate).

For real use, all the methods in the child component could be added using a Vue Mixin (https://vuejs.org/v2/guide/mixins.html) to prevent duplicating it in every child component.

@bigperson

This comment has been minimized.

Show comment
Hide comment
@bigperson

bigperson Jan 13, 2017

@sproogen
Do you have an example to solve this problem by using vuex?

bigperson commented Jan 13, 2017

@sproogen
Do you have an example to solve this problem by using vuex?

@sproogen

This comment has been minimized.

Show comment
Hide comment
@sproogen

sproogen Jan 19, 2017

@bigperson no I do not. We are using vuex in this project but I did not think we should use it for storing anything in the state.

It would be possible to store the error bag in the state, but this would need some re-writing of vee-validate.

Owner

sproogen commented Jan 19, 2017

@bigperson no I do not. We are using vuex in this project but I did not think we should use it for storing anything in the state.

It would be possible to store the error bag in the state, but this would need some re-writing of vee-validate.

@polunzh

This comment has been minimized.

Show comment
Hide comment
@polunzh

polunzh Feb 13, 2017

@sproogen
When trigger veeValidate event in parent component?

polunzh commented Feb 13, 2017

@sproogen
When trigger veeValidate event in parent component?

@tiagomatosweb

This comment has been minimized.

Show comment
Hide comment
@tiagomatosweb

tiagomatosweb Feb 24, 2017

Hi, I'm trying to use this example but VeeValidation is not being triggered. Nothing happens when I hit submit. I could build all child validations, but I'm stuck on the submit stuff. How would I check the current validation to then submit the form? tks

tiagomatosweb commented Feb 24, 2017

Hi, I'm trying to use this example but VeeValidation is not being triggered. Nothing happens when I hit submit. I could build all child validations, but I'm stuck on the submit stuff. How would I check the current validation to then submit the form? tks

@cdarken

This comment has been minimized.

Show comment
Hide comment
@cdarken

cdarken Apr 4, 2017

@sproogen mate, the line here https://gist.github.com/sproogen/147d75db261505e8a558a7fd11a20551#file-parentcomponent-vue-L16 is a bit misleading because at https://gist.github.com/sproogen/147d75db261505e8a558a7fd11a20551#file-parentcomponent-vue-L36 you're using this.$validator. Can you update the gist to be a bit more clear, please ?

cdarken commented Apr 4, 2017

@sproogen mate, the line here https://gist.github.com/sproogen/147d75db261505e8a558a7fd11a20551#file-parentcomponent-vue-L16 is a bit misleading because at https://gist.github.com/sproogen/147d75db261505e8a558a7fd11a20551#file-parentcomponent-vue-L36 you're using this.$validator. Can you update the gist to be a bit more clear, please ?

@kamihouse

This comment has been minimized.

Show comment
Hide comment
@kamihouse

kamihouse Apr 6, 2017

Is there any way to make the errors object global? Would make things easier.

kamihouse commented Apr 6, 2017

Is there any way to make the errors object global? Would make things easier.

@pimboden

This comment has been minimized.

Show comment
Hide comment
@pimboden

pimboden Apr 11, 2017

I can't get this working... validateAll() is a promise, so I don't really see how this should work

pimboden commented Apr 11, 2017

I can't get this working... validateAll() is a promise, so I don't really see how this should work

@lehni

This comment has been minimized.

Show comment
Hide comment
@lehni

lehni May 4, 2017

@sproogen I believe I found a simpler way to address this situation, see baianat/vee-validate#468 (comment)

At the moment, this requires a bit of hacking with the internals of vee-validate to remove the beforeCreate() and mounted() hooks, but maybe this pattern can find its way into the library...

lehni commented May 4, 2017

@sproogen I believe I found a simpler way to address this situation, see baianat/vee-validate#468 (comment)

At the moment, this requires a bit of hacking with the internals of vee-validate to remove the beforeCreate() and mounted() hooks, but maybe this pattern can find its way into the library...

@StMacLennan

This comment has been minimized.

Show comment
Hide comment
@StMacLennan

StMacLennan Jun 1, 2017

I tried for 6 hours to get this working with my app (as I have deeply nested components). Eventually, I just used this Advanced -
Inject
and had it solved in 3 minutes flat. If you can't get the above to work, try the injection route!

StMacLennan commented Jun 1, 2017

I tried for 6 hours to get this working with my app (as I have deeply nested components). Eventually, I just used this Advanced -
Inject
and had it solved in 3 minutes flat. If you can't get the above to work, try the injection route!

@lattam

This comment has been minimized.

Show comment
Hide comment
@lattam

lattam Jul 5, 2017

@stephenmac that's perfect, thanks! One line in child component solves everything (I have a form with several sub-form components).

inject: ['$validator']

lattam commented Jul 5, 2017

@stephenmac that's perfect, thanks! One line in child component solves everything (I have a form with several sub-form components).

inject: ['$validator']

@renanpro03

This comment has been minimized.

Show comment
Hide comment
@renanpro03

renanpro03 Jul 24, 2017

@lattam this not worked for me... any idea?

renanpro03 commented Jul 24, 2017

@lattam this not worked for me... any idea?

@DraughtGlobe

This comment has been minimized.

Show comment
Hide comment
@DraughtGlobe

DraughtGlobe Jul 26, 2017

Simply adding that single line @lattam talks about didn't work for me either. I also had to do Vue.use(VeeValidate, { inject: false }); and manually set the validator on the parent element with: $validates: true,

DraughtGlobe commented Jul 26, 2017

Simply adding that single line @lattam talks about didn't work for me either. I also had to do Vue.use(VeeValidate, { inject: false }); and manually set the validator on the parent element with: $validates: true,

@woodyalan

This comment has been minimized.

Show comment
Hide comment
@woodyalan

woodyalan Aug 31, 2017

I add inject: ['$validator'] in child component but show a warning Injection "__ob__" not found

woodyalan commented Aug 31, 2017

I add inject: ['$validator'] in child component but show a warning Injection "__ob__" not found

@imjeen

This comment has been minimized.

Show comment
Hide comment
@imjeen

imjeen Sep 7, 2017

vee-validate@2.0.0-rc.14:
this.errors.errors should be this.errors.items

imjeen commented Sep 7, 2017

vee-validate@2.0.0-rc.14:
this.errors.errors should be this.errors.items

@pymarco

This comment has been minimized.

Show comment
Hide comment
@pymarco

pymarco Sep 8, 2017

I get Injection "__ob__" not found too, the same as @woodyalan.

pymarco commented Sep 8, 2017

I get Injection "__ob__" not found too, the same as @woodyalan.

@dokicro

This comment has been minimized.

Show comment
Hide comment
@dokicro

dokicro Feb 23, 2018

@lattam this works perfectly!

dokicro commented Feb 23, 2018

@lattam this works perfectly!

@CouturierDeA

This comment has been minimized.

Show comment
Hide comment
@CouturierDeA

CouturierDeA Feb 25, 2018

You can use the instance of the parent validator in the child component (this.$validator = this.$parent.$validator in child component created hook) to validate all of the child components from the parent instance.

CouturierDeA commented Feb 25, 2018

You can use the instance of the parent validator in the child component (this.$validator = this.$parent.$validator in child component created hook) to validate all of the child components from the parent instance.

@Banandrew

This comment has been minimized.

Show comment
Hide comment
@Banandrew

Banandrew Apr 20, 2018

If someone stumbles on this gist in the future, you can also use Vue’s provide/inject API to request the parent’s validator instance.

Banandrew commented Apr 20, 2018

If someone stumbles on this gist in the future, you can also use Vue’s provide/inject API to request the parent’s validator instance.

@garymcm

This comment has been minimized.

Show comment
Hide comment
@garymcm

garymcm Apr 28, 2018

Taking the multiple clues from the last 10 messages here, the way I got this to work was:

Parent Component:

...
provide () {
    return { parentValidator: this.$validator }
  },
...

Child Component:

...
inject: [ 'parentValidator' ],
...
 created () {
    this.$validator = this.parentValidator
  }
...

garymcm commented Apr 28, 2018

Taking the multiple clues from the last 10 messages here, the way I got this to work was:

Parent Component:

...
provide () {
    return { parentValidator: this.$validator }
  },
...

Child Component:

...
inject: [ 'parentValidator' ],
...
 created () {
    this.$validator = this.parentValidator
  }
...
@mixn

This comment has been minimized.

Show comment
Hide comment
@mixn

mixn Jun 20, 2018

@garymcm That worked perfectly — thank you! :)

mixn commented Jun 20, 2018

@garymcm That worked perfectly — thank you! :)

@tkachev-o

This comment has been minimized.

Show comment
Hide comment
@tkachev-o

tkachev-o commented Jul 24, 2018

@garymcm thank you .

@forforeach

This comment has been minimized.

Show comment
Hide comment
@forforeach

forforeach Jul 24, 2018

As @Banandrew wrote, you can use inject API. The link was updated so here is an updated link -> https://baianat.github.io/vee-validate/concepts/injections.html#injecting-parent-validator

forforeach commented Jul 24, 2018

As @Banandrew wrote, you can use inject API. The link was updated so here is an updated link -> https://baianat.github.io/vee-validate/concepts/injections.html#injecting-parent-validator

@jurifo

This comment has been minimized.

Show comment
Hide comment
@jurifo

jurifo commented Aug 1, 2018

@garymcm thanks

@helmsquared

This comment has been minimized.

Show comment
Hide comment
@helmsquared

helmsquared Aug 7, 2018

@garymcm this worked perfectly, many thanks!

helmsquared commented Aug 7, 2018

@garymcm this worked perfectly, many thanks!

@jb-reynaud

This comment has been minimized.

Show comment
Hide comment
@jb-reynaud

jb-reynaud commented Aug 24, 2018

@garymcm thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment