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. 禁用状态的组件会被排除在约束验证之外,永远不会阻止表单提交。