Skip to main content

FormDialogBuilder

使用 API 自定义渲染一个表单,并以对话框的形式打开。

FormDialogBuilder​

FormDialogBuilder 是通过代码创建表单对话框的 API 对象,你可以通过 FormDialogBuilder 来组织表单项和布局,并且像开发一个表单一样,基于表单的相关事件编写个性化的逻辑。

类型名称参数类型返回类型说明
方法addFieldSet(options)AddFieldSetOptionsFieldSet在表单默认布局中添加一个字段集合,
一个字段集合会渲染成一个带有标题的区域。
方法addSubGrid(options)AddSubGridOptionsSubGrid在表单默认布局中添加一个明细表。
方法addSubTreeGrid(options)AddSubTreeGridOptionsSubTreeGrid在表单默认布局中添加一个子树表。
方法addSubGridView(options)AddSubGridViewOptionsSubGrid在表单默认布局中添加一个子表格视图。
方法addSubTreeGridView(options)AddSubTreeGridOptions & {refFieldName: string}SubTreeGrid在表单默认布局中添加一个子树表视图。
方法addTabs()voidTabs添加一个页签布局容器,
可以在页签布局下添加子页签。
方法addStackBlock(options)AddStackBlockOptionsStackBlock添加一个流式布局容器,支持灵活的布局方式。
方法open(options)OpenOptionsvoid初始化表单对话框

addFieldSet(options) 添加字段集合​

addFieldSet 用于添加一个基于流式布局实现的字段集合组件。组件由两部分组成:标题区 和 字段内容区。

标题区会在左侧显示标题文字。

字段内容区中,字段按照从左到右、从上到下的顺序依次排列。通过 fieldsPerLine 属性可以设置每一行显示的字段个数。

单据中常见的表头字段的区块就是 FieldSet。

options 参数​

名称类型说明必填默认值
titlestring区域标题。为空时不显示标题区""
fieldsPerLinenumber每行显示字段个数4

返回值​

FieldSet 字段集合

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加一个标题为 "基本信息" 的区域
const baseFieldSet = formDialogBuilder.addFieldSet({
title: '基本信息',
fieldsPerLine: 2
});

// 添加一个标题为"名称"的文本类型字段
baseFieldSet.addField({
id: "name",
title: "名称",
type: 'Text'
});

注意

如果不设置 title 属性或设置为空字符串 "",那么对应渲染的字段集合区域就不会显示标题区域。

addSubGrid(options) 添加明细表​

addSubGrid 用于添加一个以表格展示的明细表组件。组件由两部分构成:标题区 和 表格区。

标题区会在左侧显示标题文字。

表格区中,表头按照字段顺序从左到右依次构建。明细表中的每一行数据会作为表格中的一行记录进行展示。表头可以分成多级分组,数字列也可以在表格底部合计,见 SubGrid 明细表。

单据中常见的明细表就是 SubGrid。

options 参数​

名称类型说明必填默认值
idstring明细表字段名,对应表单数据上的 key☑️-
titlestring明细表标题。为空时不显示标题区☑️-
visibleboolean是否显示该明细表true
actionsSubGridActions行操作:复制、删除,以及自定义行按钮-
enableColumnFilterboolean是否开启列筛选false
suppressAutoHeightboolean是否关闭按行数自动撑高false
onRowSelectionChanged(data) => void选中行变化时触发-
styleReact.CSSProperties区域样式-

actions 参数​

名称类型说明默认值
disableboolean为 true 时不显示行操作false
includesstring[]启用的行操作。内置值为 copy、delete-
excludesstring[]禁用的行操作-
customActions{ key, title, icon?, onClick? }[]自定义行按钮-
resolveActions(actions: string[]) => string[]按当前行返回最终要显示的操作-

返回值​

SubGrid 明细表

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加一个标题为"人员明细"的明细表区域
const userGrid = formDialogBuilder.addSubGrid({
id: 'users',
title: "人员明细",
actions: {
includes: ['copy', 'delete']
}
});

// 在明细表中,添加一个标题为"人员"的外键字段,外键指向 User 表,并设置列宽为 200.
const user = userGrid.addField({
id: "user",
title: "人员",
type: "EntityRef",
source: 'User',
width: 200
});

// 在明细表中,添加一个标题为"天数"的数字字段,该字段会显示在"人员"右侧。
userGrid.addField({
id: "days",
title: "天数",
type: "Number",
width: 100
});
注意

明细表的数据 key 是 id,不是 fieldName。title 为空时不显示标题区。

addTabs(options) 添加页签容器​

addTabs 用于添加一个页签模式的容器组件。如果我们创建的表单中,信息可以以某种明确的维度进行分组。那么我们可以使用页签布局来显示的表达这个分组,提高用户的体验。

单纯添加页签容器是无法工作的,页签容器(Tabs)需要页签(Tab)一起配合,才能完成一个完整的页签定义。

返回值​

Tabs 页签容器

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加一个页签分组
const tabs = formDialogBuilder.addTabs();

