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