-
-
Save carloshm91/0cf97872e113933f0c50b071e0fb0328 to your computer and use it in GitHub Desktop.
formik ant design modal example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Fragment, PureComponent } from 'react'; | |
import { connect } from 'dva'; | |
import { Field as FormikField, Form as FormikForm, withFormik } from 'formik'; | |
import * as signalR from '@aspnet/signalr'; | |
import { formatMessage } from 'umi/locale'; | |
import { | |
Button, | |
Card, | |
Col, | |
DatePicker, | |
Divider, | |
Dropdown, | |
Form, | |
Icon, | |
Input, | |
InputNumber, | |
Menu, | |
message, | |
Modal, | |
Popconfirm, | |
Row, | |
Select, | |
} from 'antd'; | |
import StandardTable from '@/components/StandardTable'; | |
import PageHeaderWrapper from '@/components/PageHeaderWrapper'; | |
import styles from './OverGroupList.less'; | |
import * as Yup from 'yup'; | |
const FormItem = Form.Item; | |
const { TextArea } = Input; | |
const { Option } = Select; | |
const getValue = obj => | |
Object.keys(obj) | |
.map(key => obj[key]) | |
.join(','); | |
const OverGroupSchema = Yup.object().shape({ | |
name: Yup.string() | |
.min(2, 'Too Short!') | |
.max(50, 'Too Long!') | |
.required(formatMessage({ id: 'form.errors.required' })), | |
code: Yup.string() | |
.min(2, 'Too Short!') | |
.max(50, 'Too Long!') | |
.required(formatMessage({ id: 'form.errors.required' })), | |
}); | |
const InnerForm = ({ | |
props, | |
values, | |
errors, | |
touched, | |
setFieldTouched, | |
setFieldValue, | |
isSubmitting, | |
handleSubmit, | |
}) => { | |
return ( | |
<FormikForm onSubmit={handleSubmit}> | |
<FormItem> | |
<FormikField | |
name="code" | |
render={({ field }) => | |
<FormItem | |
hasFeedback={!!errors[field.name]} | |
validateStatus={errors[field.name] && 'error'} | |
help={errors[field.name]}> | |
<Input | |
placeholder="Code" | |
value={values[field.name]} | |
onChange={event => setFieldValue(field.name, event.target.value)} | |
onBlur={() => setFieldTouched(field.name)} | |
onPressEnter={handleSubmit} | |
/> | |
</FormItem> | |
} | |
/> | |
</FormItem> | |
<FormItem> | |
<FormikField | |
name="name" | |
render={({ field }) => | |
<FormItem | |
hasFeedback={!!errors[field.name]} | |
validateStatus={errors[field.name] && 'error'} | |
help={errors[field.name]}> | |
<Input | |
placeholder="Name" | |
value={values[field.name]} | |
onChange={event => setFieldValue(field.name, event.target.value)} | |
onBlur={() => setFieldTouched(field.name)} | |
onPressEnter={handleSubmit} | |
/> | |
</FormItem> | |
} | |
/> | |
</FormItem> | |
<FormItem> | |
<Button htmlType="submit" type="primary" disabled={isSubmitting}> | |
Submit | |
</Button> | |
</FormItem> | |
</FormikForm> | |
); | |
}; | |
const OverGroupFormikForm = withFormik({ | |
mapPropsToValues({ code, name }) { | |
return { | |
code: code || '', | |
name: name || '', | |
}; | |
}, | |
validationSchema: OverGroupSchema, | |
handleSubmit(values, { resetForm, setErrors, setSubmitting }) { | |
setTimeout(() => { | |
console.log('Form values', values); | |
// save | |
setSubmitting(false); | |
}, 2000); | |
}, | |
})(InnerForm); | |
const CreateForm = Form.create()(props => { | |
const { modalVisible, form, handleAdd, handleModalVisible, confirmLoading } = props; | |
const okHandle = () => { | |
form.validateFields((err, fieldsValue) => { | |
console.log(JSON.stringify(err)); | |
if (err) return; | |
handleAdd(fieldsValue, form); | |
}); | |
}; | |
return ( | |
<Modal | |
bodyStyle={{ padding: '32px 40px 48px' }} | |
destroyOnClose | |
title="Crear" | |
confirmLoading={confirmLoading} | |
visible={modalVisible} | |
onOk={okHandle} | |
onCancel={() => handleModalVisible()}> | |
<OverGroupFormikForm/> | |
</Modal> | |
); | |
}); | |
@Form.create() | |
class UpdateForm extends PureComponent { | |
constructor(props) { | |
super(props); | |
this.state = { | |
formVals: { | |
name: props.values.name, | |
description: props.values.description, | |
key: props.values.id, | |
}, | |
}; | |
} | |
okHandle = () => { | |
const { form, handleUpdate } = this.props; | |
const { formVals: oldValue } = this.state; | |
form.validateFields((err, fieldsValue) => { | |
if (err) return; | |
const formVals = { ...oldValue, ...fieldsValue }; | |
this.setState( | |
{ | |
formVals, | |
}, | |
() => { | |
handleUpdate(formVals); | |
}, | |
); | |
}); | |
}; | |
render() { | |
const { updateModalVisible, handleUpdateModalVisible, confirmLoading } = this.props; | |
const { formVals } = this.state; | |
const { form } = this.props; | |
return ( | |
<Modal | |
bodyStyle={{ padding: '32px 40px 48px' }} | |
confirmLoading={confirmLoading} | |
visible={updateModalVisible} | |
destroyOnClose | |
title="Modificar" | |
onOk={this.okHandle} | |
onCancel={() => handleUpdateModalVisible()}> | |
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} key="name" label="Name"> | |
{form.getFieldDecorator('name', { | |
rules: [{ required: true }], | |
initialValue: formVals.name, | |
})(<Input placeholder="请输入"/>)} | |
</FormItem> | |
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} key="description" label="Description"> | |
{form.getFieldDecorator('description', { | |
rules: [{ required: true, message: 'La longitud minima es 5!', min: 5 }], | |
initialValue: formVals.description, | |
})(<TextArea rows={4} placeholder="请输入至少五个字符"/>)} | |
</FormItem> | |
</Modal> | |
); | |
} | |
} | |
/* eslint react/no-multi-comp:0 */ | |
@connect(({ overgroup, loading }) => ({ | |
overgroup, | |
loading: loading.models.overgroup, | |
})) | |
@Form.create() | |
class TableList extends PureComponent { | |
state = { | |
modalVisible: false, | |
updateModalVisible: false, | |
expandForm: false, | |
selectedRows: [], | |
formValues: {}, | |
stepFormValues: {}, | |
confirmLoading: false, | |
}; | |
columns = [ | |
{ | |
title: 'Codigo', | |
dataIndex: 'code', | |
}, | |
{ | |
title: 'Nombre', | |
dataIndex: 'name', | |
}, | |
{ | |
title: 'Opciones', | |
render: (text, record) => ( | |
<Fragment> | |
<a onClick={() => this.handleUpdateModalVisible(true, record)}><Icon type="edit"/></a> | |
<Divider type="vertical"/> | |
<Popconfirm | |
onConfirm={() => this.remove(record)} | |
title="Confirm to delete?"> | |
<a href=""><Icon type="delete"/></a> | |
</Popconfirm> | |
</Fragment> | |
), | |
}, | |
]; | |
sendMessage = () => { | |
this.state.hubConnection | |
.invoke('SendMessage', this.state.nick, 'desde cuba') | |
.catch(err => console.error(err)); | |
this.setState({ message: '' }); | |
}; | |
remove(record) { | |
const { dispatch } = this.props; | |
dispatch({ | |
type: 'overgroup/remove', | |
payload: record.id, | |
callback: () => { | |
console.log('Eliminado correctamente'); | |
message.success('Eliminado correctamente'); | |
}, | |
}); | |
} | |
componentDidMount() { | |
const { dispatch } = this.props; | |
dispatch({ | |
type: 'overgroup/fetch', | |
}); | |
const nick = 'asd';//window.prompt('Your name:', ''); | |
const hubConnection = new signalR.HubConnectionBuilder().withUrl('http://localhost:51704/hub').build(); | |
this.setState({ hubConnection, nick }, () => { | |
this.state.hubConnection | |
.start() | |
.then(() => console.log('Connection started!')) | |
.catch(err => console.log('Error while establishing connection :(')); | |
this.state.hubConnection.on('ReceiveMessage', (nick, receivedMessage) => { | |
// const text = `${nick}: ${receivedMessage}`; | |
// alert(text); | |
}); | |
}); | |
} | |
handleStandardTableChange = (pagination, filtersArg, sorter) => { | |
const { dispatch } = this.props; | |
const { formValues } = this.state; | |
const filters = Object.keys(filtersArg).reduce((obj, key) => { | |
const newObj = { ...obj }; | |
newObj[key] = getValue(filtersArg[key]); | |
return newObj; | |
}, {}); | |
const params = { | |
currentPage: pagination.current, | |
pageSize: pagination.pageSize, | |
...formValues, | |
...filters, | |
}; | |
if (sorter.field) { | |
params.sorter = `${sorter.field}_${sorter.order}`; | |
} | |
dispatch({ | |
type: 'overgroup/fetch', | |
payload: params, | |
}); | |
}; | |
handleFormReset = () => { | |
const { form, dispatch } = this.props; | |
form.resetFields(); | |
this.setState({ | |
formValues: {}, | |
}); | |
dispatch({ | |
type: 'overgroup/fetch', | |
payload: {}, | |
}); | |
}; | |
toggleForm = () => { | |
const { expandForm } = this.state; | |
this.setState({ | |
expandForm: !expandForm, | |
}); | |
}; | |
handleMenuClick = e => { | |
const { dispatch } = this.props; | |
const { selectedRows } = this.state; | |
if (!selectedRows) return; | |
switch (e.key) { | |
case 'remove': | |
dispatch({ | |
type: 'overgroup/remove', | |
payload: { | |
key: selectedRows.map(row => row.key), | |
}, | |
callback: () => { | |
this.setState({ | |
selectedRows: [], | |
}); | |
}, | |
}); | |
break; | |
default: | |
break; | |
} | |
}; | |
handleSelectRows = rows => { | |
this.setState({ | |
selectedRows: rows, | |
}); | |
}; | |
handleSearch = e => { | |
e.preventDefault(); | |
const { dispatch, form } = this.props; | |
form.validateFields((err, fieldsValue) => { | |
if (err) return; | |
const values = { | |
...fieldsValue, | |
updatedAt: fieldsValue.updatedAt && fieldsValue.updatedAt.valueOf(), | |
}; | |
this.setState({ | |
formValues: values, | |
}); | |
dispatch({ | |
type: 'overgroup/fetch', | |
payload: values, | |
}); | |
}); | |
}; | |
handleCheckCode = (rule, value, callback) => { | |
console.log(JSON.stringify(rule)); | |
const { getFieldValue } = this.props.form; | |
const { dispatch } = this.props; | |
console.log(JSON.stringify(value)); | |
callback(new Promise((resolve, reject) => { | |
dispatch({ | |
type: 'overgroup/code', | |
payload: { | |
value: { code: value }, | |
resolve: resolve, | |
reject: reject, | |
}, | |
}); | |
}) | |
.then(res => { | |
console.log('res JSON >> ' + JSON.stringify(res)); | |
return true; | |
}) | |
.catch(err => { | |
console.log('err JSON >> ' + JSON.stringify(err)); | |
return false; | |
})); | |
}; | |
handleModalVisible = flag => { | |
this.setState({ | |
modalVisible: !!flag, | |
}); | |
}; | |
handleUpdateModalVisible = (flag, record) => { | |
this.setState({ | |
updateModalVisible: !!flag, | |
stepFormValues: record || {}, | |
}); | |
}; | |
handleAdd = (fields, form) => { | |
this.setState({ confirmLoading: true }); | |
const { dispatch } = this.props; | |
console.log(JSON.stringify(fields)); | |
new Promise((resolve, reject) => { | |
dispatch({ | |
type: 'overgroup/create', | |
payload: { | |
values: { | |
Code: fields.code, | |
Name: fields.name, | |
}, | |
resolve: resolve, | |
reject: reject, | |
}, | |
}); | |
}) | |
.then(res => { | |
console.log('res JSON >> ' + JSON.stringify(res)); | |
this.setState({ confirmLoading: false }); | |
message.success('Añadido correctamente'); | |
form.resetFields(); | |
this.handleModalVisible(); | |
}) | |
.catch(err => { | |
this.setState({ confirmLoading: false }); | |
console.log('err JSON >> ' + JSON.stringify(err)); | |
this.setState({ | |
validations: { | |
...this.state.validations, | |
code: { | |
validateStatus: err.Code !== undefined ? 'error' : '', | |
help: err.Code !== undefined ? err.Code[0] : '', | |
}, | |
}, | |
}); | |
this.setState({ | |
validations: { | |
...this.state.validations, | |
name: { | |
validateStatus: err.Name !== undefined ? 'error' : '', | |
help: err.Name !== undefined ? err.Name[0] : '', | |
}, | |
}, | |
}); | |
this.setState({ | |
validations: { | |
...this.state.validations, | |
description: { | |
validateStatus: err.Description !== undefined ? 'error' : '', | |
help: err.Description !== undefined ? err.Description[0] : '', | |
}, | |
}, | |
}); | |
}); | |
}; | |
handleUpdate = fields => { | |
const { dispatch } = this.props; | |
dispatch({ | |
type: 'overgroup/update', | |
payload: { | |
key: fields.key, | |
values: { | |
name: fields.name, | |
description: fields.description, | |
}, | |
}, | |
}); | |
message.success('Modificado correctamente'); | |
this.handleUpdateModalVisible(); | |
}; | |
renderSimpleForm() { | |
const { | |
form: { getFieldDecorator }, | |
} = this.props; | |
return ( | |
<Form onSubmit={this.handleSearch} layout="inline"> | |
<Row gutter={{ md: 8, lg: 24, xl: 48 }}> | |
<Col md={8} sm={24}> | |
<FormItem label="规则名称"> | |
{getFieldDecorator('name')(<Input placeholder="请输入"/>)} | |
</FormItem> | |
</Col> | |
<Col md={8} sm={24}> | |
<FormItem label="使用状态"> | |
{getFieldDecorator('status')( | |
<Select placeholder="请选择" style={{ width: '100%' }}> | |
<Option value="0">关闭</Option> | |
<Option value="1">运行中</Option> | |
</Select>, | |
)} | |
</FormItem> | |
</Col> | |
<Col md={8} sm={24}> | |
<span className={styles.submitButtons}> | |
<Button type="primary" htmlType="submit"> | |
查询 | |
</Button> | |
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}> | |
重置 | |
</Button> | |
<a style={{ marginLeft: 8 }} onClick={this.toggleForm}> | |
展开 <Icon type="down"/> | |
</a> | |
</span> | |
</Col> | |
</Row> | |
</Form> | |
); | |
} | |
renderAdvancedForm() { | |
const { | |
form: { getFieldDecorator }, | |
} = this.props; | |
return ( | |
<Form onSubmit={this.handleSearch} layout="inline"> | |
<Row gutter={{ md: 8, lg: 24, xl: 48 }}> | |
<Col md={8} sm={24}> | |
<FormItem label="规则名称"> | |
{getFieldDecorator('name')(<Input placeholder="请输入"/>)} | |
</FormItem> | |
</Col> | |
<Col md={8} sm={24}> | |
<FormItem label="使用状态"> | |
{getFieldDecorator('status')( | |
<Select placeholder="请选择" style={{ width: '100%' }}> | |
<Option value="0">关闭</Option> | |
<Option value="1">运行中</Option> | |
</Select>, | |
)} | |
</FormItem> | |
</Col> | |
<Col md={8} sm={24}> | |
<FormItem label="调用次数"> | |
{getFieldDecorator('number')(<InputNumber style={{ width: '100%' }}/>)} | |
</FormItem> | |
</Col> | |
</Row> | |
<Row gutter={{ md: 8, lg: 24, xl: 48 }}> | |
<Col md={8} sm={24}> | |
<FormItem label="更新日期"> | |
{getFieldDecorator('date')( | |
<DatePicker style={{ width: '100%' }} placeholder="请输入更新日期"/>, | |
)} | |
</FormItem> | |
</Col> | |
<Col md={8} sm={24}> | |
<FormItem label="使用状态"> | |
{getFieldDecorator('status3')( | |
<Select placeholder="请选择" style={{ width: '100%' }}> | |
<Option value="0">关闭</Option> | |
<Option value="1">运行中</Option> | |
</Select>, | |
)} | |
</FormItem> | |
</Col> | |
<Col md={8} sm={24}> | |
<FormItem label="使用状态"> | |
{getFieldDecorator('status4')( | |
<Select placeholder="请选择" style={{ width: '100%' }}> | |
<Option value="0">关闭</Option> | |
<Option value="1">运行中</Option> | |
</Select>, | |
)} | |
</FormItem> | |
</Col> | |
</Row> | |
<div style={{ overflow: 'hidden' }}> | |
<div style={{ float: 'right', marginBottom: 24 }}> | |
<Button type="primary" htmlType="submit"> | |
查询 | |
</Button> | |
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}> | |
重置 | |
</Button> | |
<a style={{ marginLeft: 8 }} onClick={this.toggleForm}> | |
收起 <Icon type="up"/> | |
</a> | |
</div> | |
</div> | |
</Form> | |
); | |
} | |
renderForm() { | |
const { expandForm } = this.state; | |
return expandForm ? this.renderAdvancedForm() : this.renderSimpleForm(); | |
} | |
render() { | |
const { | |
overgroup: { data }, | |
loading, | |
} = this.props; | |
const { selectedRows, modalVisible, updateModalVisible, stepFormValues } = this.state; | |
const menu = ( | |
<Menu onClick={this.handleMenuClick} selectedKeys={[]}> | |
<Menu.Item key="remove">删除</Menu.Item> | |
<Menu.Item key="approval">批量审批</Menu.Item> | |
</Menu> | |
); | |
const parentMethods = { | |
handleAdd: this.handleAdd, | |
confirmLoading: this.state.confirmLoading, | |
handleModalVisible: this.handleModalVisible, | |
validations: this.state.validations, | |
handleCheckCode: this.handleCheckCode, | |
}; | |
const updateMethods = { | |
handleUpdateModalVisible: this.handleUpdateModalVisible, | |
handleUpdate: this.handleUpdate, | |
confirmLoading: this.state.confirmLoading, | |
validations: this.state.validations, | |
}; | |
return ( | |
<PageHeaderWrapper title="Sobre grupos"> | |
{/*<div>*/} | |
{/*<SpreadsheetContainer/>*/} | |
{/*</div>*/} | |
<Card bordered={false}> | |
<div className={styles.tableList}> | |
{/*<div className={styles.tableListForm}>{this.renderForm()}</div>*/} | |
<div className={styles.tableListOperator}> | |
<Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}> | |
Crear | |
</Button> | |
{selectedRows.length > 0 && ( | |
<span> | |
<Button>批量操作</Button> | |
<Dropdown overlay={menu}> | |
<Button> | |
更多操作 <Icon type="down"/> | |
</Button> | |
</Dropdown> | |
</span> | |
)} | |
</div> | |
<StandardTable | |
selectedRows={selectedRows} | |
loading={loading} | |
data={data} | |
columns={this.columns} | |
onSelectRow={this.handleSelectRows} | |
onChange={this.handleStandardTableChange} | |
/> | |
</div> | |
</Card> | |
<CreateForm {...parentMethods} modalVisible={modalVisible}/> | |
{stepFormValues && Object.keys(stepFormValues).length ? ( | |
<UpdateForm | |
{...updateMethods} | |
updateModalVisible={updateModalVisible} | |
values={stepFormValues} | |
/> | |
) : null} | |
</PageHeaderWrapper> | |
); | |
} | |
} | |
export default TableList; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment