sgds-forms

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SGDS Form Validation Pattern

SGDS 表单验证模式

SGDS form components integrate with the browser's ElementInternals API so they behave like native HTML form controls — they participate in
<form>
submission,
FormData
, and constraint validation automatically.
SGDS表单组件与浏览器的ElementInternals API集成,因此它们的行为与原生HTML表单控件一致——会自动参与
<form>
提交、
FormData
处理和约束验证。

Prerequisites

前置要求

See sgds-components for installation and framework integration.
All form components must be placed inside a
<form>
element and given a
name
attribute to participate in form submission.
安装和框架集成请参考**sgds-components**。
所有表单组件必须放置在
<form>
元素内部,并设置
name
属性,才能参与表单提交。

Quick Decision Guide

快速决策指南

Show native HTML validation messages? → Add
hasFeedback
to each form component
Prevent submit when fields are invalid? → Built-in — no extra code needed
Read submitted field values? → Use
new FormData(event.target)
in the submit handler
Disable SGDS validation per component?
noValidate
prop on
<sgds-input>
or
<sgds-textarea>
(others WIP)
Disable SGDS validation for the whole form?
novalidate
on the
<form>
element
Run 3rd-party validation (e.g. Zod)? → Disable SGDS validation first, then call
setInvalid(bool)
and set
invalidFeedback
programmatically
是否显示原生HTML验证消息? → 为每个表单组件添加
hasFeedback
字段无效时阻止提交? → 内置功能——无需额外代码
读取提交的字段值? → 在提交处理函数中使用
new FormData(event.target)
按组件禁用SGDS验证? → 在
<sgds-input>
<sgds-textarea>
上添加
noValidate
属性(其他组件开发中)
为整个表单禁用SGDS验证? → 在
<form>
元素上添加
novalidate
属性
使用第三方验证(如Zod)? → 先禁用SGDS验证,再通过编程方式调用
setInvalid(bool)
并设置
invalidFeedback

How Validation Is Triggered

验证触发时机

SGDS validation is layered:
  1. onChange (after blur) — validates when the user leaves a field; shows feedback if
    hasFeedback
    is set
  2. onSubmit — final validation pass fires before submission; blocks the form if any field is invalid
  3. onReset — clears all validity states and field values when the form is reset
Disabled components skip validation entirely.
SGDS验证分为多层:
  1. onChange(失去焦点后) —— 用户离开字段时触发验证;若设置了
    hasFeedback
    则显示反馈
  2. onSubmit —— 提交前执行最终验证;若存在无效字段则阻止表单提交
  3. onReset —— 表单重置时清除所有有效性状态和字段值
禁用状态的组件会完全跳过验证。

hintText
and Error Message Placement

hintText
与错误消息的位置

On most form components (
<sgds-input>
,
<sgds-textarea>
,
<sgds-select>
,
<sgds-combo-box>
,
<sgds-quantity-toggle>
,
<sgds-file-upload>
),
hintText
and the error message share the same space below the input container:
  • When the field is invalid (and
    hasFeedback
    is set), the error message replaces
    hintText
    .
  • When the error is resolved,
    hintText
    reappears.
<sgds-checkbox-group>
and
<sgds-radio-group>
behave differently —
hintText
is rendered in the label row above the options and remains visible at all times. The error message appears separately below the options.
在大多数表单组件(
<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
会渲染在选项上方的标签行中,且始终可见。错误消息会单独显示在选项下方。

Activating Feedback Display

激活反馈显示

Constraint validation runs regardless of
hasFeedback
, but the visible error message only renders when
hasFeedback
is present
. The
hasFeedback
prop accepts:
ValueBehaviour
hasFeedback
(boolean)
Shows the native HTML validation message as error text
hasFeedback="text"
Same as boolean — shows text feedback only
hasFeedback="style"
Shows invalid border/colour styling only, no text
hasFeedback="both"
Shows both invalid styling and text feedback
You can also override the displayed message with
invalidFeedback
:
html
<sgds-input
  name="email"
  label="Email"
  type="email"
  required
  hasFeedback="both"
  invalidFeedback="Please enter a valid email address"
></sgds-input>
无论是否设置
hasFeedback
,约束验证都会运行,但只有当
hasFeedback
存在时,才会渲染可见的错误消息
hasFeedback
属性支持以下取值:
取值行为
hasFeedback
(布尔值)
将原生HTML验证消息作为错误文本显示
hasFeedback="text"
与布尔值效果相同——仅显示文本反馈
hasFeedback="style"
仅显示无效边框/颜色样式,不显示文本
hasFeedback="both"
同时显示无效样式和文本反馈
你也可以通过
invalidFeedback
覆盖显示的消息:
html
<sgds-input
  name="email"
  label="Email"
  type="email"
  required
  hasFeedback="both"
  invalidFeedback="Please enter a valid email address"
></sgds-input>

Constraint Validations by Component

各组件支持的约束验证

ComponentSupported constraints
<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>
(standalone)
required
<sgds-file-upload>
required
(file size limit WIP)
组件支持的约束规则
<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
(文件大小限制开发中)

Full Form Example

完整表单示例

html
<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>
html
<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>

Reading Form Values via FormData

通过FormData读取表单值

Use the native
FormData
API in the submit handler. Access
sgds-file-upload
files separately via the component's
selectedFiles
property:
html
<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>
在提交处理函数中使用原生
FormData
API。需通过
<sgds-file-upload>
组件的
selectedFiles
属性单独访问上传的文件:
html
<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");

    // 文件上传的文件不会自动加入FormData
    const fileUpload = document.querySelector("sgds-file-upload");
    for (let i = 0; i < fileUpload.selectedFiles.length; i++) {
      formData.append("file" + i, fileUpload.selectedFiles[i]);
    }

    // 将formData提交至服务器
  });
