跳到主要内容

XphForm 可配置表单

基本使用

测试
1 item
  • 标题2
1 item
  • 标题1
leaf3
Zhejiang / Hangzhou / West Lake
1
leaf3
0 item
Simple Empty
No data
0 item
Simple Empty
No data
上传
上传
import React from "react";
import { InputNumber } from "antd";
import dayjs from "dayjs";
import {
XphForm,
useXphForm,
IXphFormProps,
IXphFormActionType,
} from "xph-crud";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
labelCol: { span: 6 },
wrapperCol: { span: 18 },
items: [
{
name: "Input",
label: "Input",
component: "Input",
required: true,
colProps: { span: 8 },
initialValue: "Input",
componentProps: {
onChange: (e) => {
// console.log(e);
},
},
},
{
name: "render",
label: "render",
render: ({ model, disabled, name, methods, componentProps }) => (
<div>
<InputNumber
disabled={disabled}
value={model[name]}
onChange={(e) => methods.setFieldsValue({ [name]: e })}
{...componentProps}
/>
</div>
),
componentProps: {
placeholder: "render",
},
show: ({ model }) => {
return model.Input !== "Input";
},
ifShow: ({ model }) => {
return model.Input;
},
colProps: { span: 8 },
initialValue: 2,
rules: [
{
required: true,
message: "render必填",
},
],
},
{
name: "InputNumber",
label: "InputNumber",
component: "InputNumber",
componentProps: {
onBlur: (e) => {
console.log(e);
},
onChange: (e) => {
console.log(e);
},
},
initialValue: 2,
colProps: { span: 8 },
},
{
name: "Select",
label: "Select",
component: "Select",
componentProps: {
allowClear: true,
placeholder: "Select",
options: [
{ label: "测试", value: "1" },
{ label: "测试2", value: "2" },
],
onChange: (e) => {
console.log(e);
},
},
initialValue: "1",
colProps: { span: 8 },
},
{
name: "Transfer",
label: "Transfer",
component: "Transfer",
valuePropName: "targetKeys",
initialValue: ["1"],
componentProps: {
dataSource: [
{
key: "1",
title: "标题1",
},
{
key: "2",
title: "标题2",
},
],
render: (item) => item.title,
},
colProps: { span: 8 },
rules: [
{
required: true,
type: "array",
message: "Transfer必填",
},
],
},
{
name: "TreeSelect",
label: "TreeSelect",
component: "TreeSelect",
componentProps: {
placeholder: "请选择TreeSelect",
treeData: [
{
value: "parent 1",
title: "parent 1",
children: [
{
value: "parent 1-0",
title: "parent 1-0",
children: [
{
value: "leaf1",
title: "leaf1",
},
{
value: "leaf2",
title: "leaf2",
},
],
},
{
value: "parent 1-1",
title: "parent 1-1",
children: [
{
value: "leaf3",
title: <b style={{ color: "#08c" }}>leaf3</b>,
},
],
},
],
},
],
},
initialValue: "leaf3",
colProps: { span: 8 },
rules: [
{
required: true,
message: "TreeSelect必填",
},
],
},
{
name: "Switch",
label: "Switch",
component: "Switch",
componentProps: {},
initialValue: true,
valuePropName: "checked",
colProps: { span: 8 },
},
{
name: "Radio",
label: "Radio",
component: "Radio",
componentProps: {},
valuePropName: "checked",
initialValue: true,
colProps: { span: 8 },
},
{
name: "RadioGroup",
label: "RadioGroup",
component: "RadioGroup",
componentProps: {
options: [
{ label: "A", value: "a" },
{ label: "B", value: "b" },
{ label: "C", value: "c" },
{ label: "D", value: "d" },
],
},
initialValue: "a",
colProps: { span: 8 },
},
{
name: "RadioButtonGroup",
label: "RadioButtonGroup",
component: "RadioGroup",
componentProps: {
optionType: "button",
buttonStyle: "solid",
options: [
{ label: "A", value: "a", disabled: true },
{ label: "B", value: "b", disabled: false },
{ label: "C", value: "c", disabled: false },
{ label: "D", value: "d", disabled: true },
],
},
initialValue: "a",
colProps: { span: 8 },
},
{
name: "Checkbox",
label: "Checkbox",
component: "Checkbox",
componentProps: {},
valuePropName: "checked",
colProps: { span: 8 },
initialValue: true,
},
{
name: "CheckboxGroup",
label: "CheckboxGroup",
component: "CheckboxGroup",
componentProps: {
options: [
{ label: "A", value: "a" },
{ label: "B", value: "b" },
{ label: "C", value: "c" },
{ label: "D", value: "d" },
],
},
initialValue: ["a"],
colProps: { span: 8 },
},
{
name: "Cascader",
label: "Cascader",
component: "Cascader",
componentProps: {
placeholder: "请选择Cascader",
options: [
{
value: "zhejiang",
label: "Zhejiang",
children: [
{
value: "hangzhou",
label: "Hangzhou",
children: [
{
value: "xihu",
label: "West Lake",
},
],
},
],
},
],
},
initialValue: ["zhejiang", "hangzhou", "xihu"],
colProps: { span: 8 },
},
{
name: "TimePicker",
label: "TimePicker",
component: "TimePicker",
componentProps: {
format: "HH:mm",
valueFormat: "HH:mm",
},
initialValue: dayjs("12:08", "HH:mm"),
colProps: { span: 8 },
rules: [
{
validator: async (rule, value) => {
if (!value) {
return Promise.reject("TimePicker必填");
}
return Promise.resolve();
},
},
],
},
{
name: "DatePicker",
label: "DatePicker",
component: "DatePicker",
componentProps: {
format: "YYYY-MM-DD",
valueFormat: "YYYY-MM-DD",
},
colProps: { span: 8 },
initialValue: dayjs("2021-08-08", "YYYY-MM-DD"),
},
{
name: "MonthPicker",
label: "MonthPicker",
component: "MonthPicker",
componentProps: {
valueFormat: "YYYY-MM",
},
colProps: { span: 8 },
initialValue: dayjs("2021-08", "YYYY-MM"),
},
{
name: "WeekPicker",
label: "WeekPicker",
component: "WeekPicker",
componentProps: {
valueFormat: "YYYY-MM-DD HH:mm:ss",
},
colProps: { span: 8 },
initialValue: dayjs("2021-08-01", "YYYY-MM-DD"), // 2021-08-01是21年第32周
},
{
name: "RangePicker",
label: "RangePicker",
component: "RangePicker",
componentProps: {
format: "YYYY-MM-DD",
valueFormat: "YYYY-MM-DD",
},
colProps: { span: 8 },
initialValue: [
dayjs("2021-08-01 00:00:00", "YYYY-MM-DD HH:mm:ss"),
dayjs("2021-08-08 23:59:59", "YYYY-MM-DD HH:mm:ss"),
],
},
{
name: "InputPassword",
label: "InputPassword",
component: "InputPassword",
componentProps: {},
colProps: { span: 8 },
initialValue: "123456",
},
{
name: "InputTextArea",
label: "InputTextArea",
component: "InputTextArea",
componentProps: {},
colProps: { span: 8 },
initialValue: "123456",
},
{
name: "AutoComplete",
label: "AutoComplete",
component: "AutoComplete",
componentProps: {
options: [
{ value: "Burns Bay Road" },
{ value: "Downing Street" },
{ value: "Wall Street" },
],
},
initialValue: "Burns Bay Road",
colProps: { span: 8 },
},
{
name: "ApiSelect",
label: "ApiSelect",
component: "ApiSelect",
componentProps: ({ model }) => {
return {
placeholder: "ApiSelect",
allowClear: true,
immediate: true,
params: { a: model.Select },
api: async (params) => {
console.log(params, "GET ApiSelect===========================");
return [
{ label: "测试", value: "1" },
{ label: "测试2", value: "2" },
];
},
};
},
initialValue: "1",
colProps: { span: 8 },
},
{
name: "ApiTreeSelect",
label: "ApiTreeSelect",
component: "ApiTreeSelect",
componentProps: ({ model }) => {
return {
placeholder: "请选择ApiTreeSelect",
params: { a: model.Select },
immediate: true,
api: async (params) => {
console.log(
params,
"GET ApiTreeSelect==========================="
);
return [
{
value: "parent 1",
title: "parent 1",
children: [
{
value: "parent 1-0",
title: "parent 1-0",
children: [
{
value: "leaf1",
title: "leaf1",
},
{
value: "leaf2",
title: "leaf2",
},
],
},
{
value: "parent 1-1",
title: "parent 1-1",
children: [
{
value: "leaf3",
title: <b style={{ color: "#08c" }}>leaf3</b>,
},
],
},
],
},
];
},
};
},
initialValue: "leaf3",
colProps: { span: 8 },
rules: [
{
required: true,
message: "ApiTreeSelect必填",
},
],
},
{
name: "ApiTransfer",
label: "ApiTransfer",
component: "ApiTransfer",
valuePropName: "targetKeys",
initialValue: ["1"],
componentProps: ({ model }) => {
return {
params: { a: model.Select },
api: async (params) => {
// console.log(params, "GET ApiTransfer===========================");
return [
{
key: "1",
title: "标题1",
},
{
key: "2",
title: "标题2",
},
];
},
render: (item) => item.title,
};
},
colProps: { span: 8 },
rules: [
{
required: true,
type: "array",
message: "ApiTransfer必填",
},
],
},
{
name: "ApiAutoComplete",
label: "ApiAutoComplete",
component: "ApiAutoComplete",
componentProps: ({ model }) => {
return {
params: { a: model.Select },
immediate: true,
api: async (params) => {
console.log(
params,
"GET ApiAutoComplete==========================="
);
return [
{ value: "Burns Bay Road" },
{ value: "Downing Street" },
{ value: "Wall Street" },
];
},
};
},
initialValue: "Burns Bay Road",
colProps: { span: 8 },
},
{
name: "Upload",
label: "Upload",
component: "Upload",
componentProps: {
children: "上传",
showUploadList: {},
listType: "picture-card",
beforeUpload(file) {
return false;
},
onChange(info) {
const { file, fileList } = info;
const { status } = file;
switch (status) {
case "removed": {
setFieldsValue({
Upload: fileList,
});
break;
}
default: {
// 上传(此处由于没有上传服务器,默认是假上传,默认都是成功)
setFieldsValue({
Upload: [
{
uid: "-1",
name: "image.png",
status: "done",
url: "https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png",
},
],
});
}
}
},
},
colProps: { span: 8 },
valuePropName: "fileList",
initialValue: [],
rules: [
{
validator: async (rule, value) => {
console.log("validate=================", value);
if (value && value.length === 0) {
return Promise.reject("请上传文件");
}
return Promise.resolve();
},
},
],
},
{
name: "AutoUpload",
label: "AutoUpload",
component: "AutoUpload",
componentProps: {
/**
* @description 上传服务器接口,需要返回:
* type IFileList = Array<{
* uid: string;
* url: string;
* status: string;
* name: string;
* }>
*/
// api: async (params) => {
// /** 此处只是模拟上传服务器的操作 */
// return [
// {
// uid: `${+new Date()}${Math.random()}`,
// name: "image.png",
// status: "done",
// url: "https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png",
// },
// ];
// },
maxSize: 1, // 文件最大限制
maxCount: 2, // 文件最大数量
/**
* @description 表单获取到的类型
* "String"(默认,配合api使用) | "String[]"(配合api使用) | "File[]" | "FileList"(配合api使用)
* String时如果上传多文件,则返回字符串,拼接 initialValue:字符串
* String[]时如果上传多文件,则返回数组 initialValue:数组
* File[]时如果上传多文件,则返回数组 initialValue:数组
* FileList时如果上传多文件,则返回数组 initialValue:数组
*/
returnType: "File[]",
onChange(val) {
console.log("AutoUpload onChange========================", val);
},
},
colProps: { span: 8 },
initialValue: [],
rules: [
{
validator: async (rule, value) => {
console.log("validate=================", value);
if (!value.length) {
return Promise.reject("请上传文件");
}
return Promise.resolve();
},
},
],
},
{
name: "Button",
label: "Button",
component: "Button",
componentProps: {
children: "Button",
onClick: async () => {
// console.log(reactFormRef.current?.getFieldsValue(true));
// console.log(reactFormRef.current?.setFieldsValue({ Input: "123" }));
// console.log(reactFormRef.current?.getFieldsValue(["Input"]));
// console.log(await reactFormRef.current?.resetFields());
// console.log(await reactFormRef.current?.validator());
console.log(getFieldsValue(true));
console.log(
setFieldsValue({
Input: "Input test",
render: 23,
InputNumber: 21,
ApiSelect: "2",
Select: null,
Transfer: [],
ApiTransfer: [],
ApiTreeSelect: null,
TreeSelect: null,
Switch: false,
Radio: false,
RadioGroup: "b",
RadioButtonGroup: "b",
Checkbox: false,
CheckboxGroup: ["a"],
Cascader: [],
TimePicker: "2021-08-01 03:59:59",
DatePicker: "2021-08-01",
MonthPicker: "2021-09",
WeekPicker: "2021-09-02 00:00:00",
RangePicker: ["2021-08-02", "2021-08-07"],
InputPassword: "12345678",
InputTextArea: "123456789",
AutoComplete: "Burns Bay Road Test",
ApiAutoComplete: "Burns Bay Road Test",
Upload: [],
AutoUpload: [],
})
);
// console.log(getFieldsValue(["RangePicker"]));
// console.log(await resetFields());
// console.log(await validator());
},
},
colProps: { span: 8 },
},
{
name: "ResetButton",
label: "ResetButton",
component: "Button",
componentProps: {
children: "ResetButton",
onClick: async () => {
console.log(await resetFields());
},
},
colProps: { span: 8 },
},
{
name: "ValidateButton",
label: "ValidateButton",
component: "Button",
componentProps: {
children: "ValidateButton",
onClick: async () => {
console.log(await validator());
},
},
colProps: { span: 8 },
},
],
};

