vuetify vee-validate scroll to the first validation error

Total
11
Shares

If the submit button is clicked in a form, it should automatically scroll to the first validation error if an error exists.
I’ve read that I can use “scrolltoview” for this, but I don’t know exactly how.

I have already tried it with a simple ScrollTo (0.0) to simply scroll up in the event of errors and it works perfectly.
However, this is not the solution I would like to have.

_x000D_

_x000D_

< script >_x000D_
  ..._x000D_
  let name = 'm-form-user';_x000D_
export default {_x000D_
  name: name,_x000D_
  mixins: [baseForm],_x000D_
  props: {_x000D_
    name: {_x000D_
      type: String,_x000D_
      default: name_x000D_
    },_x000D_
    title: {_x000D_
      type: String,_x000D_
      default: ''_x000D_
    },_x000D_
    type: {_x000D_
      type: String,_x000D_
      default: 'create',_x000D_
      validator: function(value) {_x000D_
        return ['edit', 'create'].indexOf(value) !== -1_x000D_
      }_x000D_
    },_x000D_
  },_x000D_
  data: () => ({_x000D_
    form: {_x000D_
      firstName: '',_x000D_
      lastName: '',_x000D_
      position: '',_x000D_
      email: '',_x000D_
      mobile: '',_x000D_
      roles: []_x000D_
    }_x000D_
  }),_x000D_
  async created() {_x000D_
    if (!this.isCreationForm && this.$route.params.id) {_x000D_
      if (!this.editingUser.length) {_x000D_
        await this.requestUser({_x000D_
          id: this.$route.params.id_x000D_
        });_x000D_
      }_x000D_
      Object.assign(this.form, this.editingUser);_x000D_
      this.form.roles.pop()_x000D_
    }_x000D_
  },_x000D_
  computed: {_x000D_
    ...mapGetters({_x000D_
      getUser: "users/read"_x000D_
    }),_x000D_
_x000D_
    text() {_x000D_
      return {_x000D_
        cancel: this.$t('modules.forms.m-form-user.buttons.cancel'),_x000D_
        submit: this.$t('modules.forms.m-form-user.buttons.submit')_x000D_
      }_x000D_
    },_x000D_
_x000D_
    editingUser() {_x000D_
      return this.getUser(this.$route.params.id)_x000D_
    },_x000D_
    isCreationForm() {_x000D_
      return this.type === 'create'_x000D_
    }_x000D_
  },_x000D_
  methods: {_x000D_
    ...mapActions({_x000D_
      requestCreateUser: 'users/create',_x000D_
      requestUpdateUser: 'users/update',_x000D_
      requestUser: 'users/read'_x000D_
    }),_x000D_
    async submit() {_x000D_
      const validAll = await this.$validator.validateAll();_x000D_
      const validIdentify = this.validateIdentify();_x000D_
_x000D_
      if (!validAll || !validIdentify) {_x000D_
_x000D_
_x000D_
        // ScrolltoView_x000D_
_x000D_
        return;_x000D_
      }_x000D_
_x000D_
_x000D_
      try {_x000D_
        this.setOrganizationRelation();_x000D_
        let user = this.isCreationForm ? await this.createUser() : await this.updateUser();_x000D_
        this.notify.success(this.$t(`notifications.account.userManagement.${ this.isCreationForm ? 'created':'edited'}`, {_x000D_
          firstName: user.firstName,_x000D_
          lastName: user.lastName_x000D_
        }))_x000D_
        this.redirect(this.nav.dashboard.account.users.view.name, {_x000D_
          id: user._id_x000D_
        })_x000D_
      } catch (e) {_x000D_
        if (e.response && e.response.status === 400) {_x000D_
          e.response.data.violations.forEach(violation => {_x000D_
            if (violation.propertyPath === 'username') return; //TODO temporary workaround, remove it when we get correct response from server_x000D_
            this.$validator.errors.add({_x000D_
              id: violation.propertyPath,_x000D_
              field: violation.propertyPath,_x000D_
              msg: violation.message_x000D_
            });_x000D_
_x000D_
_x000D_
            const field = this.$validator.fields.find({_x000D_
              name: violation.propertyPath_x000D_
            });_x000D_
_x000D_
            if (!field) {_x000D_
              throw `Field "${violation.propertyPath}" in "${this.$options._componentTag}" component don't have validation on client side!`;_x000D_
            }_x000D_
_x000D_
            field.setFlags({_x000D_
              invalid: true,_x000D_
              valid: false,_x000D_
              validated: true_x000D_
            });_x000D_
          });_x000D_
        } else {_x000D_
          this.notify.processUnhandledError(e);_x000D_
        }_x000D_
      }_x000D_
_x000D_
    },_x000D_
    async createUser() {_x000D_
      return await this.requestCreateUser({ ...this.form,_x000D_
        password: passwordGenerator.generate()_x000D_
      });_x000D_
    },_x000D_
    async updateUser() {_x000D_
      return await this.requestUpdateUser(this.form)_x000D_
    },_x000D_
    cancel() {_x000D_
      this.goBack();_x000D_
    },_x000D_
_x000D_
    validateIdentify() {_x000D_
      if (!this.form.email && !this.form.mobile) {_x000D_
        const fields = (({_x000D_
          email,_x000D_
          mobile_x000D_
        }) => ({_x000D_
          email,_x000D_
          mobile_x000D_
        }))(this.$refs);_x000D_
        Object.keys(fields).forEach((key) => {_x000D_
          let field = this.$validator.fields.find({_x000D_
            name: fields[key].name_x000D_
          });_x000D_
_x000D_
          this.$validator.errors.add({_x000D_
            id: field.id,_x000D_
            field: field.name,_x000D_
            msg: this.$t('modules.forms.m-form-user.sections.contacts.emptyContacts')_x000D_
          });_x000D_
_x000D_
          field.setFlags({_x000D_
            invalid: true,_x000D_
            valid: false,_x000D_
            validated: true_x000D_
          });_x000D_
_x000D_
          this.$refs.emailBlock.open();_x000D_
          this.$refs.mobileBlock.open();_x000D_
        });_x000D_
        return false;_x000D_
      }_x000D_
      return true;_x000D_
    },_x000D_
    setOrganizationRelation() {_x000D_
      const rel = {_x000D_
        organization: this.$user.relationships.organization_x000D_
      };_x000D_
      setRelations(this.form, rel)_x000D_
    }_x000D_
  }_x000D_
} <_x000D_
/script>

_x000D_

<m-block-form-fields :required="false">_x000D_
  <template #title>_x000D_
                    {{$t('modules.forms.m-form-user.sections.personal.title')}}_x000D_
                </template>_x000D_
_x000D_
  <template>_x000D_
                    <v-layout wrap>_x000D_
                        <v-flex xs12>_x000D_
                            <e-input-user-name v-model="form.firstName" rules="required" required-style/>_x000D_
                        </v-flex>_x000D_
                        <v-flex xs12>_x000D_
                            <e-input-user-surname v-model="form.lastName" rules="required" required-style/>_x000D_
                        </v-flex>_x000D_
                        <v-flex xs12>_x000D_
                            <e-input-user-position-function v-model="form.position"/>_x000D_
                        </v-flex>_x000D_
                    </v-layout>_x000D_
                </template>_x000D_
</m-block-form-fields>

_x000D_

_x000D_

_x000D_


Solution

Try using document.querySelector to locate the first error message like below.

      if (!validAll || !validIdentify) {
        const el = document.querySelector(".v-messages.error--text:first-of-type");
        el.scrollIntoView();
        return;
      }
Leave a Reply

Your email address will not be published. Required fields are marked *