// 在页签分组下添加一个标题为"销售属性"的页签
const salesTab = tabs.addFieldSetTab({
title: "销售属性"
});

// 在"销售属性"页签中,添加"售价"字段
salesTab.addField({
id: "price",
title: "售价",
type: "Amount"
});

// 在 "销售属性" 右侧,添加一个标题为"库存属性"的页签,这个页签里显示一个明细表
const inventoryGrid = tabs.addSubGridTab({
title: "库存属性",
id: "inventories"
});
注意
  1. 如果页签容器下没有通过 addFieldSetTab、addSubGridTab 等方法添加页签,那么最终这个页签容器不会进行渲染。
  2. 页签的 title 属性必填。明细表页签的数据 key 是 id。

open(options) 初始化表单对话框​

在完成表单数据和布局定义后,可以通过 open 打开表单对话框。这会同步创建一个全新的表单实例,该表单拥有独立的运行空间、独立的生命周期及相关表单上下文。如果要在这个表单上使用 Client API,则需要通过 options 来传递相关的表单事件监听处理函数。

options 参数​

名称类型说明
titleString对话框标题
sizeString对话框大小,可选值:small、middle、large、largest, 默认值:largest
valueObject表单初始值
formOnLoadFunction表单初始化后触发,详细介绍
fieldOnChangedFunction表单中任一字段值发生改变时被触发,详细介绍
subGridOnChangedFunction明细表数据发生变化时,对明细表的 添加、复制、删除 会触发,详细介绍
subGridRowOnCreatedFunction在明细行创建之后触发,详细介绍
subGridRowOnInitFunction在明细行初始化之后触发,详细介绍
dialogOnCancelFunction在用户点击 对话框右上角 或 底部取消按钮 时触发,详细介绍
dialogOnConfirmFunction在用户点击 底部确认按钮 时触发,详细介绍
extraButtonsFormDialogButton[]额外的按钮,添加在取消和确定中间
suppressCancelButtonBoolean隐藏取消按钮,默认为false
suppressConfirmButtonBoolean隐藏确认按钮,默认为false

FormDialogButton 类型​

名称类型说明必填默认值
idstring按钮的唯一标识符☑️-
textstring按钮显示的文本-
titlestring按钮的提示信息(tooltip)-
typestring按钮类型,可选值:flat、raised、outline、icon-
iconstring按钮图标-
iconSizenumber图标大小-
onClickFunction按钮点击事件的处理函数,接收 FormExecutionCtx 作为参数☑️-

FieldSet 字段集合​

FieldSet 是一个基于流式布局实现的字段集合,集合中的字段按照从左到右、从上到下的顺序依次排列。你可以通过 addField 给相应集合中添加字段。

类型名称参数类型返回类型/类型说明
方法addField(options)AddFieldOptionsField在字段集合中添加一个字段

addField(options) 添加字段​

在字段集合 FieldSet 中添加一个字段。添加的多个字段会按照 addField 的调用顺序决定 FieldSet 中的展示顺序。

options 参数​

名称类型说明必填默认值
idstring字段名称,对应数据 key☑️-
titlestring字段标题☑️-
typeFieldType字段类型☑️-
readonlyboolean | (row) => boolean是否只读。明细列可以传函数,按当前行动态判断false
hiddenboolean是否隐藏false
requiredboolean是否必填false
labelDescriptionstring标题旁的说明-
cascade{ valueExpr: string }只按表达式展示值,不创建真实字段,也不能作为提交字段-

各类型特定参数说明​

  • Text、MultiText、Link、Mobile、Email
名称类型说明必填默认值
formatTypestring文本格式化类型-
initOptions() => Promise<\{ options, labelKey?, valueKey?, onSearch? \}>把文本做成可搜索下拉。labelKey 默认 title,valueKey 默认 id-
  • Number、Amount
名称类型说明必填默认值
decimalnumber小数位精度2
  • Percent
名称类型说明必填默认值
decimalnumber小数位精度2
  • RadioGroup
名称类型说明必填默认值
options{ text: string, value: any }[]单选项☑️-
  • Select

选项直接写在 addField 上,不需要再调用 addSelectOption。

名称类型说明必填默认值
options{ text: string, value: any }[]下拉选项-
placeholderstring占位提示-
allowClearboolean是否允许清空-
  • RichText
名称类型说明必填默认值
fieldNames{ text: string, json: string, html: string }纯文本、JSON、HTML 三个值分别写入的字段名☑️-
  • EntityRef、EnumRef、MultiEntityRef、MultiEnumRef
名称类型说明必填默认值
sourcestring引用的档案或枚举名☑️-
  • ForeignKeyLink
名称类型说明必填默认值
entityNamestring链接指向的对象名-
drillingInfo{ valueField?, objectTypeField? }穿透时取值字段和对象类型字段-
originDefobject原始字段定义☑️-
  • Color
名称类型说明必填默认值
modelany颜色选择模式-
  • Attachment
