Vee-validate: Scroll to input with validation error v3.0

Created on 3 Oct 2019  Â·  11Comments  Â·  Source: logaretm/vee-validate

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' })
}

})
}

duplicate ✨ enhancement

Most helpful comment

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
  }
});

All 11 comments

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;
    }
  }
}
Was this page helpful?
0 / 5 - 0 ratings