icsoc-rc-custom-form
v1.2.5
Published
基于antd的react组件扩展
Downloads
4
Readme
category: Components subtitle: 自定义表单组件 type: 新增组件 title: CustomForm modifiedJs: 1 order: 1 cols: 1
自定义表单组件。
何时使用
- 需要通过拖拽自定义表单布局的场景。
API
EditForm 编辑表单
| 参数 | 说明 | 类型 | 默认值 | | --------- | ----------------------------------- | ---- | ------ | | list | 左侧可拖拽数据列表 | 数组 | [] | | totalData | 表单布局数据,用于复现表单 | {} | {} | | ref | react 的 ref 用于调用组件的保存方法 | -- | -- | | noTitle | 是否不需要设置表单标题 | 布尔 | false | | btnArea | 将传入的dom直接透传在左侧数据列表下方 | -- | null |
特别说明:将 ref 绑定到 this.editForm 后通过 this.editForm.onSave()可获取编辑好的布局数据。 与后端沟通,每个字段的 options 由后端统一维护,不在数据库中保存,所以在上传给后端时需过滤掉 options 与 name 属性,在取接口数据时由后端拼接后再返回
数据举例:
list = [
{
id: "1",
name: "attachment_1",
type: "attachment",
options: {
size: "default",
placeholder: "请选择附件",
upbtnstyle: "button", // button、square
action: "/v1/ticket/upload/files",
label: "附件",
reqData: 0,
defvalueInput: "",
maxFileNum: 1, // 最大附件上传数量,仅支持attachment类型。无相关限制可不填
}
},
{
id: "2",
name: "cascade_2",
type: "cascade",
options: {
size: "default",
label: "级联",
placeholder: "级联",
defvalue: ["zhejiang", "hangzhou"],
items: [
{
value: "zhejiang",
label: "Zhejiang",
children: [
{
value: "hangzhou",
label: "Hangzhou",
children: [
{
value: "xihu",
label: "West Lake"
}
]
}
]
}
]
}
},
{
id: "3",
name: "checkbox_3",
type: "checkbox",
options: {
size: "default",
label: "多选",
defvalue: ["选项 1", "选项 2"],
items: [
{
text: "选项 1",
value: "选项 1"
},
{
text: "选项 2",
value: "选项 2"
}
],
reqData: 0,
defvalueInput: ""
}
},
{
id: "4",
name: "city_4",
type: "city",
options: {
level: 2, // 默认0,可不填 0、省市区 1、省市 2、省
size: "default",
label: "省市区",
placeholder: "请填写省市区...",
rules: [{ required: true, message: "不能空 111" }],
items: [
{
value: "zhejiang",
label: "Zhejiang",
children: [
{
value: "hangzhou",
label: "Hangzhou",
children: [
{
value: "xihu",
label: "West Lake"
}
]
}
]
}
]
}
},
{
id: "5",
name: "date_5",
type: "datetime",
options: {
size: "default",
placeholder: "请选择日期",
defvalue: "",
label: "日期",
dateFormat: "YYYY-MM-DD",
reqData: 1,
defvalueInput: "%utetime%"
}
},
{
id: "6",
name: "email_6",
type: "email",
options: {
size: "default",
placeholder: "[email protected]",
label: "邮箱",
reqData: 0,
defvalueInput: ""
}
},
{
id: "7",
name: "input_7",
type: "input",
options: {
size: "default",
placeholder: "请输入...",
label: "单行",
reqData: 1,
defvalueInput: "%name%",
rules: [{ required: true, message: "不能空 111" }]
}
},
{
id: "8",
name: "linkage_8",
type: "linkage",
options: {
size: "default",
placeholder: "请输入...",
label: "联动",
reqData: 1,
defvalueInput: "%name%",
rules: [{ required: true, message: "不能空 111" }],
items: [
{
text: "1",
value: "1"
},
{
text: "2",
value: "2",
optionLinks: [{
id: "9",
name: "textarea_9",
type: "textarea",
options: {
size: "default",
placeholder: "请填写评论...",
label: "多行",
rows: 3,
reqData: 0,
defvalueInput: ""
}
}]
}
]
}
},
{
id: "10",
name: "mobile_10",
type: "mobile",
options: {
size: "default",
placeholder: "输入手机",
label: "手机",
reqData: 0,
defvalueInput: ""
}
},
{
id: "11",
name: "number_11",
type: "number",
options: {
size: "default",
label: "数字",
defvalue: 3,
min: 1,
max: 10,
reqData: 0,
defvalueInput: ""
}
},
{
id: "12",
name: "radio_12",
type: "radio",
options: {
size: "default",
placeholder: "",
label: "单选",
defvalue: "1",
items: [
{
text: "A1",
value: "1"
},
{
text: "B1",
value: "2"
},
{
text: "C1",
value: "3"
},
{
text: "D1",
value: "4"
},
{
text: "E1",
value: "5"
},
{
text: "F1",
value: "6"
}
],
reqData: 0,
defvalueInput: ""
}
},
{
id: "13",
name: "select_13",
type: "select",
options: {
size: "default",
placeholder: "下拉选择",
defvalue: "lucy",
label: "下拉",
items: [
{
text: "苹果",
value: "lucy"
},
{
text: "葡萄",
value: "jack"
},
{
text: "香蕉",
value: "Yimingh"
}
],
reqData: 0,
defvalueInput: ""
}
},
{
id: "14",
name: "telephone_14",
type: "telephone",
options: {
size: "default",
placeholder: "座机电话",
label: "座机",
reqData: 0,
defvalueInput: ""
}
},
{
id: "15",
name: "textarea_15",
type: "textarea",
options: {
size: "default",
placeholder: "请填写评论...",
label: "多行",
rows: 3,
reqData: 0,
defvalueInput: ""
}
},
association: {
id: "16",
name: "association_1",
type: "association",
options: {
label: "客户名称",
placeholder: "请输入客户名称",
assocType: { // 参数数据 示例:{"type": "user.list", "url": "/api/user/users"}
type: "user.list",
url: "/api/user/users",
},
defvalue: [{
value: "zs",
text: "张三",
}],
latestvalue: { // 历史编辑值
value: "ls",
text: "李四",
},
rules: [{
required: true,
message: "不能为空"
}]
}
},
// crm新增类型
phone: {
id: "17",
name: "phone_1",
type: "phone",
options: {
size: "default",
placeholder: "电话",
label: "座机",
reqData: 0,
defvalueInput: ""
}
},
];
totalData={
formTitle: "000",
formData: [
{
id: "5",
type: "datetime",
rowKey: 3,
columnKey: 1,
itemId: 1,
name:"date_5",
options: {
size: "default",
placeholder: "请选择日期",
defvalue: "",
label: "日期",
dateFormat: "YYYY-MM-DD",
reqData: 1,
defvalueInput: "%utetime%"
}
},
{
id: "line1",
name: "分割线",
type: "line",
drags: true,
options: {
label: "分割线",
defvalue: "999",
placeholder: "请输入分割线名称"
},
rowKey: 1,
columnKey: 1,
itemId: 2
},
{
id: "line1",
name: "分割线",
type: "line",
drags: true,
options: {
label: "分割线",
defvalue: "888",
placeholder: "请输入分割线名称"
},
isDrag: false,
rowKey: 7,
columnKey: 1,
itemId: 7
}
],
formMatrix: [
{ key: 1, column: [1] },
{ key: 2, column: [1, 2] },
{ key: 3, column: [1, 2] },
{ key: 5, column: [1, 2] },
{ key: 4, column: [1, 2] },
{ key: 7, column: [1] },
{ key: 6, column: [1, 2] }
]
};
ShowForm 展示表单
| 参数 | 说明 | 类型 | 默认值 | | ----------- | -------------------------------------------------------- | ---- | ------------------------------------- | | totalData | 表单布局数据与默认数据 | 数组 | [] | | options | 前端传入数据,如暴露的方法与传入的变量 | obj | -- | | onRef | 通过 ref 绑定组件 | -- | onRef={ref => { this.showForm = ref}} | | customProps | 自定义拖拽属性,把指定类型的属性添加到同类型的字段表单中,在某种类型内部,还能根据表单name定制化私有属性 | 数组 | [] | | customRules | 添加一些自定义的form校验规则,与antd的Form校验规则保持一致 | obj | -- |
数据格式示例:
totalData同EditForm组件
options={
data: {
//前端传入变量
name: 222,
name2: 333
},
actions: {
//暴露给前端方法
onPhone: this.handlePhone, //手机打电话
onEmail: this.handleEmail, //手机发短信
onTelephone: this.handleTelephone //座机打电话
}
}
customProps={[
{
type:"attachment",
props:{
beforeUpload:this.beforeUpload.bind(this)
},
nameFilter: {
// 表单name
association_1: {
useCommon: true, // true | false 默认使用当前类型定义的props,为false时不使用
size: 'small',
mode: 'loadall',
action: () => {},
indivalue: { value: 'zs', text: '张三' },
}
}
},
]}
customRules={
phone: [
{
pattern: /^[0-9*]*$/,
message: '号码只能由数字与 * 组成',
},
{
max: 13,
message: '最多13位',
}
],
input: [
{
min: 5,
message: '最少5位',
}
],
}
特别说明: 1.ShowForm 组件用 form 高阶组件包装过所以无法用 ref 直接获取 this,组件内部通过 onRef 方法暴露出 this,所以可以用 onRef 获取 this;将 ref 绑定到 this.showForm.onSave()可获取编辑好的表单数据,返回的数据有 3 种情况: (1)、[0]:表示校验不通过; (2)、[1,data]:保存成功,data 为当前表单的所有数据; (3)、[2]:附件正在上传中; 2.工单项目的初始化接口需求是通过 options 里的 data 完成的,options 里的 actions 是预置的方法,用于暴露手机与座机的点击事件;可通过 customProps 覆盖。
注意事项: 1.resultForm 有自身的特殊性,因为初始化接口的需求,会不定期需要传入不同的 options 给特定的表单注入值,所以需要在 componentWillReceiveProps 中调用 form 的 setFieldsValue 方法,而此方法会使被此 form 包裹的组件全部更新,从而导致组件的无限渲 染,针对此问题的解决办法是把当前需要注入的值用 state 存起来,在调用 setFieldsValue 方法前判断当前需要注入的值与前一次的值是否 相同,如相同就不调用此方法,此解决办法引出了另一个问题,就是同一个表单只能注入一次值,这个问题的解决办法是需要注入值时需要 更新组件的 key,保证这次的组件是全新的、可以注入值的。
关于组件的想法: 此组件针对工单需求做了太多的业务处理,所以其他项目需要复用时需要做比较大的处理; 个人觉得可以在 crm 使用时做一次大的修改,把处理数据的部分与初始化接口这块的逻辑抽成方法暴露出去,在调用组件前先通过此方法把数据处理一遍再传给组件,保证组件的输入与输出数据的一致性,也便于维护与组件的复用。
API
ResultForm 编辑表单
| 参数 | 说明 | 类型 | 默认值 | | ---------- | --------------------------------------------------------------- | ---- | ------ | | formValue | 需要显示的表单的值 | {} | {} | | formData | 单个表单信息,同 EditForm 组件里 totalData 里的 formData 属性 | [] | [] | | formMatrix | 组件行列信息,同 EditForm 组件里 totalData 里的 formMatrix 属性 | [] | [] | | defaultValue | 表单值为空时的默认显示,非必填 | '' | 无 | | styleType | 整体样式风格,目前支持'default'、'crm'两种 | '' | 'default' |