名称类型说明必填默认值
disableUploadboolean是否禁用上传false
disableDeleteboolean是否禁用删除false
disableEditboolean是否禁用编辑false
enableIncrementalboolean是否启用增量处理false
compactboolean是否紧凑模式false
resourceIdstring资源ID-
attachmentPropsobject附件组件透传的额外Props-
  • Image
名称类型说明必填默认值
maxUploadCountnumber最大上传图片数量-
maxUploadSizenumber最大上传图片大小(单位:MB)-
disabledSetDefaultboolean是否禁用设置默认展示图片功能false
hideDefaultTagboolean是否隐藏默认图片标签false
RichText 富文本字段​

富文本字段在界面上渲染为一个富文本编辑器,支持段落、标题、加粗/斜体/下划线/删除线、文字颜色、链接、图片等内容。

一个富文本字段由 1 个富文本字段 和 3 个承载数据的字段 共同组成:

字段值类型说明
富文本字段(id)-用于渲染编辑器,本身不保存内容。
text 字段String富文本对应的纯文本,可用于列表展示、搜索、校验是否为空。
json 字段Object富文本内容(Tiptap JSON),是富文本内容的唯一事实来源。
html 字段Object由 json 派生的 HTML 存储值,结构为 { html, imageKeys, hasError, hasUploading }。

通过 fieldNames 告诉富文本字段这 3 个字段的字段名:

名称类型说明必填默认值
fieldNamesobject富文本数据字段映射☑️-
fieldNames.textstring纯文本字段名☑️-
fieldNames.jsonstring富文本 JSON 字段名☑️-
fieldNames.htmlstring富文本 HTML 字段名☑️-
注意
  1. fieldNames 中的 3 个字段不会自动创建,必须在同一个表单中通过 addField 显式添加,并设置 hidden: true 隐藏:text 字段类型为 Text,json 和 html 字段类型为 JsonObject。缺少这 3 个字段时,编辑器无法正常工作,field.richText 也会返回 undefined。
  2. fieldNames 中填写的是字段名本身(即对应字段的 id),不需要带任何路径前缀。
  3. 富文本字段目前只能添加在字段集合 FieldSet 中(包括页签、流式布局中的字段集合),不支持作为明细表、子树表的列。
  4. 富文本的内容请通过 field.richText 读写,不要直接给 json / html 字段赋值,否则 3 个字段的内容可能不一致。
// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

const baseFieldSet = formDialogBuilder.addFieldSet({
title: '工作汇报',
fieldsPerLine: 1
});

// 1. 添加富文本字段,用于渲染编辑器
baseFieldSet.addField({
id: 'content',
title: '汇报内容',
type: 'RichText',
required: true,
fieldNames: {
text: 'contentTextStr',
json: 'contentTextJson',
html: 'contentTextHtml',
},
});

// 2. 添加富文本的 3 个数据字段,并隐藏
baseFieldSet.addField({ id: 'contentTextStr', title: '汇报内容', type: 'Text', hidden: true });
baseFieldSet.addField({ id: 'contentTextJson', title: '汇报内容', type: 'JsonObject', hidden: true });
baseFieldSet.addField({ id: 'contentTextHtml', title: '汇报内容', type: 'JsonObject', hidden: true });

formDialogBuilder.open({
title: '填写工作汇报',
size: 'large',
// 表单加载后写入初始内容
formOnLoad: (ctx) => {
const richText = ctx.getFormContext().form.getField('contentTextStr').richText;
richText.set([
{ type: 'heading', level: 2, content: '本周工作' },
{ type: 'paragraph', content: '1. ' },
{ type: 'heading', level: 2, content: '下周计划' },
{ type: 'paragraph', content: '1. ' },
]);
},
// 提交时读取内容
dialogOnConfirm: async (ctx) => {
const form = ctx.getFormContext().form;
const snapshot = form.getField('contentTextStr').richText.get();
if (!snapshot.text.trim()) {
qiqi.ui.message.showError('请填写汇报内容');
ctx.getEventArgs().cancel();
return;
}
// snapshot.document 为富文本 JSON,snapshot.html.html 为 HTML 字符串
console.log(snapshot.text, snapshot.document, snapshot.html);
},
});

更多读写方式请参考 field.richText 富文本 API。

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加一个标题为 "基本信息" 的区域
const baseFieldSet = formDialogBuilder.addFieldSet({
title: '基本信息',
fieldsPerLine: 2
});

// 添加一个标题为"名称"的文本类型字段
baseFieldSet.addField({
id: "name",
title: "名称",
type: 'Text'
});

// 添加一个标题为"业务日期"的日期类型字段
baseFieldSet.addField({
id: "businessDate",
title: "业务日期",
type: "Date"
});

// 添加一个标题为"业务员"的外键类型字段,外键指向人员
const userField = baseFieldSet.addField({
id: "businessDate",
title: "业务员",
type: "EntityRef",
source: "User"
});

addSubTreeGrid(options) 添加子树表​

addSubTreeGrid 用于在表单默认布局中添加一个子树表,支持树形数据的展示和操作。

options 参数​

名称类型说明必填默认值
idstring子树表字段名☑️-
titlestring子树表显示名称☑️-
parentIdFieldNamestring父节点ID字段名☑️-
idFieldNamestring节点ID字段名☑️-
hasChildrenFieldNamestring是否包含子节点字段名☑️-
visibleboolean是否可见true
actionsSubGridActions行操作,含义与明细表相同-
enableColumnFilterboolean是否开启列筛选false
suppressAutoHeightboolean是否关闭按行数自动撑高false
onRowSelectionChanged(data) => void选中行变化时触发-
styleReact.CSSProperties样式配置-

返回值​

SubTreeGrid 子树表

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加子树表
const treeGrid = formDialogBuilder.addSubTreeGrid({
id: 'orgTree',
title: '组织架构',
parentIdFieldName: 'parentId',
idFieldName: 'id',
hasChildrenFieldName: 'hasChildren'
});

// 添加字段到子树表
treeGrid.addField({
id: 'name',
title: '名称',
type: 'Text',
width: 200
});

addSubGridView(options) 添加子表格视图​

addSubGridView 用于在表单默认布局中添加一个子表格视图,通常用于显示关联的实体数据。

options 参数​

AddSubGridViewOptions 继承自 AddSubGridOptions,并增加了以下额外属性:

名称类型说明必填默认值
refFieldNamestring关联字段名☑️-

返回值​

SubGrid 明细表

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加子表格视图
const subGridView = formDialogBuilder.addSubGridView({
id: 'orderItems',
title: '订单明细',
refFieldName: 'orderId'
});

// 添加字段到子表格视图
subGridView.addField({
id: 'productName',
title: '产品名称',
type: 'Text',
width: 160
});

addSubTreeGridView(options) 添加子树表视图​

addSubTreeGridView 用于在表单默认布局中添加一个子树表视图,通常用于显示关联的树形实体数据。

options 参数​

名称类型说明必填默认值
idstring子树表字段名☑️-
titlestring子树表显示名称☑️-
refFieldNamestring关联字段名☑️-
parentIdFieldNamestring父节点ID字段名☑️-
idFieldNamestring节点ID字段名☑️-
hasChildrenFieldNamestring是否包含子节点字段名☑️-
visibleboolean是否可见true
actionsSubGridActions行操作,含义与明细表相同-
enableColumnFilterboolean是否开启列筛选false
suppressAutoHeightboolean是否关闭按行数自动撑高false
onRowSelectionChanged(data) => void选中行变化时触发-
styleReact.CSSProperties样式配置-

返回值​

SubTreeGrid 子树表

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加子树表视图
const treeGridView = formDialogBuilder.addSubTreeGridView({
id: 'categoryTree',
title: '产品分类',
refFieldName: 'productId',
parentIdFieldName: 'parentId',
idFieldName: 'id',
hasChildrenFieldName: 'hasChildren'
});

// 在子树表视图中添加字段
treeGridView.addField({
id: 'categoryName',
title: '分类名称',
type: 'Text',
width: 150
});

addStackBlock(options) 添加流式布局容器​

addStackBlock 用于在表单默认布局中添加一个流式布局容器,支持水平和垂直方向的灵活布局。

options 参数​

名称类型说明必填默认值
direction'horizontal' | 'vertical'布局方向,水平或垂直'vertical'
spacingnumber子元素之间的间距-
styleReact.CSSProperties自定义样式-

返回值​

StackBlock 流式布局

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加水平流式布局
const horizontalStack = formDialogBuilder.addStackBlock({
direction: 'horizontal',
spacing: 16
});

// 在流式布局中添加字段集
const fieldSet1 = horizontalStack.addFieldSet({
title: '基本信息',
fieldsPerLine: 2
});

const fieldSet2 = horizontalStack.addFieldSet({
title: '扩展信息',
fieldsPerLine: 2
});

// 添加字段到字段集
fieldSet1.addField({
id: 'name',
title: '名称',
type: 'Text'
});

fieldSet2.addField({
id: 'description',
title: '描述',
type: 'TextArea'
});

Field 字段​

Field 是单个字段的API对象。你可以通过 Field 给字段设置相关选项及参数。

类型名称返回类型/类型说明
属性idstring(read-only)字段名,在调用 addField 时指定。在获取表单数据时,
该字段的值会以 id 作为父对象(表单或明细表行)的 key。
属性typestring(read-only)字段类型,在调用 addField 时指定。
不同字段类型的交互组件不同。具体可以参考 FieldType 类型集合

FieldType 字段类型​