/**
* ==========================================
* 一、
*
* 第一种调用form组件api的方式,通过useRef
*=============================================
* */
const reactFormRef = React.useRef<IXphFormActionType>(null);

/**
* ==========================================
* 二、
*
* 第二种调用form组件api的方式,通过封装的useReactForm方法
*=============================================
* */
const [register, { setFieldsValue, getFieldsValue, resetFields, validator }] =
useXphForm();
return (
<div style={{ minWidth: "1400px" }}>
<XphForm register={register} ref={reactFormRef} {...props}></XphForm>
</div>
);
};

export default ReactApp;

案例

表单折叠

import React from "react";
import { XphForm, IXphFormProps } from "xph-crud";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
collapsible: true, // 开启折叠
collapseNum: 2, // 超出两个折叠(collapsible为true才生效)
items: [
{
name: "Input1",
label: "Input1",
component: "Input",
componentProps: {},
},
{
name: "Input2",
label: "Input2",
component: "Input",
componentProps: {},
},
{
name: "Input3",
label: "Input3",
component: "Input",
componentProps: {},
},
],
};

return <XphForm {...props}></XphForm>;
};

export default ReactApp;

布局

import React, { useState } from "react";
import { XphForm, IXphFormProps } from "xph-crud";

const ReactApp: React.FC = () => {
const [layout, seLayout] = useState<"vertical" | "horizontal">("vertical");

const props: IXphFormProps = {
layout,
colProps: { span: 4, offset: 1 },
items: [
{
name: "Input1",
label: "Input1",
component: "Input",
componentProps: {},
},
{
name: "Input2",
label: "Input2",
component: "Input",
componentProps: {},
},
{
name: "Button",
label: "切换布局",
component: "Button",
componentProps: {
onClick: () => {
seLayout(layout === "vertical" ? "horizontal" : "vertical");
},
children: "切换布局",
},
},
],
};

return <XphForm {...props}></XphForm>;
};

