So i put together this Dynamic Form Below (Hotel Rooms) and inside it you can also create dynamic forms (Room Beds). It works, i can add rooms & Beds and the object array is returned in the console.log (onSubmit).
codesandbox: https://codesandbox.io/s/charming-hermann-nzpbu?file=/src/App.js
Issue:
If you add room1 and room2 and then delete room1, the array stays of length 2 and now it has "beds undefined" and it keeps growing when you add beds to other rooms! Help me solve this:
Object returned when you press next (in console). As you can see the array is not subtracting but it is also leaving the beds undefined when i delete a room:
listingDescription: "ss"
listingName: "aa"
pricePerMonth: 1
rooms: Array(2)
0: {roomname: "room2", beds: Array(1)}
1: {beds: undefined}
The Main Form:
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;
The Child Form (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;
Pass field.name instead of field.key or fieldKey on App.js
https://codesandbox.io/s/trusting-wind-elsdz?file=/src/App.js
Related
I have a form built with Formik containing an array of objects. When I add a second element to the form with the add-button, I get the following error:
Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.
I have made sure that initial values is defined for the the form. I use the FieldArray component from formik. If I remove the time and rate fields, so it's only the name input in each object, I don't get the error, but when I add the time and rate fields, the error occurs. The component contains the following:
const TimeItemsForm = () => {
const jiraItemsStore = useJiraItemsStore();
function jiraTimeImported(timeItemIndex: number, importedHoursTotal: number, checkedItems: CheckedTimeItems) {
// Add checked items to store
jiraItemsStore.setJiraTable(timeItemIndex, checkedItems, importedHoursTotal);
}
const TimeItemSchema = Yup.object().shape({
name: Yup.string().required('Required'),
time: Yup.number().min(0).required('Required'),
// rate: Yup.number().min(0).required('Required'),
});
const TimeItemsSchema = Yup.object().shape({
timeItems: Yup.array().of(TimeItemSchema),
})
const initialValues = {
timeItems: [
{
name: '',
time: 0,
rate: 0,
},
],
};
return (
<>
<Formik
validateOnChange={false}
initialValues={initialValues}
validationSchema={TimeItemsSchema}
onSubmit={(values) => console.log(values)}>
{({ values, errors, touched }) => (
<Form onChange={() => console.log("hs")}>
<FieldArray
name="timeItems"
render={arrayHelpers => (
<div>
{values.timeItems && values.timeItems.length > 0 ? (
values.timeItems.map((timeItem, index) => (
<React.Fragment key={index}>
<Stack gap={2}>
<Flex alignItems="end" gap={4}>
<FormControl>
<FormLabel htmlFor="timeItems[${index}].name">Name</FormLabel>
<Field as={Input} placeholder="Time Item Name" variant="filled" name={`timeItems[${index}].name`} />
</FormControl>
<FormControl>
<FormLabel htmlFor="timeItems[${index}].time">Time</FormLabel>
<InputGroup>
<Field as={Input} type="number" placeholder="0 Hours" variant="filled" name={`timeItems[${index}].time`} />
<InputRightAddon children='Hours' />
</InputGroup>
</FormControl>
<FormControl>
<FormLabel htmlFor="timeItems[${index}].rate">Rate</FormLabel>
<InputGroup>
<Field as={Input} type="number" placeholder="USD 0" variant="filled" name={`timeItems[${index}].rate`} />
<InputRightAddon children='Hours' />
</InputGroup>
</FormControl>
<Flex flexShrink="0" gap={3} direction="column">
<Heading fontWeight="normal" size="sm">Apply Taxes & Discounts</Heading>
<Flex mb={0.5} gap={4}>
<Tooltip label='Tax 1' fontSize='sm'>
<IconButton variant={true ? 'solid' : 'outline'} aria-label='Tax' icon={<TbReceipt />} />
</Tooltip>
<IconButton variant='outline' aria-label='Discount' icon={<TbDiscount />} onClick={() => arrayHelpers.insert(index, { name: "", email: "" })} />
</Flex>
</Flex>
</Flex>
<Flex py={2} gap={10} justifyContent="space-between">
<TimeItemsTable timeItemIndex={index} jiraTimeImported={jiraTimeImported} />
<Flex gap={4}>
<IconButton aria-label='Create Time Item' icon={<MinusIcon />} onClick={() => arrayHelpers.remove(index)} />
<IconButton aria-label='Create Time Item' icon={<AddIcon />} onClick={() => arrayHelpers.insert(index, { name: "", email: "" })} />
</Flex>
</Flex>
</Stack>
<Divider my={4} />
</React.Fragment>
))
) : (
<button type="button" onClick={() => arrayHelpers.push('')}>
Add a Time Item
</button>
)}
<Flex mt={6} gap={10} justifyContent="space-between">
<Button colorScheme="purple" type="submit">Save</Button>
{/* <TimeItemsStats /> */}
</Flex>
</div>
)}
/>
</Form>
)}
</Formik>
</>
)
}
Solution:
The arrayHelpers.push and arrayHelpers.insert didn't insert the values with the correct type, as seen in the code.
I have a Material-UI Select inside a nested useFieldArray. Every time I'll add the Material-UI Select and submit it to the form, whatever values that were entered in the form will not be saved and do not log in to the console. Also, I keep on having this warning when I do not have a ref anymore.
Link to codesandbox where codes are complete here: https://codesandbox.io/s/react-hook-form-usefieldarray-nested-arrays-forked-vjwbp?file=/src/nestedFieldArray.js:0-1722
Warning: Invalid value for prop refer on tag. Either remove it
from the element, or pass a string or number value to keep it in the
DOM.
Material-UI select
import { InputLabel, MenuItem, FormControl, Select } from "#mui/material";
const Size = ({ name, refer, defaultValue }) => {
return (
<FormControl fullWidth variant="filled">
<InputLabel id="Size Label">Size</InputLabel>
<Select
labelId="Size"
id="size"
name={name}
label="Product"
refer={refer}
defaultValue={defaultValue}
>
<MenuItem value="S">Small</MenuItem>
<MenuItem value="M">Medium</MenuItem>
<MenuItem value="L">Large</MenuItem>
</Select>
</FormControl>
);
};
export default Size;
I'm using the Size here:
import React from "react";
import { useFieldArray } from "react-hook-form";
import Size from "./Drop_drowns/Size";
import { TextField } from "#mui/material";
export default ({ nestIndex, control, register }) => {
const { fields, remove, append } = useFieldArray({
control,
name: `test[${nestIndex}].nestedArray`
});
return (
<div>
{fields.map((item, k) => {
return (
<div key={item.id} style={{ marginLeft: 20 }}>
<label>Colors:</label>
<Size
name={`test[${nestIndex}].nestedArray[${k}].field1`}
refer={register({ required: true })}
defaultValue={item.field1}
style={{ marginRight: "25px" }}
/>
{/* <input
name={`test[${nestIndex}].nestedArray[${k}].field1`}
ref={register({ required: true })}
defaultValue={item.field1}
style={{ marginRight: "25px" }}
/> */}
<TextField
name={`test[${nestIndex}].nestedArray[${k}].field2`}
refer={register()}
defaultValue={item.field2}
/>
<TextField
name={`test[${nestIndex}].nestedArray[${k}].field3`}
refer={register()}
defaultValue={item.field3}
/>
<button type="button" onClick={() => remove(k)}>
Delete Colors
</button>
</div>
);
})}
<button
type="button"
onClick={() =>
append({
field1: "field1",
field2: "field2"
})
}
>
Add Colors
</button>
<hr />
</div>
);
};
I have a form that should print the data in console but unfortunately I'm not able to.
I want to print data to the console when a form is submitted.
The form is not submitting don't know why. I have the code below.
I would be very grateful if you could decide.
import { Button, Grid, Paper, TextField } from "#mui/material";
import React from "react";
import { useForm } from "react-hook-form";
export default function Page2(props) {
const { handleSubmit } = useForm();
const handelInputChange = (e) => {
const { name, value } = e.target;
console.log(name, value);
};
const handleData = (data) => {
console.log("data");
};
return (
<>
<Paper
style={{ margin: "10px auto", textAlign: "center" }}
elevation={24} >
<h1 style={{ textAlign: "center" }}>Todo Application</h1>
<form onSubmit={handleSubmit(handleData)}>
<Grid
style={{ margin: "10px" }}
container
spacing={1}
direction="column" >
<Grid item xs={6}>
<TextField
name="title"
label="Title"
variant="standard"
onChange={handelInputChange} />
<TextField
name="desc"
label="Description"
variant="standard"
onChange={handelInputChange} />
<TextField
name="priority"
type="number"
label="Priority"
variant="standard"
onChange={handelInputChange} />
</Grid>
</Grid>
</form>
<button type="submit" variant="contained" color="primary">
Add
</button>
</Paper>
</>
);
}
You have wrong HTML structure. button[type=submit] should be inside <form> tag
In addition to Steve, You can use simply register function to do the work for you just supply register function in the inputRef of your MUI Form Component.
import { Button, Grid, Paper, TextField } from "#mui/material";
import React from "react";
import { useForm } from "react-hook-form";
export default function Page2(props) {
const { handleSubmit, register } = useForm();
const handelInputChange = (e) => {
const { name, value } = e.target;
console.log(name, value);
};
const handleData = (data) => {
console.log("data",data);
};
return (
<>
<Paper
style={{ margin: "10px auto", textAlign: "center" }}
elevation={24} >
<h1 style={{ textAlign: "center" }}>Todo Application</h1>
<form onSubmit={handleSubmit(handleData)}>
<Grid
style={{ margin: "10px" }}
container
spacing={1}
direction="column" >
<Grid item xs={6}>
<TextField
name="title"
label="Title"
variant="standard"
inputRef={register}
onChange={handelInputChange} />
<TextField
name="desc"
label="Description"
variant="standard"
inputRef={register}
onChange={handelInputChange} />
<TextField
name="priority"
type="number"
label="Priority"
variant="standard"
inputRef={register}
onChange={handelInputChange} />
</Grid>
</Grid>
<button type="submit" variant="contained" color="primary">
Add
</button>
</form>
</Paper>
</>
);
}
You have quite a bit of things to do in order to get this form to console.log. First, as the other poster mentioned, the submit button needs to be within the form (and you probably want to uppercase that B in "<Button" so that you're using the MUI component.
<form onSubmit={handleSubmit(handleData)}>
<Grid
style={{ margin: "10px" }}
container
spacing={1}
direction="column"
>
<Grid item xs={6}>
<TextField
name="title"
label="Title"
variant="standard"
onChange={handelInputChange}
/>
...
</Grid>
</Grid>
// Moved and renamed here
<Button type="submit" variant="contained" color="primary">
Add
</Button>
</form>
That solves your submit problem, but then you will notice that the console.log("data") will only ever contain an empty object {} -- this is because react-form-hooks needs to be given a FormProvider and made aware of the form elements in the form that it should control. To do this you need to register the component. I have added working code example on one way to complete this task.
In this example, I created a generic FormFieldController wrapper that you can use to pass in whatever just about form fields you need. (I would not use this in production code, without cleanup, as it is only meant as an example):
const FormFieldController = ({
component: Component = TextField,
name = "",
defaultValue = "",
label = "",
validation = {},
required = false,
valueProp = "value",
callbackProp = "onChange",
onChange,
...rest
}) => {
const { control } = useFormContext();
return (
<Controller
name={name}
control={control}
defaultValue={defaultValue}
rules={validation}
render={({
field: { onChange: internalOnChange, value, ref },
fieldState: { error }
}) => {
const pipes = {
[valueProp]: value,
[callbackProp]: function () {
internalOnChange.apply(this, arguments);
// Middleman callback to allow for onChange back to the caller, if needed
if (onChange) {
onChange.apply(this, arguments);
}
}
};
return (
<>
<Component
id={name}
inputRef={ref}
caption={error ? error?.message : ""}
label={label}
{...pipes}
{...rest}
/>
</>
);
}}
/>
);
};
Working CodeSandbox Example
I'm following the docs of Antd and tried to use this piece of code from here antd dynamic form item:
import { Form, Input, Button, Space } from 'antd';
import { MinusCircleOutlined, PlusOutlined } from '#ant-design/icons';
const Demo = () => {
const onFinish = values => {
console.log('Received values of form:', values);
};
return (
<Form name="dynamic_form_nest_item" onFinish={onFinish} autoComplete="off">
<Form.List name="users">
{(fields, { add, remove }) => (
<>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="baseline">
<Form.Item
{...field}
name={[field.name, 'first']}
fieldKey={[field.fieldKey, 'first']}
rules={[{ required: true, message: 'Missing first name' }]}
>
<Input placeholder="First Name" />
</Form.Item>
<Form.Item
{...field}
name={[field.name, 'last']}
fieldKey={[field.fieldKey, 'last']}
rules={[{ required: true, message: 'Missing last name' }]}
>
<Input placeholder="Last Name" />
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
))}
<Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
Add field
</Button>
</Form.Item>
</>
)}
</Form.List>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
};
But I have this error, when I add some rows, then delete some of them and finally submit, the validator keeps working even after I had deleted those rows.
Here is a demo that replicates my error.
https://codesandbox.io/s/quizzical-ride-m1pe6?file=/src/App.js
This is a bug from antd.
An issue was opened about that on their github.
https://github.com/ant-design/ant-design/issues/27576
And the associate PR :
https://github.com/react-component/field-form/pull/213
A fix has been merged last week. Normally, the next release will include the fix.
I used the React ant design drawer , When the user did not complete the form, I clicked on the outer side of the drawer and tried to display the notification message. but its not working, anyone know how to do that correctly
stack blitz here
Code here
import React, { Component } from 'react';
import { render } from 'react-dom';
import 'antd/dist/antd.css';
import './style.css';
import { Drawer, Form, Button, Col, Row, Input, Select, DatePicker, Icon } from 'antd';
const { Option } = Select;
class App extends Component {
state = { visible: false };
showDrawer = () => {
this.setState({
visible: true,
});
};
onClose = () => {
this.setState({
visible: false,
});
};
render() {
return (
<div>
<Button type="primary" onClick={this.showDrawer}>
<Icon type="plus" /> New account
</Button>
<Drawer
title="Create a new account"
width={720}
onClose={this.onClose}
visible={this.state.visible}
bodyStyle={{ paddingBottom: 80 }}
>
<Row gutter={16}>
<Col span={12}>
<Form.Item label="Name">
<Input placeholder="Please enter user name" />)}
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="Url">
<Input
style={{ width: '100%' }}
addonBefore="http://"
addonAfter=".com"
placeholder="Please enter url"
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item label="Owner">
<Select placeholder="Please select an owner">
<Option value="xiao">Xiaoxiao Fu</Option>
<Option value="mao">Maomao Zhou</Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="Type">
<Select placeholder="Please choose the type">
<Option value="private">Private</Option>
<Option value="public">Public</Option>
</Select>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item label="Approver">
<Select placeholder="Please choose the approver">
<Option value="jack">Jack Ma</Option>
<Option value="tom">Tom Liu</Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="DateTime">
<DatePicker.RangePicker
style={{ width: '100%' }}
getPopupContainer={trigger => trigger.parentNode}
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={24}>
<Form.Item label="Description">
<Input.TextArea rows={4} placeholder="please enter url description" />)}
</Form.Item>
</Col>
</Row>
<div
style={{
position: 'absolute',
right: 0,
bottom: 0,
width: '100%',
borderTop: '1px solid #e9e9e9',
padding: '10px 16px',
background: '#fff',
textAlign: 'right',
}}
>
<Button onClick={this.onClose} style={{ marginRight: 8 }}>
Cancel
</Button>
<Button onClick={this.onClose} type="primary">
Submit
</Button>
</div>
</Drawer>
</div>
);
}
}
render(<App />, document.getElementById('root'));
You need to add the logic about displaying notification on the onClose method of the <Drawer/>. Note that this method takes as input the elements that can trigger 'close' of drawer which are a div (background mask), an svg (X icon) and a button (Cancel).
At the following example the error notification is displayed if any input is empty when the drawer mask is clicked.
You can find also the example here: https://stackblitz.com/edit/react-28u4zw
import React, { Component } from "react";
import { render } from "react-dom";
import "antd/dist/antd.css";
import "./style.css";
import {
message,
Drawer,
Form,
Button,
Col,
Row,
Input,
Select,
DatePicker,
Icon
} from "antd";
const { Option } = Select;
const FIELD_NAMES = ["name", "url", "owner", "type", "approver", "dates"];
const initialValues = FIELD_NAMES.reduce(
(fieldList, fieldName) => ({ ...fieldList, [fieldName]: null }),
{}
);
class App extends Component {
state = {
visible: false,
...initialValues
};
showDrawer = () => {
this.setState({
visible: true
});
};
onClose = e => {
this.setState({
visible: false
});
const emptyFieldNames = FIELD_NAMES.filter(
fieldName => !this.state[fieldName]
);
if (emptyFieldNames.length > 0 && e.target.tagName === "DIV") {
return message.error(
`Please fill ${emptyFieldNames.join(", ")} field(s)`
);
}
};
setInput = fieldName => e => {
this.setState({ [fieldName]: e.target.value });
};
setSelect = fieldName => val => {
this.setState({ [fieldName]: val });
};
setDate = fieldName => dateList => {
this.setState({ [fieldName]: dateList.length > 0 ? dateList : null });
};
render() {
return (
<div>
<Button type="primary" onClick={this.showDrawer}>
<Icon type="plus" /> New account
</Button>
<Drawer
title="Create a new account"
width={720}
onClose={this.onClose}
visible={this.state.visible}
bodyStyle={{ paddingBottom: 80 }}
>
<Row gutter={16}>
<Col span={12}>
<Form.Item label="Name">
<Input
placeholder="Please enter user name"
onChange={this.setInput("name")}
/>
)}
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="Url">
<Input
style={{ width: "100%" }}
addonBefore="http://"
addonAfter=".com"
placeholder="Please enter url"
onChange={this.setInput("url")}
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item label="Owner">
<Select
placeholder="Please select an owner"
onChange={this.setSelect("owner")}
>
<Option value="xiao">Xiaoxiao Fu</Option>
<Option value="mao">Maomao Zhou</Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="Type">
<Select
placeholder="Please choose the type"
onChange={this.setSelect("type")}
>
<Option value="private">Private</Option>
<Option value="public">Public</Option>
</Select>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item label="Approver">
<Select
placeholder="Please choose the approver"
onChange={this.setSelect("approver")}
>
<Option value="jack">Jack Ma</Option>
<Option value="tom">Tom Liu</Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="DateTime">
<DatePicker.RangePicker
style={{ width: "100%" }}
getPopupContainer={trigger => trigger.parentNode}
onChange={this.setDate("dates")}
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={24}>
<Form.Item label="Description">
<Input.TextArea
rows={4}
placeholder="please enter url description"
/>
)}
</Form.Item>
</Col>
</Row>
<div
style={{
position: "absolute",
right: 0,
bottom: 0,
width: "100%",
borderTop: "1px solid #e9e9e9",
padding: "10px 16px",
background: "#fff",
textAlign: "right"
}}
>
<Button onClick={this.onClose} style={{ marginRight: 8 }}>
Cancel
</Button>
<Button onClick={this.onClose} type="primary">
Submit
</Button>
</div>
</Drawer>
</div>
);
}
}
render(<App />, document.getElementById("root"));