类型值类型说明
TextString单行文本。
MultiTextString多行文本。
LinkString链接。
MobileString手机号。
EmailString邮箱。
NumberNumber数字。
AmountNumber金额。
PercentNumber百分比。
YearDate年。
YearMonthDate年-月。
DateMonthDate月。
DateDate年-月-日。
DateTimeDate年-月-日 时:分。
DateTimeSecondDate年-月-日 时:分:秒。
TimeDate时:分:秒。
CheckboxBoolean勾选框。
RadioGroupany单选按钮组,选项由 options 提供。
Selectany下拉选择,选项由 options 提供。
EntityRefObject档案、单据参照。
EnumRefObject枚举参照。
MultiEntityRefArray多选档案、单据参照。
MultiEnumRefArray多选枚举参照。
ForeignKeyLinkObject外键链接,可穿透到关联数据。
ImageObject图片上传。
AttachmentObject附件上传。
RichTextObject富文本,内容保存在 fieldNames 指定的 text / json / html 字段中,详细介绍。
JsonObjectObjectJSON 数据字段,只用来承载数据,需配合 hidden: true 使用,例如富文本的 json / html 数据字段。
ColorObject颜色选择。
GeolocationObject地理定位。

Tabs 页签容器​

Tabs 是页签容器的API对象。你可以通过 Tabs 添加页签Tab。Tabs的页签展示顺序保持和 addFieldSetTab 、addSubGridTab 的调用顺序一致。

类型名称参数类型返回类型/类型说明
方法addFieldSetTab(options)AddFieldSetTabOptionsFieldSet添加一个字段集合的子页签
方法addSubGridTab(options)AddSubGridOptionsSubGrid添加一个明细表的子页签
方法addSubGridViewTab(options)AddSubGridViewOptionsSubGrid添加一个子表格视图页签
方法addSubTreeGridTab(options)AddSubTreeGridOptionsSubTreeGrid添加一个子树表的子页签
方法addSubTreeGridViewTab(options)AddSubTreeGridOptions & {refFieldName: string}SubTreeGrid添加一个子树表视图的子页签
注意

如果页签容器下没有通过 addFieldSetTab 或 addSubGridTab 来添加页签,那么最终这个页签容器不会进行渲染。

addFieldSetTab(options) 添加字段集合页签​

addFieldSetTab 用于在页签容器中添加一个字段集合页签。

options 参数​

名称类型说明必填默认值
titlestring字段标题☑️""
fieldsPerLinenumber每行显示字段个数4
注意

addFieldSetTab 中,title 属性必填。

返回值​

FieldSet 字段集合

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加一个页签分组
const tabs = formDialogBuilder.addTabs();

// 在页签分组下添加一个标题为"销售属性"的页签
const salesTab = tabs.addFieldSetTab({
title: "销售属性"
});

// 在"销售属性"页签中,添加"售价"字段
salesTab.addField({
id: "price",
title: "售价",
type: "Amount"
});

addSubGridTab(options) 添加明细表页签​

addSubGridTab 用于在页签容器中添加一个明细表页签。

options 参数​

参数与 AddSubGridOptions 相同。id、title 必填。

注意

addSubGridTab 中,title 和 id 必填。数据 key 是 id。

返回值​

SubGrid 明细表

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加一个页签分组
const tabs = formDialogBuilder.addTabs();

// 在 "销售属性" 右侧,添加一个标题为"库存属性"的页签,这个页签里显示一个明细表
const inventoryGrid = tabs.addSubGridTab({
title: "库存属性",
id: "inventories"
});

// 库存属性明细表中,添加一个标题为"存货"的列
inventoryGrid.addField({
id: 'product',
title: '存货',
type: 'EntityRef',
source: 'Product',
width: 160
})

addSubGridViewTab(options) 添加子表格视图页签​

addSubGridViewTab 用于在页签中添加一个子表格视图。参数与 AddSubGridViewOptions 相同:在明细表参数之外,必须再传 refFieldName,表格展示的是该字段上的数据。

语法​

const tabs = formDialogBuilder.addTabs();

const orderTab = tabs.addSubGridViewTab({
id: 'orderItems',
title: '订单明细',
refFieldName: 'orderId'
});

orderTab.addField({
id: 'productName',
title: '产品名称',
type: 'Text',
width: 160
});

addSubTreeGridTab(options) 添加子树表页签​

addSubTreeGridTab 用于在页签容器中添加一个子树表页签。

options 参数​

名称类型说明必填默认值
idstring子树表字段名☑️-
titlestring子树表显示名称☑️-
parentIdFieldNamestring父节点ID字段名☑️-
idFieldNamestring节点ID字段名☑️-
hasChildrenFieldNamestring是否包含子节点字段名☑️-
visibleboolean是否可见true
actionsSubGridActions行操作,含义与明细表相同-
enableColumnFilterboolean是否开启列筛选false
suppressAutoHeightboolean是否关闭按行数自动撑高false
onRowSelectionChanged(data) => void选中行变化时触发-
styleReact.CSSProperties样式配置-
注意

addSubTreeGridTab 中,title 属性必填。

返回值​

SubTreeGrid 子树表

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加一个页签分组
const tabs = formDialogBuilder.addTabs();

// 添加一个组织架构的子树表页签
const orgTreeTab = tabs.addSubTreeGridTab({
title: "组织架构",
id: "orgTree",
parentIdFieldName: "parentId",
idFieldName: "id",
hasChildrenFieldName: "hasChildren"
});