export default ReactApp;

栅格

import React from "react";
import { XphForm, IXphFormProps } from "xph-crud";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
colProps: { span: 4 },
items: [
{
name: "Input1",
label: "Input1",
component: "Input",
componentProps: {},
},
{
name: "Input2",
label: "Input2",
component: "Input",
componentProps: {},
colProps: {
span: 20, // 优先级高于表单的colProps
},
},
],
};

return <XphForm {...props}></XphForm>;
};

export default ReactApp;

尺寸

import React, { useState } from "react";
import { XphForm, IXphFormProps } from "xph-crud";
import { Radio, Divider } from "antd";

const ReactApp: React.FC = () => {
const [size, setSize] = useState<"small" | "middle" | "large">("small");

const props: IXphFormProps = {
colProps: { span: 11, offset: 1 },
labelCol: { style: { width: "100px" } },
labelAlign: "right",
size,
items: [
{
name: "Input",
label: "Input",
component: "Input",
componentProps: {},
},
{
name: "Select",
label: "Select",
component: "Select",
componentProps: {
options: [
{ label: "测试", value: "1" },
{ label: "测试2", value: "2" },
],
},
},
{
name: "InputNumber",
label: "InputNumber",
component: "InputNumber",
componentProps: {},
},
],
};

const onChange = (e) => {
setSize(e.target.value);
};

return (
<div>
<Radio.Group
options={[
{
label: "Small",
value: "small",
},
{
label: "Middle",
value: "middle",
},
{
label: "Large",
value: "large",
},
]}
onChange={onChange}
value={size}
optionType="button"
/>
<Divider />
<XphForm {...props}></XphForm>
</div>
);
};

