嵌套动态表单 Antd
Nested Dynamic Forms Antd
所以我将这个动态表单放在一起(酒店房间),您还可以在其中创建动态表单(房间床)。它有效,我可以添加房间和床位,并且对象数组在 console.log (onSubmit) 中返回。
codesandbox: https://codesandbox.io/s/charming-hermann-nzpbu?file=/src/App.js
问题:
如果你添加 room1 和 room2 然后删除 room1,数组的长度保持为 2,现在它有“未定义的床”,并且当你向其他房间添加床时它会不断增长!帮我解决这个问题:
当您按下下一步(在控制台中)时返回对象。正如您所看到的,数组没有减去,但当我删除房间时它也没有定义床:
listingDescription: "ss"
listingName: "aa"
pricePerMonth: 1
rooms: Array(2)
0: {roomname: "room2", beds: Array(1)}
1: {beds: undefined}
主要形式:
import React from 'react';
import { useStateMachine } from 'little-state-machine';
import { useForm } from 'react-hook-form';
import { Row, Col, Input, InputNumber, Button, Form, Space } from 'antd';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import FormControl from 'components/UI/FormControl/FormControl';
import AddListingAction from './AddListingAction';
import { FormHeader, Title, FormContent, FormAction } from './AddListing.style';
import BedForm from "./BedForm";
const BasicInformation = ({ setStep }) => {
const { action, state } = useStateMachine(AddListingAction);
const { control, register, errors, setValue, handleSubmit } = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<Form onFinish={(e) => onSubmit(e)}>
<FormContent>
<FormHeader>
<Title>Step 1: Start with the basics</Title>
</FormHeader>
<Row gutter={30}>
<Col sm={12}>
<FormControl
label='Listing Name'
htmlFor='listingName'
error={errors.listingName && <span>This field is required!</span>}
>
<Form.Item
id='listingName'
name='listingName'
defaultValue={state.data.listingName}
control={control}
placeholder='Write a name for your listing here'
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
</FormControl>
</Col>
<Col sm={12}>
<FormControl
label='Price Per Night (USD)'
htmlFor='pricePerMonth'
>
<Form.Item
name='pricePerMonth'
id='pricePerMonth'
defaultValue={state.data.pricePerMonth}
control={control}
placeholder='00.00'
rules={[
{
required: true,
pattern: /^[0-9]*$/,
},
]}
>
<InputNumber min={0} />
</Form.Item>
</FormControl>
</Col>
</Row>
<FormControl
label='Listing Description'
htmlFor='listingDescription'
error={
errors.listingDescription && <span>This field is required!</span>
}
>
<Form.Item
id='listingDescription'
name='listingDescription'
defaultValue={state.data.listingDescription}
control={control}
placeholder='Tell people about your listing, rooms, location & amenities'
rules={[
{
required: true,
},
]}
>
<Input.TextArea rows={5} />
</Form.Item>
</FormControl>
<FormControl
label='How many rooms does your listing have?'
error={errors.guest && <span>This field is required!</span>}
>
{/* This is the Dynamic room Adder */}
<Form.List name='rooms'>
{(fields, { add, remove }) => {
return (
<div>
{fields.map((field) => (
<Space
key={field.key}
style={{ display: 'flex', marginBottom: 8 }}
align='start'
>
<Form.Item
{...field}
name={[field.name, 'roomname']}
fieldKey={[field.fieldKey, 'roomname']}
rules={[
{ required: true, message: 'Missing room name' },
]}
>
<Input placeholder='Room Name' />
</Form.Item>
{/* This is the Dynamic bed Adder */}
<Form.Item>
<BedForm fieldKey={field.key} />
</Form.Item>
<MinusCircleOutlined
onClick={() => {
remove(field.name);
console.log(field)
}}
/>
</Space>
))}
<Button
type='dashed'
onClick={() => {
add();
}}
block
>
<PlusOutlined /> Add room
</Button>
</div>
);
}}
</Form.List>
</FormControl>
</FormContent>
<FormAction>
<div className='inner-wrapper'>
<Button type='primary' htmlType='submit'>
Next
</Button>
</div>
</FormAction>
</Form>
);
};
export default BasicInformation;
儿童形态 (BedForm)
import React from 'react';
import { Form, Input, Button, Space, Select } from 'antd';
import { PlusOutlined, MinusCircleOutlined } from '@ant-design/icons';
const { Option } = Select;
//@ATT:this was created to make nested dynamic elements! This is hard!
const BedForm = (props) => {
return (
<>
<Form.List name={[props.fieldKey, 'beds']}>
{(beds, { add, remove }) => {
return (
<div>
{beds.map((bed, index2) => (
<Space
key={bed.key}
style={{ display: 'flex', marginBottom: 8 }}
align='start'
>
<Form.Item
// name={"aar"}
{...bed}
name={[bed.name, 'bed']}
fieldKey={[bed.fieldKey, 'bed']}
key={index2}
// noStyle
rules={[
{
required: true, message: 'Beds Missing'
},
]}
>
<Select placeholder="Please select a Bed Type">
<Option value='double'>Double(2 person)</Option>
<Option value='single'>Single (1 person)</Option>
<Option value='king'>King Size (2 person)</Option>
<Option value='queen'>Queen Size (2 person)</Option>
<Option value='Bunk'>Bunk Bed (1 person)</Option>
<Option value='sofa'>Sofa Bed (1 person)</Option>
</Select>
</Form.Item>
{/* <MinusCircleOutlined
onClick={() => {
remove(bed.name);
}}
/> */}
</Space>
))}
<Form.Item>
<Button
type='dashed'
onClick={() => {
add();
}}
>
<PlusOutlined /> Add Bed
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</>
);
};
export default BedForm;
传递 field.name 而不是 field.key 或 App.js
上的 fieldKey
https://codesandbox.io/s/trusting-wind-elsdz?file=/src/App.js
所以我将这个动态表单放在一起(酒店房间),您还可以在其中创建动态表单(房间床)。它有效,我可以添加房间和床位,并且对象数组在 console.log (onSubmit) 中返回。
codesandbox: https://codesandbox.io/s/charming-hermann-nzpbu?file=/src/App.js
问题: 如果你添加 room1 和 room2 然后删除 room1,数组的长度保持为 2,现在它有“未定义的床”,并且当你向其他房间添加床时它会不断增长!帮我解决这个问题:
当您按下下一步(在控制台中)时返回对象。正如您所看到的,数组没有减去,但当我删除房间时它也没有定义床:
listingDescription: "ss"
listingName: "aa"
pricePerMonth: 1
rooms: Array(2)
0: {roomname: "room2", beds: Array(1)}
1: {beds: undefined}
主要形式:
import React from 'react';
import { useStateMachine } from 'little-state-machine';
import { useForm } from 'react-hook-form';
import { Row, Col, Input, InputNumber, Button, Form, Space } from 'antd';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import FormControl from 'components/UI/FormControl/FormControl';
import AddListingAction from './AddListingAction';
import { FormHeader, Title, FormContent, FormAction } from './AddListing.style';
import BedForm from "./BedForm";
const BasicInformation = ({ setStep }) => {
const { action, state } = useStateMachine(AddListingAction);
const { control, register, errors, setValue, handleSubmit } = useForm();
const onSubmit = (data) => {
console.log(data);
};
return (
<Form onFinish={(e) => onSubmit(e)}>
<FormContent>
<FormHeader>
<Title>Step 1: Start with the basics</Title>
</FormHeader>
<Row gutter={30}>
<Col sm={12}>
<FormControl
label='Listing Name'
htmlFor='listingName'
error={errors.listingName && <span>This field is required!</span>}
>
<Form.Item
id='listingName'
name='listingName'
defaultValue={state.data.listingName}
control={control}
placeholder='Write a name for your listing here'
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
</FormControl>
</Col>
<Col sm={12}>
<FormControl
label='Price Per Night (USD)'
htmlFor='pricePerMonth'
>
<Form.Item
name='pricePerMonth'
id='pricePerMonth'
defaultValue={state.data.pricePerMonth}
control={control}
placeholder='00.00'
rules={[
{
required: true,
pattern: /^[0-9]*$/,
},
]}
>
<InputNumber min={0} />
</Form.Item>
</FormControl>
</Col>
</Row>
<FormControl
label='Listing Description'
htmlFor='listingDescription'
error={
errors.listingDescription && <span>This field is required!</span>
}
>
<Form.Item
id='listingDescription'
name='listingDescription'
defaultValue={state.data.listingDescription}
control={control}
placeholder='Tell people about your listing, rooms, location & amenities'
rules={[
{
required: true,
},
]}
>
<Input.TextArea rows={5} />
</Form.Item>
</FormControl>
<FormControl
label='How many rooms does your listing have?'
error={errors.guest && <span>This field is required!</span>}
>
{/* This is the Dynamic room Adder */}
<Form.List name='rooms'>
{(fields, { add, remove }) => {
return (
<div>
{fields.map((field) => (
<Space
key={field.key}
style={{ display: 'flex', marginBottom: 8 }}
align='start'
>
<Form.Item
{...field}
name={[field.name, 'roomname']}
fieldKey={[field.fieldKey, 'roomname']}
rules={[
{ required: true, message: 'Missing room name' },
]}
>
<Input placeholder='Room Name' />
</Form.Item>
{/* This is the Dynamic bed Adder */}
<Form.Item>
<BedForm fieldKey={field.key} />
</Form.Item>
<MinusCircleOutlined
onClick={() => {
remove(field.name);
console.log(field)
}}
/>
</Space>
))}
<Button
type='dashed'
onClick={() => {
add();
}}
block
>
<PlusOutlined /> Add room
</Button>
</div>
);
}}
</Form.List>
</FormControl>
</FormContent>
<FormAction>
<div className='inner-wrapper'>
<Button type='primary' htmlType='submit'>
Next
</Button>
</div>
</FormAction>
</Form>
);
};
export default BasicInformation;
儿童形态 (BedForm)
import React from 'react';
import { Form, Input, Button, Space, Select } from 'antd';
import { PlusOutlined, MinusCircleOutlined } from '@ant-design/icons';
const { Option } = Select;
//@ATT:this was created to make nested dynamic elements! This is hard!
const BedForm = (props) => {
return (
<>
<Form.List name={[props.fieldKey, 'beds']}>
{(beds, { add, remove }) => {
return (
<div>
{beds.map((bed, index2) => (
<Space
key={bed.key}
style={{ display: 'flex', marginBottom: 8 }}
align='start'
>
<Form.Item
// name={"aar"}
{...bed}
name={[bed.name, 'bed']}
fieldKey={[bed.fieldKey, 'bed']}
key={index2}
// noStyle
rules={[
{
required: true, message: 'Beds Missing'
},
]}
>
<Select placeholder="Please select a Bed Type">
<Option value='double'>Double(2 person)</Option>
<Option value='single'>Single (1 person)</Option>
<Option value='king'>King Size (2 person)</Option>
<Option value='queen'>Queen Size (2 person)</Option>
<Option value='Bunk'>Bunk Bed (1 person)</Option>
<Option value='sofa'>Sofa Bed (1 person)</Option>
</Select>
</Form.Item>
{/* <MinusCircleOutlined
onClick={() => {
remove(bed.name);
}}
/> */}
</Space>
))}
<Form.Item>
<Button
type='dashed'
onClick={() => {
add();
}}
>
<PlusOutlined /> Add Bed
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
</>
);
};
export default BedForm;
传递 field.name 而不是 field.key 或 App.js
上的 fieldKeyhttps://codesandbox.io/s/trusting-wind-elsdz?file=/src/App.js