// 在子树表中添加字段
orgTreeTab.addField({
id: 'name',
title: '名称',
type: 'Text',
width: 200
});

addSubTreeGridViewTab(options) 添加子树表视图页签​

addSubTreeGridViewTab 用于在页签容器中添加一个子树表视图页签,通常用于显示关联的实体数据。

options 参数​

名称类型说明必填默认值
idstring子树表字段名☑️-
titlestring子树表显示名称☑️-
refFieldNamestring关联字段名☑️-
parentIdFieldNamestring父节点ID字段名☑️-
idFieldNamestring节点ID字段名☑️-
hasChildrenFieldNamestring是否包含子节点字段名☑️-
visibleboolean是否可见true
actionsSubGridActions行操作,含义与明细表相同-
enableColumnFilterboolean是否开启列筛选false
suppressAutoHeightboolean是否关闭按行数自动撑高false
onRowSelectionChanged(data) => void选中行变化时触发-
styleReact.CSSProperties样式配置-
注意

addSubTreeGridViewTab 中,title 属性必填。

返回值​

SubTreeGrid 子树表

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加一个页签分组
const tabs = formDialogBuilder.addTabs();

// 添加一个关联实体的子树表视图页签
const categoryTreeTab = tabs.addSubTreeGridViewTab({
title: "产品分类",
id: "categoryTree",
refFieldName: "productId",
parentIdFieldName: "parentId",
idFieldName: "id",
hasChildrenFieldName: "hasChildren"
});

// 在子树表视图中添加字段
categoryTreeTab.addField({
id: 'categoryName',
title: '分类名称',
type: 'Text',
width: 150
});

StackBlock 流式布局​

StackBlock 是流式布局容器的API对象,提供灵活的布局方式。你可以通过 StackBlock 添加字段集、明细表、页签等组件,支持水平或垂直方向的布局。

类型名称参数类型返回类型/类型说明
方法addFieldSet(options)AddFieldSetOptionsFieldSet添加一个字段集合
方法addSubGrid(options)AddSubGridOptionsSubGrid添加一个明细表
方法addSubTreeGrid(options)AddSubTreeGridOptionsSubTreeGrid添加一个子树表
方法addSubGridView(options)AddSubGridViewOptionsSubGrid添加一个子表格视图
方法addSubTreeGridView(options)AddSubTreeGridOptions & {refFieldName: string}SubTreeGrid添加一个子树表视图
方法addTabs(options)AddTabsOptionsTabs添加一个页签容器
方法addStackItem(options){style?: React.CSSProperties}StackBlock添加一个子流式布局区域
方法addStackBlock(options)AddStackBlockOptionsStackBlock添加一个嵌套的流式布局区域

AddStackBlockOptions 流式布局配置选项​

名称类型说明必填默认值
direction'horizontal' | 'vertical'布局方向,水平或垂直'vertical'
spacingnumber子元素之间的间距-
styleReact.CSSProperties自定义样式-

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加一个水平流式布局
const stackBlock = formDialogBuilder.addStackBlock({
direction: 'horizontal',
spacing: 16
});

// 在流式布局中添加字段集
const fieldSet = stackBlock.addFieldSet({
title: '基本信息',
fieldsPerLine: 2
});

// 添加字段到字段集
fieldSet.addField({
id: 'name',
title: '名称',
type: 'Text'
});

// 添加另一个流式布局作为子项
const subStack = stackBlock.addStackItem({
style: { padding: 16 }
});

SubTreeGrid 子树表​

SubTreeGrid 是子树表的API对象,支持树形数据的展示和操作。子树表以树形表格形式展示,支持树形数据的展开和折叠。

类型名称参数类型返回类型/类型说明
方法addParentLayout(options)AddParentLayoutOptionsColumnLayout添加列分组,用于多级表头
方法addField(options)AddSubgridFieldOptionsField在子树表中添加一个字段
方法removeParentLayout(layoutId)stringboolean删除列分组,并删除其下的子分组和字段
方法removeField(fieldId)stringboolean删除末级字段
方法changeRowSelection(mode)'single' | 'multiple' | 'none'void修改行选择模式
方法getToolBar()voidIDetailToolBar获取工具栏对象
方法rebuildColumns()voidvoid改列后刷新列头,并同步行数据

列的添加、删除、多级表头和底部合计与 SubGrid 明细表 使用同一套接口。树形明细开启合计后,只按末级行计算:有子节点的父行不计入;hasChildren 为 true 时,即使子节点还没加载,也不当作末级。展开或折叠不改变合计结果,合计按全部末级数据计算。

AddSubTreeGridOptions 子树表配置选项​

名称类型说明必填默认值
idstring子树表字段名☑️-
titlestring子树表显示名称☑️-
parentIdFieldNamestring父节点ID字段名☑️-
idFieldNamestring节点ID字段名☑️-
hasChildrenFieldNamestring是否包含子节点字段名☑️-
visibleboolean是否可见true
actionsSubGridActions行操作,含义与明细表相同-
enableColumnFilterboolean是否开启列筛选false
suppressAutoHeightboolean是否关闭按行数自动撑高false
onRowSelectionChanged(data) => void选中行变化时触发-
styleReact.CSSProperties样式配置-