export default ReactApp;

禁用

import React, { useState } from "react";
import { XphForm, IXphFormProps } from "xph-crud";
import { Radio, Divider } from "antd";

const ReactApp: React.FC = () => {
const [disabled, setDisabled] = useState<boolean>(false);

const props: IXphFormProps = {
colProps: { span: 4, offset: 1 },
disabled,
items: [
{
name: "Input1",
label: "Input1",
component: "Input",
componentProps: {},
},
{
name: "InputNumber",
label: "InputNumber",
component: "InputNumber",
componentProps: {
onBlur: (e) => {
console.log(e);
},
onChange: (e) => {
console.log(e);
},
},
initialValue: 2,
},
],
};

const onChange = (e) => {
setDisabled(e.target.value);
};

return (
<div>
<Radio.Group
options={[
{
label: "禁用",
value: true,
},
{
label: "不禁用",
value: false,
},
]}
onChange={onChange}
value={disabled}
optionType="button"
/>
<Divider />
<XphForm {...props}></XphForm>
</div>
);
};

export default ReactApp;

自定义操作组

import React from "react";
import { XphForm, IXphFormProps, useXphForm } from "xph-crud";
import { Flex, Button } from "antd";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
colProps: { span: 11, offset: 1 },
labelCol: { style: { width: "100px" } },
labelAlign: "right",
items: [
{
name: "Input",
label: "Input",
component: "Input",
required: true,
componentProps: {},
},
{
name: "Select",
label: "Select",
component: "Select",
componentProps: {
options: [
{ label: "测试", value: "1" },
{ label: "测试2", value: "2" },
],
},
},
{
name: "InputNumber",
label: "InputNumber",
component: "InputNumber",
componentProps: {},
},
],
renderActions: () => {
return (
<div style={{ width: "100%" }}>
<Flex gap={"small"} justify={"flex-end"}>
<Button
type="primary"
onClick={() => console.log(getFieldsValue())}
>
查询
</Button>
<Button onClick={() => resetFields()}>重置</Button>
</Flex>
</div>
);
},
};