</script>

Custom Validation (Disabling SGDS Validation)

自定义验证(禁用SGDS验证)

For 3rd-party validation libraries (e.g. Zod) or fully custom logic, disable SGDS's built-in validation first, then call
setInvalid(bool)
and update
invalidFeedback
in response to input events.
对于第三方验证库(如Zod)或完全自定义的逻辑,需先禁用SGDS的内置验证,再响应输入事件调用
setInvalid(bool)
并更新
invalidFeedback

Option 1 — Disable per component with
noValidate

选项1 —— 按组件使用
noValidate
禁用

Currently supported on
<sgds-input>
and
<sgds-textarea>
only. Other components are WIP.
html
<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>
目前仅支持**
<sgds-input>
<sgds-textarea>
**。其他组件开发中。
html
<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>

Option 2 — Disable at form level with
novalidate

选项2 —— 在表单层级使用
novalidate
禁用

Adding
novalidate
to the
<form>
element disables constraint validation and SGDS validation for all child components. Then apply
setInvalid
logic per field.
html
<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>
<form>
元素上添加
novalidate
会禁用约束验证和SGDS验证,对所有子组件生效。然后为每个字段应用
setInvalid
逻辑。
html
<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)
Method

setInvalid(bool)
方法

ParameterTypeDescription
bool
boolean
true
marks the component invalid and shows
invalidFeedback
;
false
clears the invalid state
Pair
setInvalid(true)
with setting the
invalidFeedback
property on the element to control the displayed message.
参数类型描述
bool
boolean
true
会标记组件为无效并显示
invalidFeedback
false
会清除无效状态
setInvalid(true)
与设置元素的
invalidFeedback
属性配合使用,可控制显示的消息。

Custom Validation Support Status

自定义验证支持状态

ComponentStatus
<sgds-input>
✅ Implemented
<sgds-textarea>
✅ Implemented
<sgds-checkbox>
/
<sgds-checkbox-group>
WIP
<sgds-datepicker>
WIP
<sgds-quantity-toggle>
WIP
<sgds-radio-group>
WIP
<sgds-file-upload>
WIP
<sgds-select>
WIP
<sgds-combo-box>
WIP

组件状态
<sgds-input>
✅ 已实现
<sgds-textarea>
✅ 已实现
<sgds-checkbox>
/
<sgds-checkbox-group>
开发中
<sgds-datepicker>
开发中
<sgds-quantity-toggle>
开发中
<sgds-radio-group>
开发中
<sgds-file-upload>
开发中
<sgds-select>
开发中
<sgds-combo-box>
开发中

For AI agents

给AI Agent的提示

  1. Always place SGDS form components inside a
    <form>
    element with
    name
    attributes for them to participate in form submission and
    FormData
    .
  2. hasFeedback
    must be present on a form component for the error message to visually appear — constraint validation alone does not show UI feedback.
  3. To show both the invalid border style and the error message text, use
    hasFeedback="both"
    . A plain boolean
    hasFeedback
    shows the message text only.
  4. Use
    invalidFeedback
    to override the browser's native constraint validation message with a custom string.
  5. Constraint validation and form submission blocking are built-in — do not add extra submit event listeners to replicate this behaviour.
  6. Use
    new FormData(event.target)
    in the submit handler to read values. For file uploads, read
    selectedFiles
    directly from the
    <sgds-file-upload>
    element.
  7. When using custom/3rd-party validation on
    <sgds-input>
    or
    <sgds-textarea>
    , add
    noValidate
    on the component (or
    novalidate
    on the form), then call
    element.setInvalid(true/false)
    and set
    element.invalidFeedback
    inside the
    sgds-input
    event listener.
  8. Only
    <sgds-input>
    and
    <sgds-textarea>
    fully support custom validation via
    noValidate
    +
    setInvalid
    . All other form components have this feature as WIP.
  9. The reset button (
    type="reset"
    ) automatically clears all validity states and values — no extra reset logic is needed.
  10. Disabled components are excluded from constraint validation and will never block form submission.
  1. 务必将SGDS表单组件放置在带有
    name
    属性的
    <form>
    元素内部,这样它们才能参与表单提交和
    FormData
    处理。
  2. 表单组件必须设置
    hasFeedback
    才会可视化显示错误消息——仅约束验证不会显示UI反馈。
  3. 若要同时显示无效边框样式和错误消息文本,请使用
    hasFeedback="both"
    。纯布尔值
    hasFeedback
    仅显示消息文本。
  4. 使用
    invalidFeedback
    可将浏览器原生约束验证消息替换为自定义字符串。
  5. 约束验证和表单提交阻止是内置功能——无需添加额外的提交事件监听器来复现此行为。
  6. 在提交处理函数中使用
    new FormData(event.target)
    读取值。对于文件上传,直接从
    <sgds-file-upload>
    元素读取
    selectedFiles
  7. <sgds-input>
    <sgds-textarea>
    上使用自定义/第三方验证时,需在组件上添加
    noValidate
    (或在表单上添加
    novalidate
    ),然后在
    sgds-input
    事件监听器中调用
    element.setInvalid(true/false)
    并设置
    element.invalidFeedback
  8. 只有
    <sgds-input>
    <sgds-textarea>
    完全支持通过
    noValidate
    +
    setInvalid
    实现自定义验证。所有其他表单组件的此功能仍在开发中。
  9. 重置按钮(
    type="reset"
    )会自动清除所有有效性状态和值——无需额外的重置逻辑。
  10. 禁用状态的组件会被排除在约束验证之外,永远不会阻止表单提交。