关于 sgds-forms
sgds-forms 介绍 SGDS 表单组件的验证模式,这些组件可融入浏览器原生表单行为。它帮助开发者处理内置约束、错误反馈、提交数据和自定义验证逻辑。
主要功能
- 01原生表单提交与 FormData
- 02内置约束验证
- 03可配置的验证反馈
- 04按组件或整个表单控制验证
- 05使用 setInvalid 自定义验证
适用场景
- 01字段无效时阻止表单提交
- 02显示浏览器或自定义验证消息
- 03将 SGDS 字段接入第三方验证
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ govtechsg/ sgds-web-component --skill sgds-forms安装后在 Claude Code 中输入/sgds-forms确认已加载。
详细介绍
SGDS 表单验证模式
SGDS 表单组件集成了浏览器的 ElementInternals API,因此其行为与原生 HTML 表单控件一致——它们会自动参与 <form> 提交、FormData 和约束验证。
前提条件
安装和框架集成说明请参阅 sgds-components。
所有表单组件都必须放在 <form> 元素内,并设置 name 属性,才能参与表单提交。
快速决策指南
显示原生 HTML 验证消息? → 为每个表单组件添加 hasFeedback
字段无效时阻止提交? → 内置功能,无需额外代码
读取已提交的字段值? → 在提交处理程序中使用 new FormData(event.target)
针对单个组件禁用 SGDS 验证? → 在 <sgds-input>、<sgds-textarea>、<sgds-combo-box>、<sgds-select>、<sgds-datepicker>、<sgds-quantity-toggle> 或 <sgds-file-upload> 上使用 noValidate 属性
针对整个表单禁用 SGDS 验证? → 在 <form> 元素上设置 novalidate
运行第三方验证(例如 Zod)? → 先禁用 SGDS 验证,然后调用 setInvalid(bool) 并以编程方式设置 invalidFeedback
验证触发方式
SGDS 验证分为多个阶段:
- onChange(失去焦点后) — 用户离开字段时进行验证;如果设置了
hasFeedback,则显示反馈 - onSubmit — 提交前进行最终验证;如果任何字段无效,则阻止表单提交
- onReset — 重置表单时清除所有有效性状态和字段值
禁用的组件会完全跳过验证。
hintText 和错误消息的位置
对于大多数表单组件(<sgds-input>、<sgds-textarea>、<sgds-select>、<sgds-combo-box>、<sgds-quantity-toggle>、<sgds-file-upload>),hintText 和错误消息会共用输入容器下方的同一空间:
- 字段无效时(且设置了
hasFeedback),错误消息会替代hintText。 - 错误已解决时,
hintText会重新显示。
<sgds-checkbox-group> 和 <sgds-radio-group> 的行为不同——hintText 会显示在选项上方的标签行中,并始终保持可见。错误消息则会单独显示在选项下方。
启用反馈显示
无论是否设置 hasFeedback,都会运行约束验证,但只有存在 hasFeedback 时才会显示错误消息。hasFeedback 属性接受以下值:
| 值 | 行为 |
|---|---|
hasFeedback(布尔值) | 将原生 HTML 验证消息显示为错误文本 |
hasFeedback="text" | 与布尔值相同——仅显示文本反馈 |
hasFeedback="style" | 仅显示无效状态的边框/颜色样式,不显示文本 |
hasFeedback="both" | 同时显示无效状态样式和文本反馈 |
你也可以使用 invalidFeedback 覆盖显示的消息:
<sgds-input
name="email"
label="Email"
type="email"
required
hasFeedback="both"
invalidFeedback="Please enter a valid email address"
></sgds-input>
各组件支持的约束
| 组件 | 支持的约束 |
|---|---|
<sgds-input> | required、pattern、min、max、minlength、maxlength |
<sgds-textarea> | required、minlength、maxlength |
<sgds-quantity-toggle> | min、max |
<sgds-datepicker> | required、minDate、maxDate |
<sgds-select> | required |
<sgds-combo-box> | required |
<sgds-radio-group> | required |
<sgds-checkbox-group> | required |
<sgds-checkbox>(独立使用) | required |
<sgds-file-upload> | required(文件大小限制尚在开发中) |
完整表单示例
<form id="my-form" class="d-flex-column">
<sgds-input
label="First Name"
name="firstName"
required
hasFeedback="both"
pattern="[A-Za-z ]+"
invalidFeedback="Letters only"
></sgds-input>
<sgds-datepicker label="Appointment Date" name="appointmentDate" required hasFeedback></sgds-datepicker>
<sgds-radio-group label="Gender" name="gender" required hasFeedback>
<sgds-radio value="female">Female</sgds-radio>
<sgds-radio value="male">Male</sgds-radio>
</sgds-radio-group>
<sgds-checkbox-group label="Food Preference" name="food" required hasFeedback hintText="Select at least one option">
<sgds-checkbox value="vegetarian">Vegetarian</sgds-checkbox>
<sgds-checkbox value="halal">Halal</sgds-checkbox>
</sgds-checkbox-group>
<sgds-textarea label="Comments" name="comments" required minlength="3" hasFeedback></sgds-textarea>
<sgds-button type="submit">Submit</sgds-button>
<sgds-button type="reset" variant="ghost">Reset</sgds-button>
</form>
通过 FormData 读取表单值
在提交处理函数中使用原生 FormData API。通过组件的 selectedFiles 属性单独访问 sgds-file-upload 文件:
<script>
const form = document.getElementById("my-form");
form.addEventListener("submit", event => {
event.preventDefault();
const formData = new FormData(event.target);
const firstName = formData.get("firstName");
const gender = formData.get("gender");
const comments = formData.get("comments");
// File upload files are not in FormData automatically
const fileUpload = document.querySelector("sgds-file-upload");
for (let i = 0; i < fileUpload.selectedFiles.length; i++) {
formData.append("file" + i, fileUpload.selectedFiles[i]);
}
// Submit formData to server
});
</script>
自定义验证(禁用 SGDS 验证)
对于第三方验证库(例如 Zod)或完全自定义的逻辑,请先禁用 SGDS 内置验证,然后调用 setInvalid(bool),并在输入事件发生时更新 invalidFeedback。
选项 1 — 使用 noValidate 禁用单个组件的验证
目前支持 <sgds-input>、<sgds-textarea>、<sgds-combo-box>、<sgds-datepicker>、<sgds-file-upload>、<sgds-select>、<sgds-quantity-toggle>、<sgds-radio-group>、<sgds-checkbox> 和 <sgds-checkbox-group>。
<sgds-input
noValidate
id="keys-input"
name="keys"
label="Keys"
hintText="Cannot start with special characters"
hasFeedback="both"
></sgds-input>
<script>
const input = document.getElementById("keys-input");
input.addEventListener("sgds-input", e => {
if (/^[^a-zA-Z0-9]/.test(e.target.value)) {
e.target.setInvalid(true);
e.target.invalidFeedback = "Keys cannot start with special characters";
} else {
e.target.setInvalid(false);
}
});
</script>
选项 2 — 使用 novalidate 在表单级别禁用验证
向 <form> 元素添加 novalidate,即可为所有子组件禁用约束验证和 SGDS 验证。然后为每个字段应用 setInvalid 逻辑。
<form id="custom-form" novalidate class="d-flex-column">
<sgds-input id="keys-input" name="keys" label="Keys" hasFeedback="both"></sgds-input>
<sgds-textarea id="bio-textarea" name="bio" label="Bio" hasFeedback></sgds-textarea>
</form>
<script>
document.getElementById("keys-input").addEventListener("sgds-input", e => {
if (/^[^a-zA-Z0-9]/.test(e.target.value)) {
e.target.setInvalid(true);
e.target.invalidFeedback = "Invalid key format";
} else {
e.target.setInvalid(false);
}
});
document.getElementById("bio-textarea").addEventListener("sgds-input", e => {
if (e.target.value.length < 10) {
e.target.setInvalid(true);
e.target.invalidFeedback = "Bio must be at least 10 characters";
} else {
e.target.setInvalid(false);
}
});
</script>
setInvalid(bool) 方法
| 参数 | 类型 | 说明 |
|---|---|---|
bool | boolean | true 会将组件标记为无效并显示 invalidFeedback;false 会清除无效状态 |
将 setInvalid(true) 与设置元素的 invalidFeedback 属性配合使用,以控制显示的消息。
自定义验证支持状态
| 组件 | 状态 |
|---|---|
<sgds-input> | ✅ 已实现 |
<sgds-textarea> | ✅ 已实现 |
<sgds-datepicker> | ✅ 已实现 |
<sgds-checkbox> / <sgds-checkbox-group> | ✅ 已实现 |
<sgds-quantity-toggle> | ✅ 已实现 |
<sgds-radio-group> | ✅ 已实现 |
<sgds-file-upload> | ✅ 已实现 |
<sgds-select> | ✅ 已实现 |
<sgds-combo-box> | ✅ 已实现 |
面向 AI Agent
- 始终将 SGDS 表单组件放在
<form>元素内,并为其设置name属性,使其参与表单提交和FormData。 - 表单组件必须设置
hasFeedback,错误消息才会以可视方式显示——仅进行约束验证不会显示界面反馈。 - 如需同时显示无效状态的边框样式和错误消息文本,请使用
hasFeedback="both"。仅设置布尔属性hasFeedback时,只会显示消息文本。 - 使用
invalidFeedback可将浏览器原生的约束验证消息替换为自定义字符串。 - 约束验证和阻止表单提交的行为均为内置功能——请勿额外添加提交事件监听器来复现此行为。
- 在提交处理程序中使用
new FormData(event.target)读取值。上传文件时,直接从<sgds-file-upload>元素读取selectedFiles。 - 使用自定义验证或第三方验证时,请在组件上添加
noValidate(或在表单上添加novalidate),然后在相关事件监听器中调用element.setInvalid(true/false)并设置element.invalidFeedback(输入框/文本区域使用sgds-input,日期选择器使用sgds-change-date,选择器/组合框/单选组/复选框组/数量切换器使用sgds-change,文件上传使用sgds-add-files/sgds-remove-file)。 - 所有表单组件(
<sgds-input>、<sgds-textarea>、<sgds-datepicker>、<sgds-combo-box>、<sgds-select>、<sgds-quantity-toggle>、<sgds-radio-group>、<sgds-checkbox>、<sgds-checkbox-group>和<sgds-file-upload>)均通过noValidate+setInvalid完整支持自定义验证。 - 重置按钮(
type="reset")会自动清除所有有效性状态和值——无需额外编写重置逻辑。 - 禁用的组件不参与约束验证,也不会阻止表单提交。