const [register, { getFieldsValue, resetFields }] = useXphForm();

return <XphForm register={register} {...props}></XphForm>;
};

export default ReactApp;

表单项禁用

Select
import React, { useState } from "react";
import { XphForm, IXphFormProps } from "xph-crud";
import { Radio, Divider } from "antd";

const ReactApp: React.FC = () => {
const [disabled, setDisabled] = useState<boolean>(false);

const props: IXphFormProps = {
colProps: { span: 11, offset: 1 },
labelCol: { style: { width: "100px" } },
items: [
{
name: "Input",
label: "Input",
component: "Input",
componentProps: {
placeholder: "Input有值时禁用Select",
},
},
{
name: "Select",
label: "Select",
component: "Select",
componentProps: {
allowClear: true,
placeholder: "Select",
options: [
{ label: "测试", value: "1" },
{ label: "测试2", value: "2" },
],
},
disabled: ({ model }) => {
return disabled || model.Input;
},
},
{
name: "InputNumber",
label: "InputNumber",
component: "InputNumber",
componentProps: {
placeholder: "禁用",
},
disabled: true,
},
],
};

const onChange = (e) => {
setDisabled(e.target.value);
};

return (
<div>
<Radio.Group
options={[
{
label: "禁用Select",
value: true,
},
{
label: "不禁用Select",
value: false,
},
]}
onChange={onChange}
value={disabled}
optionType="button"
/>
<Divider />
<XphForm {...props}></XphForm>
</div>
);
};

export default ReactApp;

默认值

