From 9b8b4294e5ab96c90e46d3fb248696866e666bbf Mon Sep 17 00:00:00 2001 From: Takagi <1103069291@qq.com> Date: Thu, 3 Aug 2023 15:51:27 +0800 Subject: [PATCH] pref: scroll to the error location when form submission validation fails (#4358) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### 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 当表单填写错误时,将会自动滚动至错误项。 ``` --- console/src/formkit/formkit.config.ts | 2 ++ .../formkit/plugins/auto-scroll-to-errors.ts | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 console/src/formkit/plugins/auto-scroll-to-errors.ts diff --git a/console/src/formkit/formkit.config.ts b/console/src/formkit/formkit.config.ts index 78b90628b..76cfd06ee 100644 --- a/console/src/formkit/formkit.config.ts +++ b/console/src/formkit/formkit.config.ts @@ -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, diff --git a/console/src/formkit/plugins/auto-scroll-to-errors.ts b/console/src/formkit/plugins/auto-scroll-to-errors.ts new file mode 100644 index 000000000..78dee5e9f --- /dev/null +++ b/console/src/formkit/plugins/auto-scroll-to-errors.ts @@ -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; +}