语法​

// 创建 builder
const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

// 添加子树表
const treeGrid = formDialogBuilder.addSubTreeGrid({
id: 'orgTree',
title: '组织架构',
parentIdFieldName: 'parentId',
idFieldName: 'id',
hasChildrenFieldName: 'hasChildren'
});

// 添加字段到子树表
treeGrid.addField({
id: 'name',
title: '名称',
type: 'Text',
width: 200
});

// 获取工具栏并添加按钮
const toolBar = treeGrid.getToolBar();
toolBar.addButton({
id: 'expandAll',
text: '展开全部',
onClick: () => {
console.log('展开全部');
}
});

IDetailToolBar 明细工具栏​

IDetailToolBar 是明细表和子树表右上角工具栏。按钮配置与 FormDialogButton 相同:id、text、title、type、icon、iconSize、onClick。工具栏按钮没有 style、className。

类型名称参数类型返回类型说明
方法addButton(...buttons)FormDialogButtonvoid添加一个或多个按钮。id 已存在时不会重复添加
方法removeButton(id)stringvoid按按钮 id 删除
方法getButtons()voidFormDialogButton[]返回当前按钮
方法addSearchInput(options)SearchInputOptionsvoid添加搜索框
方法addSearchArea(options)SearchAreaOptionsvoid添加搜索区域

SearchInputOptions​

名称类型说明必填
idstring搜索框标识☑️
placeholderstring占位提示
onChange(value: string) => void输入变化时触发
styleReact.CSSProperties样式

SearchAreaOptions​

名称类型说明必填
idstring搜索区域标识☑️
styleReact.CSSProperties样式

语法​

const toolBar = subGrid.getToolBar();

toolBar.addButton({
id: 'customAction',
text: '自定义操作',
icon: 'edit',
onClick: (formExecutionContext) => {
const form = formExecutionContext.getFormContext().form;
console.log(form.value);
}
});

toolBar.addSearchInput({
id: 'keyword',
placeholder: '搜索',
onChange: (value) => {
console.log(value);
}
});

toolBar.removeButton('customAction');

SubGrid 明细表​

SubGrid 是明细表的 API 对象。你可以通过 SubGrid 给明细表定义列、多级表头和底部合计。SubTreeGrid 使用同一套列接口。

类型名称参数类型返回类型/类型说明
方法addParentLayout(options)AddParentLayoutOptionsColumnLayout添加列分组,只负责表头展示,不绑定数据
方法addField(options)AddSubgridFieldOptionsField添加末级字段列
方法removeParentLayout(layoutId)stringboolean删除列分组,并删除其下的子分组和字段
方法removeField(fieldId)stringboolean删除末级字段
方法changeRowSelection(mode)'single' \| 'multiple' \| 'none'void修改行选择模式
方法getToolBar()voidIDetailToolBar获取工具栏对象
方法rebuildColumns()voidvoid改列后刷新列头,并同步子表 schema 与已有行数据
注意

如果 SubGrid 没有通过 addField 添加过字段,那么最终该明细表不会渲染,并且在表单中,也不会创建该明细表的数据模型对象。

表单已经打开之后再增删列,必须调用 rebuildColumns()。只在建表阶段把列搭好、打开后不再改列,则不必调用。

addField(options) 添加字段​

在明细表中添加一个末级字段列。同级的 addField 和 addParentLayout 按调用顺序从左到右排列。

options 参数​

明细列在 公共字段属性 之外,还支持下面这些参数。readonly 在明细列上可以传 (row) => boolean。

名称类型说明必填默认值
widthnumber列宽☑️-
parentIdstring归属列分组 id。不设则为顶层列-
suppressFilterboolean禁用该列筛选false
enableBatchEditboolean | { checkAlso, lockedBy, rowFilter }表头批量勾选编辑。对象形式可配置连带勾选、锁定和参与批量赋值的行false
enableSummaryboolean是否在表格底部显示该列合计false
summaryType'Sum' \| 'Max' \| 'Min' \| 'Avg' \| 'Count'合计方式。开启合计后未指定时按 SumSum

enableBatchEdit 传对象时:

名称类型说明
checkAlsostring[]勾选本列时连带勾选的字段
lockedBystring[]这些字段为 true 时,本列不可取消勾选
rowFilter(row) => boolean参与全选和批量赋值的行。未设置时包含全部行

返回值​

Field 字段

语法​

const formDialogBuilder = qiqi.builder.createDialogFormBuilder();

const userGrid = formDialogBuilder.addSubGrid({
id: 'users',
title: '人员明细'
});

userGrid.addField({
id: 'user',
title: '人员',
type: 'EntityRef',
source: 'User',
width: 200
});

