I'm currently updating to Vee-Validate 3. In Vee-Validate 2 I had my own custom logic using this.$validator.errors in order to find the elements with errors and scroll to the first one.
I'm struggling to find a way to do this in Vee-validate 3. Is there a way to get an observers errors within the js submit method? Something like this.$refs.observer.errors.
eg.
```
submit() {
this.$refs.signupForm.validate().then(valid => {
if (valid) {
this.register()
} else {
// scroll to element with error
// the old way I used to do it in vee-validate 2
// document.getElementsByName([this.$validator.errors.items[0].field])[0].scrollIntoView({ block: 'center' })
}
})
}
This is similar to #2350 #2248
Thanks @logaretm
I've managed to achieve what I need using this.$refs.observer.ctx.errors
@logaretm Hello, any ideas to achieve the same behavior with the 3.1 version? (we don't have access to the ctx anymore)
https://github.com/logaretm/vee-validate/pull/2535 will this pull request allow us to access to the id of the element that is invalid ? if so i guess this solves my case :)
@JoelPintoRibeiro Was you able to solve it?
@JoelPintoRibeiro Was you able to solve it?
Yes i found an alternative way to do it based on the class and some js like this :
this.$nextTick(() => {
//scroll to the first error
let elementsInErrors = document.getElementsByClassName('failed');
if (elementsInErrors && elementsInErrors.length > 0) {
elementsInErrors[0].scrollIntoView();
}
});
Not sure that's the best solution but it works in my case
@zefexdeveloper
Thank you @JoelPintoRibeiro. @logaretm Can you help us with this? Your opinion would be much appreciated here.
I manage to solve this with the help of #2248 and https://stackoverflow.com/a/49629733/1530437
this.$refs.form.validate().then(success => {
if (!success) {
setTimeout(() => {
const errors = Object.entries(this.$refs.form.errors)
.map(([key, value]) => ({ key, value }))
.filter(error => error["value"].length);
this.$refs.form.refs[errors[0]["key"]].$el.scrollIntoView({
behavior: "smooth",
block: "center"
});
}, 100);
} else {
// success
}
});
I manage to solve this with the help of #2248 and https://stackoverflow.com/a/49629733/1530437
this.$refs.form.validate().then(success => { if (!success) { setTimeout(() => { const errors = Object.entries(this.$refs.form.errors) .map(([key, value]) => ({ key, value })) .filter(error => error["value"].length); this.$refs.form.refs[errors[0]["key"]].$el.scrollIntoView({ behavior: "smooth", block: "center" }); }, 100); } else { // success } });
Solved my issue, thanks.
updated @jbalzar version
const errors = Object.entries(this.$refs.observer.refs)
.map(([key, value]) => ({
key,
value
}))
.filter(error => {
if (!error || !error.value || !error.value.failedRules) return false;
return Object.keys(error.value.failedRules).length > 0;
});
if (errors && errors.length > 0) {
this.$refs.observer.refs[errors[0]['key']].$el.scrollIntoView({
behavior: 'smooth',
block: 'center'
});
}
ValidationObserver has fields property. Can I use these fields?
As a premise, keys (_vee_n) are consecutive.
const observer = this.$refs.observer;
const success = await observer.validate();
if (!success) {
for (const key of Object.keys(observer.fields).sort()) {
if (observer.fields[key].invalid) {
observer.refs[key].$el.scrollIntoView();
return;
}
}
}
Most helpful comment
I manage to solve this with the help of #2248 and https://stackoverflow.com/a/49629733/1530437