pref: scroll to the error location when form submission validation fails (#4358)

#### What type of PR is this?

/kind improvement
/area console

#### What this PR does / why we need it:

为 `Formkit` 添加自动滚动至错误的插件,当表单校验不通过时,如果错误处被隐藏,则会滚动至错误处。

#### Which issue(s) this PR fixes:

Fixes #4317 

#### Special notes for your reviewer:

找到表单中的必选项或其他校验项,尝试填写一个错误的选项。之后滚动表单直到隐藏当前项,此时点击提交,查看是否能够自动滚动至对应的错误项。

#### Does this PR introduce a user-facing change?
```release-note
当表单填写错误时,将会自动滚动至错误项。
```
pull/4371/head^2
Takagi 2023-08-03 15:51:27 +08:00 committed by GitHub
parent 355fb860e5
commit 9b8b4294e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 0 deletions

View File

@ -24,6 +24,7 @@ import radioAlt from "./plugins/radio-alt";
import stopImplicitSubmission from "./plugins/stop-implicit-submission";
import passwordPreventAutocomplete from "./plugins/password-prevent-autocomplete";
import requiredAsterisk from "./plugins/required-asterisk";
import autoScrollToErrors from "./plugins/auto-scroll-to-errors";
const config: DefaultConfigOptions = {
config: {
@ -34,6 +35,7 @@ const config: DefaultConfigOptions = {
stopImplicitSubmission,
passwordPreventAutocomplete,
requiredAsterisk,
autoScrollToErrors,
],
inputs: {
form,

View File

@ -0,0 +1,34 @@
import type { FormKitNode } from "@formkit/core";
export default function autoScrollToErrors(node: FormKitNode) {
const scrollTo = (node: FormKitNode) => {
if (!node.props.id) {
return;
}
const el = document.getElementById(node.props.id);
if (el) {
el.scrollIntoView({ block: "end", inline: "nearest" });
}
};
const scrollToErrors = () => {
node.walk((child) => {
if (child.ledger.value("blocking") || child.ledger.value("errors")) {
scrollTo(child);
return false;
}
}, true);
};
if (node.props.type === "form") {
const onOldSubmitInvalid = node.props.onSubmitInvalid;
node.props.onSubmitInvalid = () => {
if (onOldSubmitInvalid) {
onOldSubmitInvalid(node);
}
scrollToErrors();
};
node.on("unsettled:errors", scrollToErrors);
}
return false;
}