ecp_dform_app 2.1.7+1
ecp_dform_app: ^2.1.7+1 copied to clipboard
动态表单
ecp_dform_app #
ecp_dform_app 是一个自动生成渲染表单组件的组件库,通过渲染特定规则Json字符串渲染样式,特定规则数据Json字符串渲染数据;目前组件支持渲染如下组件:
此库专为内部项目需求设计,若不符合您的使用场景,敬请谅解。
- 输入框(Input)
- 数字输入框(InputNumber)
- 多行输入框 (Input.TextArea)
- 备注(remark)
- 时间选择 (TimePicker)
- 日期选择 (DatePicker)
- 组件布局(FormLayout)
- 单选框 (Radio.Group)
- 组件网格布局(FormGrid)
- 组件网格子布局 (FormGrid.GridColumn)
- 上传文件 (YiFileUpload)
对应默认组件名称如下:
- input/InputNumber ->TextEditorField
- datePicker ->DatePickerField
- timePicker ->TimePickerField
- textArea/textArea ->TextAreaField
- radioGroup ->radioPicker
- formGrid ->formGrid
- gridColumn ->gridColumn
- fileUpload -> UploadFileField
简单使用 #
- 准备组件样式Json字符串(本地或远程网络)
{
"schema": {
"x-designable-id": "momamuigso7",
"type": "object",
"properties": {
"Input1": {
"x-component": "Input",
"x-decorator": "FormItem",
"x-designable-id": "q5wn6s6b8a0",
"x-display": "visible",
"x-decorator-props": {},
"name": "Input1",
"x-pattern": "readOnly",
"x-validator": {},
"x-component-props": {
"required": false
},
"type": "string",
"title": "输入1",
"x-index": 0
},
"Input2": {
"x-component": "Input",
"x-decorator": "FormItem",
"x-designable-id": "cse7oco9skb",
"x-display": "visible",
"x-decorator-props": {
},
"name": "Input2",
"x-pattern": "editable",
"x-validator": {
},
"x-component-props": {
"required": true
},
"type": "string",
"title": "输入2",
"x-index": 1
},
"ewgsrvgtu25": {
"x-component": "Input",
"x-decorator": "FormItem",
"x-designable-id": "ewgsrvgtu25",
"x-display": "visible",
"x-decorator-props": {},
"x-pattern": "readOnly",
"x-validator": {},
"x-component-props": {
"required": true
},
"type": "string",
"title": "输入3",
"x-index": 2
}
}
}
}
- 准备对应组件初始化数据(本地或远程网络)
{
"Input1": "3131",
"Input2": "1414",
"ewgsrvgtu25": "414141"
}
- 渲染
DynamicForm(
jsonSchema: _jsonSchema, ///样式Json字符串
dataSchema: _data, ///数据Json字符串
controller: controller, ///控制器
)
属性说明 #
DynamicForm #
最终动态表单渲染组件,负责解析和渲染工作,默认渲染样式为ListView,其中包含可传入参数如下:
- items:静态表单数据,内部包含组件样式及数据,适用于静态渲染
- controller:动态表单组件控制器,负责处理数据
- factory:组件样式适配器,默认为DefaultMapperFactory
- jsonSchema:组件样式Json字符串
- dataSchema:组件数据字符串
- parse:解析器,负责将jsonSchema以及dataSchema解析为List
- physics:滑动类型,因为表单可能内嵌于其他滑动组件,防止动态表单渲染组件内ListView与外部组件冲突,建议设置成NeverScrollableScrollPhysics
- shrinkWrap:防止滑动嵌套时,内部ListView组件渲染不全
- permissions:控制表单组件显示、隐藏以及编辑功能
DynamicFormController #
动态表单控制器,用来控制整体表单数据行为,提供如下方法:
- reset:重置所有表单值
- save:保存当前表单值
- validate:校验表单组件是否合法
- submit:提交表单信息,首先通过[validate]方法校验是否表单是否合法,其次调用[save]方法保存表单数据至[FormSharedWidget]的[savedResult]中,最后调用[DynamicForm]的onSaved方法
DynamicFormConfig #
DynamicFormConfig保存了动态表单全局表单适配器以及解析器信息,可在应用初始化时替换
- factory:表单适配器,默认DefaultMapperFactory
- parse:表单解析器,默认_defaultParse
默认表单组件 #
动态表单内设置了默认表单组件,可根据需求继承/重写表单样式。
TextEditorField #
#
TextPickField #

RadioPickerField #

DatePickerField #

TimePickerField #

UploadFileField(Card) #

UploadFileField(List) #
#
自定义表单组件 #
若默认组件不满足需求,那么我们就需要自定义表单组件,自定义组件的步骤如下:
- 继承DynamicFieldState,重写content或者build方法,必要时重写didChange方法,更改组件数据
class DynamicTextFieldState<T> extends DynamicFieldState<T> {
@protected
late TextEditingController controller;
DynamicTextField<T> get _widget => widget as DynamicTextField<T>;
@override
Widget content() => TextField(
controller: controller,
keyboardType: _widget.inputType,
inputFormatters: _widget.inputFormatters,
style: _widget.contentStyle ?? context.bodyMediumStyle,
textAlign: _widget.contentAlign ?? TextAlign.end,
readOnly: _widget.readOnly ?? formItem.readOnly,
enabled: !(_widget.readOnly ?? formItem.readOnly),
onChanged: (newValue) {
if (value is String?) {
didChange(newValue as T);
}
},
maxLines: _widget.maxLines,
minLines: _widget.minLines,
maxLength: _widget.maxLength,
decoration: _widget.contentDecoration ??
InputDecoration(
isCollapsed: true,
border: InputBorder.none,
contentPadding:
_widget.contentPadding ?? EdgeInsets.only(left: 8.w),
hintText: _widget.hint,
hintStyle: _widget.hintStyle,
),
);
...
@override
void didChange(T? value) {
_updateText(value);
super.didChange(value);
}
}
- 继承DynamicField,重写createState方法,返回1步骤中继承DynamicFieldState的类型
///带文字输入框基础组件
///
///@author lzj
///
///@since 2022/8/8 14:10
class DynamicTextField<T> extends DynamicField<T> {
///忽略属性代码
...
DynamicTextField({
super.key,
...
}) :super();
@override
DynamicTextFieldState<T> createState() => DynamicTextFieldState<T>();
}