vuetify vee-validate 滚动到第一个验证错误
vuetify vee-validate scroll to the first validation error
如果在表单中单击提交按钮,如果存在错误,它应该会自动滚动到第一个验证错误。
我读过我可以为此使用 "scrolltoview",但我不知道具体如何。
我已经尝试过使用简单的 ScrollTo (0.0) 来在出现错误时简单地向上滚动,并且效果很好。
然而,这不是我想要的解决方案。
< script >
...
let name = 'm-form-user';
export default {
name: name,
mixins: [baseForm],
props: {
name: {
type: String,
default: name
},
title: {
type: String,
default: ''
},
type: {
type: String,
default: 'create',
validator: function(value) {
return ['edit', 'create'].indexOf(value) !== -1
}
},
},
data: () => ({
form: {
firstName: '',
lastName: '',
position: '',
email: '',
mobile: '',
roles: []
}
}),
async created() {
if (!this.isCreationForm && this.$route.params.id) {
if (!this.editingUser.length) {
await this.requestUser({
id: this.$route.params.id
});
}
Object.assign(this.form, this.editingUser);
this.form.roles.pop()
}
},
computed: {
...mapGetters({
getUser: "users/read"
}),
text() {
return {
cancel: this.$t('modules.forms.m-form-user.buttons.cancel'),
submit: this.$t('modules.forms.m-form-user.buttons.submit')
}
},
editingUser() {
return this.getUser(this.$route.params.id)
},
isCreationForm() {
return this.type === 'create'
}
},
methods: {
...mapActions({
requestCreateUser: 'users/create',
requestUpdateUser: 'users/update',
requestUser: 'users/read'
}),
async submit() {
const validAll = await this.$validator.validateAll();
const validIdentify = this.validateIdentify();
if (!validAll || !validIdentify) {
// ScrolltoView
return;
}
try {
this.setOrganizationRelation();
let user = this.isCreationForm ? await this.createUser() : await this.updateUser();
this.notify.success(this.$t(`notifications.account.userManagement.${ this.isCreationForm ? 'created':'edited'}`, {
firstName: user.firstName,
lastName: user.lastName
}))
this.redirect(this.nav.dashboard.account.users.view.name, {
id: user._id
})
} catch (e) {
if (e.response && e.response.status === 400) {
e.response.data.violations.forEach(violation => {
if (violation.propertyPath === 'username') return; //TODO temporary workaround, remove it when we get correct response from server
this.$validator.errors.add({
id: violation.propertyPath,
field: violation.propertyPath,
msg: violation.message
});
const field = this.$validator.fields.find({
name: violation.propertyPath
});
if (!field) {
throw `Field "${violation.propertyPath}" in "${this.$options._componentTag}" component don't have validation on client side!`;
}
field.setFlags({
invalid: true,
valid: false,
validated: true
});
});
} else {
this.notify.processUnhandledError(e);
}
}
},
async createUser() {
return await this.requestCreateUser({ ...this.form,
password: passwordGenerator.generate()
});
},
async updateUser() {
return await this.requestUpdateUser(this.form)
},
cancel() {
this.goBack();
},
validateIdentify() {
if (!this.form.email && !this.form.mobile) {
const fields = (({
email,
mobile
}) => ({
email,
mobile
}))(this.$refs);
Object.keys(fields).forEach((key) => {
let field = this.$validator.fields.find({
name: fields[key].name
});
this.$validator.errors.add({
id: field.id,
field: field.name,
msg: this.$t('modules.forms.m-form-user.sections.contacts.emptyContacts')
});
field.setFlags({
invalid: true,
valid: false,
validated: true
});
this.$refs.emailBlock.open();
this.$refs.mobileBlock.open();
});
return false;
}
return true;
},
setOrganizationRelation() {
const rel = {
organization: this.$user.relationships.organization
};
setRelations(this.form, rel)
}
}
} <
/script>
<m-block-form-fields :required="false">
<template #title>
{{$t('modules.forms.m-form-user.sections.personal.title')}}
</template>
<template>
<v-layout wrap>
<v-flex xs12>
<e-input-user-name v-model="form.firstName" rules="required" required-style/>
</v-flex>
<v-flex xs12>
<e-input-user-surname v-model="form.lastName" rules="required" required-style/>
</v-flex>
<v-flex xs12>
<e-input-user-position-function v-model="form.position"/>
</v-flex>
</v-layout>
</template>
</m-block-form-fields>
尝试使用 document.querySelector
找到第一条错误消息,如下所示。
if (!validAll || !validIdentify) {
const el = document.querySelector(".v-messages.error--text:first-of-type");
el.scrollIntoView();
return;
}
这是基于@Eldar 的回答。
因为您要更改 DOM,所以您只想在 DOM 更新后查找新元素。
我能够使它与 nextTick 一起使用。
if(!validAll || !validIdentify) {
// Run after the next update cycle
this.$nextTick(() => {
const el = this.$el.querySelector(".v-messages.error--text:first-of-type");
this.$vuetify.goTo(el);
return;
});
}
如果在表单中单击提交按钮,如果存在错误,它应该会自动滚动到第一个验证错误。 我读过我可以为此使用 "scrolltoview",但我不知道具体如何。
我已经尝试过使用简单的 ScrollTo (0.0) 来在出现错误时简单地向上滚动,并且效果很好。 然而,这不是我想要的解决方案。
< script >
...
let name = 'm-form-user';
export default {
name: name,
mixins: [baseForm],
props: {
name: {
type: String,
default: name
},
title: {
type: String,
default: ''
},
type: {
type: String,
default: 'create',
validator: function(value) {
return ['edit', 'create'].indexOf(value) !== -1
}
},
},
data: () => ({
form: {
firstName: '',
lastName: '',
position: '',
email: '',
mobile: '',
roles: []
}
}),
async created() {
if (!this.isCreationForm && this.$route.params.id) {
if (!this.editingUser.length) {
await this.requestUser({
id: this.$route.params.id
});
}
Object.assign(this.form, this.editingUser);
this.form.roles.pop()
}
},
computed: {
...mapGetters({
getUser: "users/read"
}),
text() {
return {
cancel: this.$t('modules.forms.m-form-user.buttons.cancel'),
submit: this.$t('modules.forms.m-form-user.buttons.submit')
}
},
editingUser() {
return this.getUser(this.$route.params.id)
},
isCreationForm() {
return this.type === 'create'
}
},
methods: {
...mapActions({
requestCreateUser: 'users/create',
requestUpdateUser: 'users/update',
requestUser: 'users/read'
}),
async submit() {
const validAll = await this.$validator.validateAll();
const validIdentify = this.validateIdentify();
if (!validAll || !validIdentify) {
// ScrolltoView
return;
}
try {
this.setOrganizationRelation();
let user = this.isCreationForm ? await this.createUser() : await this.updateUser();
this.notify.success(this.$t(`notifications.account.userManagement.${ this.isCreationForm ? 'created':'edited'}`, {
firstName: user.firstName,
lastName: user.lastName
}))
this.redirect(this.nav.dashboard.account.users.view.name, {
id: user._id
})
} catch (e) {
if (e.response && e.response.status === 400) {
e.response.data.violations.forEach(violation => {
if (violation.propertyPath === 'username') return; //TODO temporary workaround, remove it when we get correct response from server
this.$validator.errors.add({
id: violation.propertyPath,
field: violation.propertyPath,
msg: violation.message
});
const field = this.$validator.fields.find({
name: violation.propertyPath
});
if (!field) {
throw `Field "${violation.propertyPath}" in "${this.$options._componentTag}" component don't have validation on client side!`;
}
field.setFlags({
invalid: true,
valid: false,
validated: true
});
});
} else {
this.notify.processUnhandledError(e);
}
}
},
async createUser() {
return await this.requestCreateUser({ ...this.form,
password: passwordGenerator.generate()
});
},
async updateUser() {
return await this.requestUpdateUser(this.form)
},
cancel() {
this.goBack();
},
validateIdentify() {
if (!this.form.email && !this.form.mobile) {
const fields = (({
email,
mobile
}) => ({
email,
mobile
}))(this.$refs);
Object.keys(fields).forEach((key) => {
let field = this.$validator.fields.find({
name: fields[key].name
});
this.$validator.errors.add({
id: field.id,
field: field.name,
msg: this.$t('modules.forms.m-form-user.sections.contacts.emptyContacts')
});
field.setFlags({
invalid: true,
valid: false,
validated: true
});
this.$refs.emailBlock.open();
this.$refs.mobileBlock.open();
});
return false;
}
return true;
},
setOrganizationRelation() {
const rel = {
organization: this.$user.relationships.organization
};
setRelations(this.form, rel)
}
}
} <
/script>
<m-block-form-fields :required="false">
<template #title>
{{$t('modules.forms.m-form-user.sections.personal.title')}}
</template>
<template>
<v-layout wrap>
<v-flex xs12>
<e-input-user-name v-model="form.firstName" rules="required" required-style/>
</v-flex>
<v-flex xs12>
<e-input-user-surname v-model="form.lastName" rules="required" required-style/>
</v-flex>
<v-flex xs12>
<e-input-user-position-function v-model="form.position"/>
</v-flex>
</v-layout>
</template>
</m-block-form-fields>
尝试使用 document.querySelector
找到第一条错误消息,如下所示。
if (!validAll || !validIdentify) {
const el = document.querySelector(".v-messages.error--text:first-of-type");
el.scrollIntoView();
return;
}
这是基于@Eldar 的回答。
因为您要更改 DOM,所以您只想在 DOM 更新后查找新元素。
我能够使它与 nextTick 一起使用。
if(!validAll || !validIdentify) {
// Run after the next update cycle
this.$nextTick(() => {
const el = this.$el.querySelector(".v-messages.error--text:first-of-type");
this.$vuetify.goTo(el);
return;
});
}