测试
import React from "react";
import { XphForm, IXphFormProps } from "xph-crud";
import dayjs from "dayjs";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
items: [
{
name: "Input",
label: "Input",
component: "Input",
componentProps: {},
initialValue: "Input",
},
{
name: "Select",
label: "Select",
component: "Select",
componentProps: {
allowClear: true,
placeholder: "Select",
options: [
{ label: "测试", value: "1" },
{ label: "测试2", value: "2" },
],
},
initialValue: "1",
},
{
name: "Switch",
label: "Switch",
component: "Switch",
componentProps: {},
initialValue: true,
/** 定义子节点的值的属性,如 Switch、Checkbox 的是 checked */
valuePropName: "checked",
},
{
name: "DatePicker",
label: "DatePicker",
component: "DatePicker",
componentProps: {
format: "YYYY-MM-DD",
valueFormat: "YYYY-MM-DD",
},
initialValue: dayjs("2021-08-08", "YYYY-MM-DD"),
},
],
};

return <XphForm {...props}></XphForm>;
};

export default ReactApp;

隐藏表单项(相当于 display: none)

测试
import React from "react";
import { XphForm, IXphFormProps } from "xph-crud";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
items: [
{
name: "Input",
label: "Input",
component: "Input",
required: true,
componentProps: {},
},
{
name: "Select",
label: "Select",
component: "Select",
componentProps: {
allowClear: true,
placeholder: "Select",
options: [
{ label: "测试", value: "1" },
{ label: "测试2", value: "2" },
],
},
initialValue: "1",
show: ({ model }) => {
// Input有值才显示(相当于display:none)
return model.Input;
},
},
],
};

return <XphForm {...props}></XphForm>;
};

export default ReactApp;

隐藏表单项(会新增删除节点)

import React from "react";
import { XphForm, IXphFormProps } from "xph-crud";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
items: [
{
name: "Input",
label: "Input",
component: "Input",
required: true,
componentProps: {},
},
{
name: "Select",
label: "Select",
component: "Select",
componentProps: {
allowClear: true,
placeholder: "Select",
options: [
{ label: "测试", value: "1" },
{ label: "测试2", value: "2" },
],
},
initialValue: "1",
ifShow: ({ model }) => {
// Input有值才显示(会新增或删除节点)
return model.Input;
},
},
],
};

return <XphForm {...props}></XphForm>;
};

export default ReactApp;

校验规则

1 item
  • 标题2
1 item
  • 标题1
import React from "react";
import { XphForm, IXphFormProps } from "xph-crud";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
items: [
{
name: "Input",
label: "Input",
component: "Input",
required: true,
componentProps: {},
},
{
name: "Transfer",
label: "Transfer",
component: "Transfer",
valuePropName: "targetKeys",
initialValue: ["1"],
componentProps: {
dataSource: [
{
key: "1",
title: "标题1",
},
{
key: "2",
title: "标题2",
},
],
render: (item) => item.title,
},
rules: [
{
required: true,
type: "array",
message: "Transfer必填",
},
],
},
{
name: "TimePicker",
label: "TimePicker",
component: "TimePicker",
componentProps: {
format: "HH:mm",
valueFormat: "HH:mm",
},
rules: [
{
validator: async (rule, value) => {
if (!value) {
return Promise.reject("TimePicker必填");
}
return Promise.resolve();
},
},
],
},
],
};

return <XphForm {...props}></XphForm>;
};

export default ReactApp;

强制换行

Select
import React, { useState } from "react";
import { XphForm, IXphFormProps } from "xph-crud";
import { Radio, Divider } from "antd";

const ReactApp: React.FC = () => {
const [forceRow, setForceRow] = useState<boolean>(false);

const props: IXphFormProps = {
colProps: { span: 11, offset: 1 },
labelCol: { style: { width: "100px" } },
items: [
{
name: "Input",
label: "Input",
component: "Input",
componentProps: {},
},
{
name: "Select",
label: "Select",
component: "Select",
componentProps: {
allowClear: true,
placeholder: "Select",
options: [
{ label: "测试", value: "1" },
{ label: "测试2", value: "2" },
],
},
forceRow,
},
{
name: "InputNumber",
label: "InputNumber",
component: "InputNumber",
componentProps: {},
},
],
};

const onChange = (e) => {
setForceRow(e.target.value);
};

return (
<div>
<Radio.Group
options={[
{
label: "Select换行",
value: true,
},
{
label: "Select不换行",
value: false,
},
]}
onChange={onChange}
value={forceRow}
optionType="button"
/>
<Divider />
<XphForm {...props}></XphForm>
</div>
);
};

export default ReactApp;

自定义表单项组件

