Based on React, ANTD V4 with ANTD-form-Render can easily implement various forms

Try: github.com/leonwgc/ant…

  1. 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
  1. 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
  1. 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