Create a gist now

Instantly share code, notes, and snippets.

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?

@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

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.

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

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 logaretm/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 logaretm/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!

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?

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

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

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.

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.

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.

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