Skip to content

Instantly share code, notes, and snippets.

@carloshm91
Last active August 9, 2022 05:43
Show Gist options
  • Save carloshm91/0cf97872e113933f0c50b071e0fb0328 to your computer and use it in GitHub Desktop.
Save carloshm91/0cf97872e113933f0c50b071e0fb0328 to your computer and use it in GitHub Desktop.
formik ant design modal example
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