Based on React, ANTD V4 with ANTD-form-Render can easily implement various forms
Try: github.com/leonwgc/ant…
- Row by column layout
import React from 'react';
import styled from 'styled-components';
import { Form, Button, Space, Input, message } from 'antd';
import FormRender from 'antd-form-render';
const StyledOneRow = styled.div` width: 400px; `;
const OneCol = () = > {
const [form] = Form.useForm();
const oneRowLayout = [
{
type: Input,
label: 'Phone number'.placeholder: 'Please enter'.name: 'tel'.elProps: {
maxLength: 11,},itemProps: {
rules: [{required: true.message: 'Please enter' },
{ pattern: /^1\d{10}$/, message: 'Phone number must be 11 digits'},],},}, {type: Input.Password,
label: 'password'.placeholder: 'Please enter'.name: 'pwd'.itemProps: {
rules: [{ required: true.message: 'Please enter'}],}}, {type: Input.Password,
label: 'Confirm password'.placeholder: 'Please enter'.name: 'confirmPwd'.itemProps: {
rules: [{required: true.message: 'Please enter' },
({ getFieldValue }) = > ({
validator(_, value) {
if(! value || getFieldValue('pwd') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('Two different passwords')); },}),],},}, {type: Input.TextArea,
name: 'desc'.label: 'introduction'.elProps: {
placeholder: 'Personal Profile'.rows: 4,}}, {// Custom render
render() {
return (
<Form.Item wrapperCol={{ offset: 6}} >
<Space>
<Button htmlType="submit" type="primary">determine</Button>
<Button htmlType="reset">reset</Button>
</Space>
</Form.Item>); }},];return (
<StyledOneRow>
<Form
form={form}
labelCol={{ span: 6 }}
onFinish={(v)= > {
message.success(JSON.stringify(v));
}}
>
<FormRender layoutData={oneRowLayout}></FormRender>
</Form>
</StyledOneRow>
);
};
export default OneCol;
Copy the code
- One-row multi-column layout
import React, { useState } from 'react';
import styled from 'styled-components';
import { Input, Radio, Form } from 'antd';
import FormRender from 'antd-form-render';
const StyledOneRow = styled.div` width: 800px; `;
const MultipleCols = () = > {
const layout = [];
const [cols, setCols] = useState(4);
for (let i = 0; i < 11; i++) {
layout.push({
type: Input,
label: ` input box${i + 1}`.placeholder: 'Please enter'.name: `name${i}`}); }return (
<StyledOneRow>
<Form layout="vertical">
<div style={{ margin: '16px 0' }}>
<Radio.Group
onChange={(e)= > setCols(Number(e.target.value))}
optionType="button"
value={cols}
>
<Radio value={1}>Row 1 column 1</Radio>
<Radio value={2}>1 row 2 column</Radio>
<Radio value={3}>1 line 3 columns</Radio>
<Radio value={4}>1 line 4 columns</Radio>
</Radio.Group>
</div>
<FormRender layoutData={layout} cols={cols}></FormRender>
</Form>
<FormRender layoutData={layout}></FormRender>
</StyledOneRow>
);
};
export default MultipleCols;
Copy the code
- Equal spacing (often used for searches on list pages, etc.)
import React, { useState } from 'react';
import styled from 'styled-components';
import { Input, Radio, Form } from 'antd';
import { FormSpaceRender } from 'antd-form-render';
const StyledOneRow = styled.div` width: 1000px; `;
const SpaceLayout = () = > {
const layout = [];
const [space, setSpace] = useState(8);
for (let i = 0; i < 3; i++) {
layout.push({
type: Input,
label: ` input box${i + 1}`.placeholder: 'Please enter'.name: `name${i}`}); }return (
<StyledOneRow>
<Form layout="horizontal">
<div style={{ margin: '16px 0' }}>
<Radio.Group
onChange={(e)= > setSpace(Number(e.target.value))}
optionType="button"
value={space}
>
<Radio value={8}>8px</Radio>
<Radio value={16}>16px</Radio>
<Radio value={24}>24px</Radio>
<Radio value={32}>32px</Radio>
</Radio.Group>
</div>
<FormSpaceRender layoutData={layout} size={space}></FormSpaceRender>
</Form>
</StyledOneRow>
);
};
export default SpaceLayout;
Copy the code
4. Form linkage
import React, { useState } from 'react';
import styled from 'styled-components';
import { Form, Button, Radio, message } from 'antd';
import FormRender from 'antd-form-render';
const StyledOneRow = styled.div` width: 600px; `;
const StyledP = styled.p` padding: 10px; `;
const OneColWithDynamicControl = () = > {
const [form] = Form.useForm();
const [form1] = Form.useForm();
// To synchronize form state
const [data, setData] = useState({});
const layout = [
{
type: Radio.Group,
label: 'gender'.name: 'gender'.elProps: {
options: [{label: 'male'.value: 'the boys' },
{ label: 'woman'.value: 'the girl'},],},}, {type: 'div'.label: 'are you'.elProps: {
children: data.gender || 'Not selected',}}, {type: Button,
elProps: {
htmlType: 'submit'.type: 'primary'.children: 'sure',},itemProps: {
wrapperCol: { offset: 6}},},];// Form linkage based on ANTd, dependency
const layout1 = [
{
type: Radio.Group,
label: 'gender'.name: 'gender'.elProps: {
options: [{label: 'male'.value: 'the boys' },
{ label: 'woman'.value: 'the girl'},],},}, {render() {
return (
<Form.Item label="Are you" dependencies={['gender']} >{() => { const gender = form1.getFieldValue('gender'); Return gender | | 'no choice'; }}</Form.Item>); }, {},type: Button,
elProps: {
htmlType: 'submit'.type: 'primary'.children: 'sure',},itemProps: {
wrapperCol: { offset: 6}},},];return (
<StyledOneRow>
<StyledP>1. Define onValuesChange to synchronize the state to state, triggering rerendering to implement form linkage</StyledP>
<Form
form={form}
onValuesChange={(v)= >{ setData((p) => ({ ... p, ... v })); }} labelCol={{ span: 6 }} onFinish={(v) => { message.success(JSON.stringify(v)); }} ><FormRender layoutData={layout}></FormRender>
</Form>
<StyledP>2. Implement Form linkage with form. Item dependencies and custom render</StyledP>
<Form
form={form1}
labelCol={{ span: 6 }}
onFinish={(v)= > {
message.success(JSON.stringify(v));
}}
>
<FormRender layoutData={layout1}></FormRender>
</Form>
</StyledOneRow>
);
};
export default OneColWithDynamicControl;
Copy the code