userGrid.addField({
id: 'days',
title: '天数',
type: 'Number',
width: 100,
decimal: 2,
enableSummary: true,
summaryType: 'Sum'
});

addParentLayout(options) 多级表头​

addParentLayout 添加的是表头分组。分组只负责展示,不产生数据列,也不参与校验和提交。只有末级 addField 才是可录入列。

分组可以多层嵌套:parentId 指向已添加的上级分组。不传 parentId 时,分组位于顶层。分组 id 在同一张表内不能与字段 id 重复。

options 参数​

名称类型说明必填默认值
idstring分组唯一标识☑️-
titlestring表头显示名称☑️-
parentIdstring上级分组 id。不设则为顶层分组-

语法​

const items = formDialogBuilder.addSubGrid({
id: 'items',
title: '明细'
});

items.addField({ id: 'code', title: '编码', type: 'Text', width: 120 });
items.addParentLayout({ id: 'amount', title: '金额' });
items.addParentLayout({ id: 'tax', title: '税额', parentId: 'amount' });
items.addField({
id: 'amountValue',
title: '金额',
type: 'Number',
width: 100,
decimal: 2,
parentId: 'amount',
enableSummary: true,
summaryType: 'Sum'
});
items.addField({
id: 'taxAmount',
title: '税额',
type: 'Number',
width: 100,
decimal: 2,
parentId: 'tax',
enableSummary: true,
summaryType: 'Sum'
});
items.addField({ id: 'remark', title: '备注', type: 'Text', width: 200 });

用户看到的表头结构是:

编码
金额(分组)
├─ 税额(分组)
│ └─ 税额
└─ 金额
备注

同级顺序等于 addField / addParentLayout 的调用顺序。上面示例的顶层顺序是「编码、金额分组、备注」。「金额」分组下先是「税额」分组,再是金额列;「税额」分组下只有税额列。分组本身不产生数据,只有最末级的编码、税额、金额、备注才写入行数据。

removeField / removeParentLayout 删除列​

grid.removeField('amt_2026_01');
grid.removeParentLayout('year_2026');
grid.rebuildColumns();
  • removeField(fieldId) 删除一个末级字段。
  • removeParentLayout(layoutId) 删除分组,并连带删除其下的子分组和字段。
  • 表单打开后再删除,必须接着调用 rebuildColumns()。删除后该列从表头消失,已有行上对应的值也会清掉。

rebuildColumns() 刷新列​

表单打开后,用建表时拿到的明细表对象调用 addField、addParentLayout、removeField、removeParentLayout,最后必须调用 rebuildColumns()。运行时也可以通过 ctx.getFormContext().form.getSubGrid(path).rebuildColumns() 刷新。

rebuildColumns 会:

  1. 按当前字段同步子表 schema:新增列补上类型,删除列清掉行上的旧 key
  2. 刷新列头
  3. 让已有行数据与新列对齐

动态列的 id 必须和行数据的 key 一致。按月份展开金额时,一行上是多个金额格子,而不是一个月一行。

function rebuildAmountColumns(grid, months) {
grid.removeParentLayout('year_2026');
grid.addParentLayout({ id: 'year_2026', title: '2026' });

months.forEach((month) => {
const monthId = 'm_' + month;
const fieldId = 'amt_2026_' + String(month).padStart(2, '0');
grid.addParentLayout({ id: monthId, title: String(month), parentId: 'year_2026' });
grid.addField({
id: fieldId,
title: '金额',
type: 'Number',
width: 100,
decimal: 2,
parentId: monthId,
enableSummary: true,
summaryType: 'Sum'
});
});

grid.rebuildColumns();
}

formOnInit 时表单还没创建,不能在这个时机改列。列维护放在 formOnLoad 以及之后的事件里。

底部合计​

在列上设置 enableSummary: true 后,表格底部固定一行显示该列的汇总值。行号位置显示「合计」。

summaryType含义适用列
Sum求和仅数字列:Number、Amount、Percent
Max最大值数字或文本等
Min最小值数字或文本等
Avg平均值建议数字列
Count非空格子的个数任意类型

规则:

  • 未设置 enableSummary 的列,底部不显示合计。
  • 开了合计但没写 summaryType,按 Sum 计算。
  • 非数字列使用 Sum 不会生效,需要改成 Max、Min、Avg 或 Count。
  • 空值、null、空字符串不参与 Sum、Avg、Max、Min。Count 只统计有值的格子。
  • 数字合计按列的 decimal 四舍五入,未设置时按 2 位。
  • 树形明细只合计末级行。父行上的金额不会再加一次。例如父节点数量是 10,两个末级分别是 4 和 6,合计是 10,不是 20。
items.addField({
id: 'qty',
title: '数量',
type: 'Number',
width: 100,
decimal: 2,
enableSummary: true,
summaryType: 'Sum'
});

items.addField({
id: 'remark',
title: '备注',
type: 'Text',
width: 160,
enableSummary: true,
summaryType: 'Count'
});

数量列底部是各行数量之和,备注列底部是填写了备注的行数。