9.1 KiB
9.1 KiB
Bricks.js 表单模块技术文档
本文档描述了
bricks框架中表单相关组件的实现逻辑、结构与使用方式。该模块提供了灵活的表单构建能力,支持动态字段渲染、数据校验、提交处理及工具栏集成。
目录
概述
本模块为 bricks.js 提供了一套完整的表单系统,包含以下功能:
- 动态生成表单字段(支持嵌套分组)
- 支持文件上传(需使用
FormData) - 自动化工具栏(提交、重置、取消按钮)
- 数据获取与验证
- 提交前后事件分发
- 多布局支持(水平/垂直输入框)
主要适用于 Web 端复杂表单场景,如配置页、编辑器、数据录入等。
核心变量
bricks.need_formdata_fields
bricks.need_formdata_fields = ['file', 'video', 'audio'];
说明:
指定哪些字段类型需要通过 FormData 提交(例如文件上传类字段)。这些字段将触发表单启用 multipart/form-data 编码模式。
核心方法
show_resp_message_or_error(resp)
bricks.show_resp_message_or_error = async function(resp){...}
参数:
resp:Response对象(来自fetch请求)
功能:
- 解析响应体为 JSON。
- 调用
widgetBuild将返回的 UI 描述渲染到页面主体中。
用途:
用于处理服务端返回的动态 UI 或错误信息并展示。
类说明
FieldGroup
负责根据字段定义递归构建表单控件。
构造函数
new FieldGroup(opts)
opts: 配置对象(目前未实际使用)
方法:build_fields(form, parent, fields)
| 参数 | 类型 | 说明 |
|---|---|---|
form |
Form 实例 | 当前所属表单对象 |
parent |
Widget | 容器组件(如 VBox/HBox) |
fields |
Array | 字段数组 |
行为说明:
- 使用
DynamicColumn实现响应式列布局(移动端默认两列)。 - 若遇到
uitype: 'group'的字段,则递归构建其内部字段,并插入新列。 - 非隐藏字段创建
VBox或HBox包裹标签和输入控件。 - 所有输入控件由
Input.factory(field)创建,并存入form.name_inputs。 - 若字段类型在
need_formdata_fields中,设置form.need_formdata = true。
FormBody
继承自 VScrollPanel,是表单内容区域的核心容器。
构造函数
new FormBody(form, opts)
初始化操作:
- 设置宽高为 100%
- 初始化
name_inputs映射 - 创建
FieldGroup渲染非文本字段 - 调用
build_text_fields()渲染文本字段
方法:build_text_fields()
遍历 form.textfields,对每个字段:
- 创建标签文字 (
Text) - 创建只读文本控件 (
UiText) - 包装成
VBox并添加至容器 - 注册到
form.name_inputs中以便后续取值
注意:
text类型字段不参与编辑,仅用于显示。
FormBase
表单基类,提供通用功能(继承自 Layout)。
属性
| 属性名 | 类型 | 说明 |
|---|---|---|
name_inputs |
Object | 存储字段名 → 控件实例映射 |
submit_changed |
Boolean | 是否仅提交变更字段 |
origin_data |
Object | 初始数据快照(用于比对变化) |
submit_url |
String | 提交地址 |
method |
String | HTTP 方法,默认 'POST' |
toolbar |
Object | 工具栏配置扩展 |
方法
build_toolbar(widget)
动态构建顶部工具栏(含“提交”、“重置”、“取消”按钮),支持自定义扩展。
- 默认图标路径由
bricks_resource()加载。 - 使用
IconTextBar组件呈现按钮条。 - 绑定
command事件到command_handle。
command_handle(event)
处理工具栏命令事件:
| 命令名 | 行为 |
|---|---|
submit |
触发 validation() |
reset |
调用 reset_data() |
cancel |
触发 dispatch('cancel') |
| 其他 | 若有 action 则执行事件处理器;否则直接 dispatch(name) |
reset_data()
重置所有输入控件为其初始值(调用各控件的 reset() 方法)。
_getValue()
收集所有字段值,进行必填校验:
- 忽略无权访问的属性(
hasOwnProperty) - 调用
getValue()获取控件值 - 必填项为空时弹出错误提示并聚焦
- 返回合并后的数据对象
⚠️ 若校验失败则中断并返回
undefined
getValue()
优先返回缓存的 this.data,否则调用 get_formdata()。
get_formdata()
构建 FormData 实例:
- 遍历所有控件,调用
set_formdata(data)写入数据 - 若启用了
submit_changed,跳过未修改字段 - 忽略值为
null的字段 - 返回
FormData或null(无变更)
validation()
异步提交流程控制:
- 显示加载动画(
Running组件) - 获取
FormData - 分发
submit事件 - 若设置了
submit_url,发起 HTTP 请求 - 成功后分发
submited事件,传入响应对象 - 出错时捕获异常并输出日志
- 隐藏加载动画
save_origin_data()
保存当前所有字段值作为原始状态,用于后续变更判断。
InlineForm
轻量级内联表单,适合嵌入其他组件内部。
特性:
- 不包含标题或描述
- 直接渲染字段 + 工具栏
- 自动保存初始数据
构造函数
new InlineForm(opts)
行为:
- 设置宽高 100%,开启滚动
- 调用
FieldGroup.build_fields()渲染opts.fields - 添加工具栏到第一个子容器
- 保存初始数据
Form
完整表单组件,具备标题、描述、分栏、工具栏等功能。
配置选项(opts)
| 参数 | 类型 | 说明 |
|---|---|---|
title |
String | 表单标题(可国际化) |
description |
String | 表单描述文本 |
notoolbar |
Boolean | 是否隐藏工具栏,默认 false |
input_layout |
String | 输入框布局 "VBox"(默认)或 "HBox" |
fields |
Array | 字段定义数组 |
submit_url |
String | 提交 URL |
method |
String | HTTP 方法(GET/POST) |
toolbar |
Object | 自定义工具栏配置 |
构造流程
- 设置尺寸与滚动
- 添加标题(若有)
- 添加描述(若有)
- 添加填充容器
Filler - 分离
text与其他字段 - 创建
FormBody渲染主体内容 - 条件性构建工具栏
- 保存初始数据
工厂注册
bricks.Factory.register('InlineForm', bricks.InlineForm);
bricks.Factory.register('Form', bricks.Form);
允许通过字符串名称动态创建组件实例,便于模板化渲染。
使用示例
定义一个简单表单
var form = new bricks.Form({
title: "User Profile",
description: "Please fill in your information.",
submit_url: "/api/user/update",
method: "POST",
input_layout: "VBox",
fields: [
{ name: "username", label: "Username", uitype: "text_input", required: true },
{ name: "email", label: "Email", uitype: "email", required: true },
{ name: "avatar", label: "Avatar", uitype: "file" },
{ name: "bio", label: "Bio", uitype: "textarea" },
{
uitype: "group",
fields: [
{ name: "phone", label: "Phone", uitype: "tel" },
{ name: "age", label: "Age", uitype: "number" }
]
}
]
});
// 监听提交事件
form.bind('submit', function(data){
console.log("Submitting:", data);
});
form.bind('submited', function(resp){
alert("Saved successfully!");
});
内联表单示例
var inline = new bricks.InlineForm({
fields: [
{ name: "name", label: "Name", uitype: "text_input" },
{ name: "status", label: "Status", uitype: "select", options: [...] }
],
toolbar: {
tools: [
{ icon: "...", name: "custom", label: "Custom Action", action: "doSomething" }
]
}
});
inline.bind('command:custom', function(){ ... });
附录:字段定义格式
[
{
"name": "field_name",
"label": "Display Label",
"uitype": "text_input|email|file|group|hide|...",
"required": true,
"value": "default_value",
"removable": false,
"icon": "optional_icon_path"
}
]
其中:
group: 可嵌套子字段text: 仅展示,不可编辑hide: 隐藏字段(但仍会渲染占位)
注意事项
- 文件上传字段必须使用
FormData,确保submit_url接口支持multipart/form-data。 - 所有文本标签建议启用
i18n: true实现多语言支持。 - 自定义控件需实现
getValue()和set_formdata(formData)接口。 - 错误提示依赖
bricks.Error组件,请确保已加载。
📚 更多组件参考请查阅 Bricks.js 官方文档。