简体中文 | English
- 表单中每个表单项的配置
- 一般只需要配置
type
等少量参数即可使用 Form
组件会基于每个formItem
的配置对输入的数值进行相应的验证Form
验证不通过将无法点击确认
或下一步
按钮
-
每个表单项包含通用型配置
-
name
,表单项的key
值,必须项,且唯一,表单项的值在验证通过后保存在form.values[name]
中 -
label
,表单项左侧的标签 -
required
, 可选项,默认值为false
,值为true
时为必填项 -
hidden
, 当前表单项是否可隐藏,默认值为false
-
onChange
,当前表单项变更时触发的函数 -
extra
,表单想下方的说明文字 -
tip
,表单项左侧标签旁边的问号悬停时显示的内容-
以创建云主机
src/pages/compute/containers/Instance/actions/StepCreate/BaseStep/index.jsx
为例{ name: 'availableZone', label: t('Available Zone'), type: 'select', placeholder: t('Please select'), isWrappedValue: true, required: true, options: this.availableZones, tip: t( 'Availability zone refers to a physical area where power and network are independent of each other in the same area. In the same region, the availability zone and the availability zone can communicate with each other in the intranet, and the available zones can achieve fault isolation.' ), }
-
-
validator
,验证表单的数值是否符合要求-
返回
Promise
-
以裸机节点创建端口
src/pages/compute/containers/BareMetalNode/Detail/Port/actions/Create.jsx
为例export const macAddressValidate = (rule, value) => { if (isMacAddress(value.toUpperCase())) { return Promise.resolve(true); } return Promise.reject(new Error(`${t('Invalid: ')}${macAddressMessage}`)); }; { name: 'address', label: t('MAC Address'), required: true, type: 'input', validator: macAddressValidate, }
-
-
component
,直接使用component
中的组件,而不是使用type
配置的组件-
以云主机修改配置
src/pages/compute/containers/Instance/actions/Resize.jsx
为例- 直接展示云主机类型选择组件
{ name: 'newFlavor', label: t('Flavor'), component: ( <FlavorSelectTable flavor={flavor} onChange={this.onFlavorChange} /> ), required: true, wrapperCol: { xs: { span: 24, }, sm: { span: 18, }, }, }
-
-
labelCol
,调整表单项标题的布局,默认使用Form
下定义的标签布局 -
wrapperCol
,调整表单项右侧的布局,默认使用Form
下定义的布局 -
style
,定义表单项的样式-
以创建虚拟网卡
src/pages/network/containers/VirtualAdapter/actions/Create.jsx
为例{ name: 'ipv6', label: 'IPv6', type: 'label', style: { marginBottom: 24 }, content: ( <span> {t('The selected VPC/subnet does not have IPv6 enabled.')}{' '} <Button type="link"> {t('To open')} <FormOutlined /> </Button>{' '} </span> ), hidden: true, }
-
-
dependencies
,依赖项,数组,依赖项的数值变动后,会触发当前表单项的验证-
以云主机更新密码
src/pages/compute/containers/Instance/actions/ChangePassword.jsx
为例- 确认密码的验证,要依赖于密码的输入
{ name: 'confirmPassword', label: t('Confirm Password'), type: 'input-password', dependencies: ['password'], required: true, otherRule: getPasswordOtherRule('confirmPassword', 'instance'), },
-
-
otherRule
,额外的验证规则
-
-
每个表单根据自己的
type
有独属于自身的配置项,目前支持的type
有-
label
-
展示内容使用
-
iconType
属性,可以显示资源对应的 iconconst iconTypeMap = { instance: <DesktopOutlined />, router: <BorderOuterOutlined />, externalNetwork: <GlobalOutlined />, network: <GlobalOutlined />, firewall: <SecurityScanOutlined />, volume: <InboxOutlined />, gateway: <GatewayOutlined />, user: <UserOutlined />, snapshot: <CameraOutlined />, backup: <SaveOutlined />, keypair: <KeyOutlined />, image: ImageIcon, aggregate: <ClusterOutlined />, metadata: <TagOutlined />, flavor: <HddOutlined />, host: <CloudServerOutlined />, };
-
content
属性,默认是基于name
属性展示内容,如果具有content
属性,则依照content
展示内容-
content
可以是字符串,也可以是 ReactNode -
以虚拟网卡修改 QoS
src/pages/network/containers/VirtualAdapter/actions/ModifyQoS.jsx
为例{ name: 'name', label: t('Current QoS policy name'), type: 'label', content: <div>{qosPolicy.name || t('Not yet bound')}</div>, hidden: !enableQosPolicy, }
-
-
-
input
-
select
-
选择
-
options
,必须项,option
数组,每个option
需要具有如下属性value
,值label
,展示的文本
-
以创建云主机选择可用域
src/pages/compute/containers/Instance/actions/StepCreate/BaseStep/index.jsx
为例get availableZones() { return (globalAvailabilityZoneStore.list.data || []) .filter((it) => it.zoneState.available) .map((it) => ({ value: it.zoneName, label: it.zoneName, })); } { name: 'availableZone', label: t('Available Zone'), type: 'select', placeholder: t('Please select'), isWrappedValue: true, required: true, options: this.availableZones, tip: t( 'Availability zone refers to a physical area where power and network are independent of each other in the same area. In the same region, the availability zone and the availability zone can communicate with each other in the intranet, and the available zones can achieve fault isolation.' ), },
-
isWrappedValue
,表示表单项的值中是否要包含option
信息- 默认值为
false
,值为选中的option
中的value
- 如果设为
true
,值为选中的option
- 默认值为
-
-
divider
-
radio
-
单选
-
options
,必须项,option
数组,每个option
需要具有如下属性value
,值label
,展示的文本
-
以创建云主机选择登陆凭证类型
src/pages/compute/containers/Instance/actions/StepCreate/SystemStep/index.jsx
为例get loginTypes() { return [ { label: t('Keypair'), value: 'keypair', disabled: this.isWindowsImage, }, { label: t('Password'), value: 'password', }, ]; } { name: 'loginType', label: t('Login Type'), type: 'radio', options: this.loginTypes, isWrappedValue: true, },
-
isWrappedValue
,表示表单项的值中是否要包含option
信息- 默认值为
false
,值为选中的option
中的value
- 如果设为
true
,值为选中的option
- 默认值为
-
-
select-table
-
带有选择操作的表格
-
isMulti
,是否是多选,默认为false
-
data
,数据源,使用前端分页时使用 -
columns
,表格列的配置,配置方式同BaseList
-
filterParams
,搜索项的配置 -
pageSize
,每页条目数量,默认为 5 -
disabledFunc
,判定哪些条目不可选 -
selectedLabel
,表格底部的标签,默认为已选
-
header
,表格上方的内容 -
backendPageStore
,使用后端分页时,数据对应的store
-
backendPageFunc
,使用后端分页时,获取数据的方法,默认为fetchListByPage
-
backendPageDataKey
,使用后端分页时,数据在store
中的位置,默认为list
-
extraParams
,使用后端分页时,发起请求时的额外参数 -
isSortByBack
,是否使用后端排序,默认为false
-
defaultSortKey
,使用后端排序时,默认的排序键 -
defaultSortOrder
,使用后端排序时,默认的排序方向 -
initValue
,初始值 -
rowKey
,数据的唯一标识,默认为id
-
onRow
,点击条目时的操作,默认点击条目就会选中该条目 -
tabs
,tab 型的表格 -
defaultTabValue
,tab 型表格时,默认的 tab -
onTabChange
,tab 型表格时,tab 切换时,调用的函数 -
以创建云主机选择安全组
src/pages/compute/containers/Instance/actions/StepCreate/NetworkStep/index.jsx
为例- 这个表格的右侧标题有 tip 提示
- 使用后端分页的方式展示数据,并具有额外的参数
- 是多选
- 这个表格的上方有额外的展示内容
- 需要复写
onRow
属性,以免点击表格中的查看规则
按钮时产生操作冲突
{ name: 'securityGroup', label: t('Security Group'), type: 'select-table', tip: t( 'Each instance belongs to at least one security group, which needs to be specified when it is created. Instances in the same security group can communicate with each other on the network, and instances in different security groups are disconnected from the internal network by default.' ), backendPageStore: this.securityGroupStore, extraParams: { project_id: this.currentProjectId }, required: true, isMulti: true, header: ( <div style={{ marginBottom: 8 }}> {t( 'The security group is similar to the firewall function and is used to set up network access control. ' )} {t(' You can go to the console to ')} <Link to="/network/security-group"> {t('create a new security group')}>{' '} </Link> {t( 'Note: The security group you use will act on all virtual adapters of the instance.' )} </div> ), filterParams: securityGroupFilter, columns: securityGroupColumns, onRow: () => {}, },
-
以创建云硬盘选择镜像
src/pages/storage/containers/Volume/actions/Create/index.jsx
为例- 这是带有 Tab 标签的表格,默认展示第一个 tab,tab 切换时会更新数据源
- 数据使用前端分页的方式获取,直接配置
data
即可 - 是单选
- 配置了已选标签为
已选 镜像
{ name: 'image', label: t('Operating System'), type: 'select-table', data: this.images, required: sourceTypesIsImage, isMulti: false, hidden: !sourceTypesIsImage, filterParams: [ { label: t('Name'), name: 'name', }, ], columns: getImageColumns(this), tabs: this.systemTabs, defaultTabValue: this.systemTabs[0].value, selectedLabel: t('Image'), onTabChange: this.onImageTabChange, }
-
-
input-number
-
input-int
-
instance-volume
-
云主机硬盘配置组件
-
options
,云硬盘类型的选项 -
minSize
,云硬盘大小输入框的最小值 -
以创建云主机配置系统盘
src/pages/compute/containers/Instance/actions/StepCreate/BaseStep/index.jsx
为例{ name: 'systemDisk', label: t('System Disk'), type: 'instance-volume', options: this.volumeTypes, required: !this.sourceTypeIsVolume, hidden: this.sourceTypeIsVolume, validator: this.checkSystemDisk, minSize: this.getSystemDiskMinSize(), extra: t('Disk size is limited by the min disk of flavor, image, etc.'), onChange: this.onSystemDiskChange, }
-
-
input-password
-
密码输入框
-
以创建云主机输入密码
src/pages/compute/containers/Instance/actions/StepCreate/SystemStep/index.jsx
为例- 输入密码,确认密码,并要验证密码格式,以及两次输入数据的一致性
{ name: 'password', label: t('Login Password'), type: 'input-password', required: isPassword, hidden: !isPassword, otherRule: getPasswordOtherRule('password', 'instance'), }, { name: 'confirmPassword', label: t('Confirm Password'), type: 'input-password', required: isPassword, hidden: !isPassword, otherRule: getPasswordOtherRule('confirmPassword', 'instance'), },
-
-
input-name
-
带有格式验证的名称输入框
-
placeholder
,输入框的提示语 -
isFile
,以文件格式验证名称 -
isKeypair
,以密钥支持的格式验证名称 -
isStack
,以堆栈支持的格式验证名称 -
isImage
,以镜像支持的格式验证名称 -
isInstance
,以云主机支持的格式验证名称 -
以创建云主机输入名称
src/pages/compute/containers/Instance/actions/StepCreate/SystemStep/index.jsx
为例{ name: 'name', label: t('Name'), type: 'input-name', placeholder: t('Please input name'), required: true, isInstance: true, }
-
-
port-range
-
more
-
textarea
-
upload
-
add-select
-
可以添加、删除条目的表单项
-
minCount
,最小数量 -
maxCount
,最多数量 -
itemComponent
,增加的每个条目使用的组件 -
defaultItemValue
,新增条目的默认值 -
addText
,添加条目按钮右侧的文字 -
addTextTips
,如果maxCount
存在,随着条目数量的变更,显示的文字 -
以创建云主机设置数据盘
src/pages/compute/containers/Instance/actions/StepCreate/BaseStep/index.jsx
为例- 可以设置任意个数的数据盘
{ name: 'dataDisk', label: t('Data Disk'), type: 'add-select', options: this.volumeTypes, defaultItemValue: this.defaultVolumeType, itemComponent: InstanceVolume, minCount: 0, addTextTips: t('Data Disks'), addText: t('Add Data Disks'), extra: t( 'Too many disks mounted on the instance will affect the read and write performance. It is recommended not to exceed 16 disks.' ), onChange: this.onDataDiskChange, },
-
-
ip-input
-
带有验证功能的 IP 输入框
-
version
,ip 类型,默认是4
,还可设置为6
-
以云主机挂载网卡手动指定 IP
src/pages/compute/containers/Instance/actions/AttachInterface.jsx
为例{ name: 'ip', label: t('Given IP'), type: 'ip-input', required: ipType === 1, hidden: ipType !== 1, version, // defaultIp, validator: this.checkIP, extra: t('Please make sure this IP address be available.'), }
-
-
member-allocator
-
descriptions
-
展示多种信息的表单项
-
title
,右侧内容的标题 -
onClick
,右侧内容标题旁的跳转按钮 -
items
,每个信息展示项的配置,数组label
,信息展示项左侧的标题文字value
,信息展示项右侧的值span
,信息展示右侧占用的布局尺寸
-
以创建云主机确认
src/pages/compute/containers/Instance/actions/StepCreate/ConfirmStep/index.jsx
为例{ name: 'confirm-config', label: t('Config Overview'), type: 'descriptions', title: t('Base Config'), onClick: () => { this.goStep(0); }, items: [ { label: t('Start Source'), value: context.source.label, }, { label: t('System Disk'), value: this.getSystemDisk(), }, { label: t('Available Zone'), value: context.availableZone.label, }, { label: t('Start Source Name'), value: this.getSourceValue(), }, { label: t('Data Disk'), value: this.getDataDisk(), }, { label: t('Project'), value: context.project, }, { label: t('Flavor'), value: this.getFlavor(), }, ], }
-
-
slider-input
-
滑动与输入联动的表单项
-
min
,最小值 -
max
,最大值 -
description
,滑动条下的描述语 -
以创建云硬盘设置容量
src/pages/storage/containers/Volume/actions/Create/index.jsx
为例{ name: 'size', label: t('Capacity (GB)'), type: 'slider-input', max: this.maxSize, min: minSize, description: `${minSize}GB-${this.maxSize}GB`, required: this.quotaIsLimit, hidden: !this.quotaIsLimit, onChange: this.onChangeSize, },
-
-
title
-
switch
-
开关
-
以创建虚拟网卡设置安全组
src/pages/network/containers/VirtualAdapter/actions/Create.jsx
为例{ name: 'port_security_enabled', label: t('Port Security'), type: 'switch', tip: t( 'Disabling port security will turn off the security group policy protection and anti-spoofing protection on the port. General applicable scenarios: NFV or operation and maintenance Debug.' ), onChange: (e) => { this.setState({ port_security_enabled: e, }); }, }
-
-
check
-
transfer
-
穿梭框
-
leftTableColumns
,左侧表格的列配置 -
rightTableColumns
,右侧表格的列配置 -
dataSource
,可供选择的数据源 -
showSearch
,是否显示搜索输入框 -
oriTargetKeys
,初始化的选中值 -
disabled
,是否禁用左侧数据的选中,默认为false
-
以用户编辑系统角色
src/pages/identity/containers/User/actions/SystemRole.jsx
为例- 左侧是项目名称列表
- 右侧是项目名称、对项目配置的角色信息列表
{ name: 'select_project', type: 'transfer', label: t('Project'), leftTableColumns: this.leftUserTable, rightTableColumns: this.rightUserTable, dataSource: this.projectList ? this.projectList.filter((it) => it.domain_id === domainDefault) : [], disabled: false, showSearch: true, oriTargetKeys: projectRoles ? Object.keys(projectRoles) : [], }
-
-
check-group
-
checkbox 组
-
options
,配置每个checkbox
的信息label
,每个checkbox
对应的文字value
,checkbox
对应的键
-
以编辑元数据
src/pages/configuration/containers/Metadata/actions/Edit.jsx
为例- 配置 公有、受保护的 属性
{ name: 'options', label: t('Options'), type: 'check-group', options: [ { label: t('Public'), value: 'isPublic' }, { label: t('Protected'), value: 'isProtected' }, ], }
-
-
textarea-from-file
-
ip-distributer
-
mac-address
-
network-select-table
-
volume-select-table
-
选择硬盘的表单项
-
分 Tab 展示可用的、共享的云硬盘
-
disabledFunc
,配置什么样的云硬盘不可选 -
以云主机挂载硬盘选择硬盘
src/pages/compute/containers/Instance/actions/AttachVolume.jsx
为例{ name: 'volume', label: t('Volume'), type: 'volume-select-table', tip: multiTip, isMulti: false, required: true, serverId: this.item.id, disabledFunc: (record) => { const diskFormat = _get( record, 'origin_data.volume_image_metadata.disk_format' ); return diskFormat === 'iso'; }, }
-
-
tab-select-table
-
带有 Tab 的表格型选择表单项
-
isMulti
,配置是否为多选 -
以申请浮动 IP 选择 Qos
src/pages/network/containers/FloatingIp/actions/Allocate.jsx
为例- 分当前项目、共享的 QoS,如果用户具有管理员权限,也具有所有 QoS 标签项
{ name: 'qos_policy_id', label: t('QoS Policy'), type: 'tab-select-table', tabs: getQoSPolicyTabs.call(this), isMulti: false, tip: t('Choosing a QoS policy can limit bandwidth and DSCP'), onChange: this.onQosChange, }
-
-
metadata-transfer
-
编辑元数据的表单项
-
以镜像编辑元数据
src/pages/compute/containers/Image/actions/ManageMetadata.jsx
为例{ name: 'systems', label: t('Metadata'), type: 'metadata-transfer', metadata: this.metadata, validator: (rule, value) => { if (this.hasNoValue(value)) { return Promise.reject(t('Please input value')); } return Promise.resolve(); }, }
-
-
aceEditor
-
aceEditor
-
以创建虚拟网卡编辑 Profile
src/pages/network/containers/VirtualAdapter/actions/Create.jsx
为例{ name: 'bindingProfile', label: t('Binding Profile'), type: 'aceEditor', hidden: !more, mode: 'json', wrapEnabled: true, tabSize: 2, width: '100%', height: '200px', setOptions: { enableBasicAutocompletion: true, enableLiveAutocompletion: true, enableSnippets: true, }, validator: (item, value) => { if (value !== undefined && value !== '') { try { JSON.parse(value); return Promise.resolve(true); } catch (e) { return Promise.reject(new Error(t('Illegal JSON scheme'))); } } return Promise.resolve(true); }, }
-
-
input-json
-
带有 json 格式验证的输入框
-
以创建堆栈编辑参数为例
src/resources/stack.js
为例export const getFormItemType = (type) => { switch (type) { case 'number': return { type: 'input-number', }; case 'json': return { type: 'input-json', }; case 'boolean': return { type: 'radio', options: yesNoOptions, }; default: return { type: 'input', }; } };
-
-