2
import React from "react";
import { XphForm, IXphFormProps } from "xph-crud";
import { InputNumber } from "antd";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
items: [
{
name: "render",
label: "render",
render: ({ model, disabled, name, methods, componentProps }) => (
<div>
<InputNumber
disabled={disabled}
value={model[name]}
onChange={(e) => methods.setFieldsValue({ [name]: e })}
{...componentProps}
/>
<span style={{ marginLeft: 8, fontWeight: "bold", color: "red" }}>
{model[name]}
</span>
</div>
),
componentProps: {
placeholder: "render",
},
initialValue: 2,
rules: [
{
required: true,
message: "render必填",
},
],
},
],
};

return <XphForm {...props}></XphForm>;
};

export default ReactApp;

表单项组件属性

https://.com
import React from "react";
import { XphForm, IXphFormProps } from "xph-crud";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
items: [
{
name: "Input",
label: "Input",
component: "Input",
/** 此处的componentProps中的属性,会直接透传给根部的表单组件 */
/** 若映射的表单组件是antd的组件,会完全继承antd组件的属性 */
componentProps: {
addonAfter: ".com",
addonBefore: "https://",
maxLength: 20,
placeholder: "三级域名.二级域名",
allowClear: true,
/** 更多属性请看 https://ant.design/index-cn ... */
},
rules: [
{
required: true,
message: "请输入三级域名.二级域名",
},
],
},
],
};

return <XphForm {...props}></XphForm>;
};

export default ReactApp;

表单项组件映射

组件映射

注册

import React from "react";
import { XphForm, IXphFormProps, useXphForm } from "xph-crud";
import { Divider, Flex, Button } from "antd";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
colProps: { span: 11, offset: 1 },
labelCol: { style: { width: "100px" } },
labelAlign: "right",
items: [
{
name: "Input",
label: "Input",
component: "Input",
required: true,
componentProps: {},
},
{
name: "Select",
label: "Select",
component: "Select",
componentProps: {
options: [
{ label: "测试", value: "1" },
{ label: "测试2", value: "2" },
],
},
},
{
name: "InputNumber",
label: "InputNumber",
component: "InputNumber",
componentProps: {},
},
],
};

const [register, { setFieldsValue, getFieldsValue, resetFields, validator }] =
useXphForm();

return (
<div>
<Flex gap={"small"}>
<Button
onClick={() =>
setFieldsValue({ Input: "Input", Select: "1", InputNumber: 0 })
}
>
设置值
</Button>
<Button onClick={() => console.log(getFieldsValue())}>获取值</Button>
<Button onClick={() => validator()}>校验</Button>
<Button onClick={() => resetFields()}>重置</Button>
</Flex>
<Divider />
<XphForm register={register} {...props}></XphForm>
</div>
);
};

export default ReactApp;

instance

import React from "react";
import { XphForm, IXphFormProps, IXphFormActionType } from "xph-crud";
import { Divider, Flex, Button } from "antd";

const ReactApp: React.FC = () => {
const props: IXphFormProps = {
colProps: { span: 11, offset: 1 },
labelCol: { style: { width: "100px" } },
labelAlign: "right",
items: [
{
name: "Input",
label: "Input",
component: "Input",
required: true,
componentProps: {},
},
{
name: "Select",
label: "Select",
component: "Select",
componentProps: {
options: [
{ label: "测试", value: "1" },
{ label: "测试2", value: "2" },
],
},
},
{
name: "InputNumber",
label: "InputNumber",
component: "InputNumber",
componentProps: {},
},
],
};

const reactFormRef = React.useRef<IXphFormActionType>(null);

return (
<div>
<Flex gap={"small"}>
<Button
onClick={() =>
reactFormRef.current?.setFieldsValue({
Input: "Input",
Select: "1",
InputNumber: 0,
})
}
>
设置值
</Button>
<Button
onClick={() => console.log(reactFormRef.current?.getFieldsValue())}
>
获取值
</Button>
<Button onClick={() => reactFormRef.current?.validator()}>校验</Button>
<Button onClick={() => reactFormRef.current?.resetFields()}>
重置
</Button>
</Flex>
<Divider />
<XphForm ref={reactFormRef} {...props}></XphForm>
</div>
);
};

export default ReactApp;

API

Form API

FormInstance API

在 CodeSandbox 尝试

Edit XiaoPiHong/xph-crud/codesandbox