react antd Form.List Form.Iterm Checkbox.Group的案例

邮件订阅交易报表流水

需求功能

react antd Form.List Form.Iterm Checkbox.Group的案例_第1张图片

关键代码

import React from "react";
import { inject, observer } from "mobx-react";
import { withRouter } from "react-router-dom";
import {Input, Button, Checkbox, Form, Skeleton} from "antd";
import addIcon from 'images/icon/add.png';
import subIcon from 'images/icon/reduce.png';

@inject(state => ({
    history: state.history,
    subscribeInfo: state.store.subscribe.subscribeInfo,
    getSubscribeInfo: state.store.subscribe.getSubscribeInfo,
    setSubscribeInfo: state.store.subscribe.setSubscribeInfo,
}))

@withRouter
@observer
class Report extends React.Component {
    formRef = React.createRef();
    state = {
        cycleOptions: [
            { label: '全部', value: 'all' },
            { label: '日报', value: 'day' },
            { label: '周报', value: 'week' },
            { label: '月报', value: 'month' },
        ],
        cycleRules: [
            {
                required: true,
                message: '请勾选交易报告纬度'
            }
        ],
        mailRules: [
            {
                required: true,
                message: '请输入邮箱地址'
            },
            {
                pattern: /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/,
                message: '邮箱地址不正确'
            }
        ],
        originReportCycle: [],
        formData: {
            toMails:[null],
            toCcMails:[null],
            reportCycle: [],
        },
        formLoading: true,
    };

    componentDidMount () {
        this.props.getSubscribeInfo( () => {
            let reportInfo = this.props.subscribeInfo;
            let initCycle = this.initReportCycle(reportInfo.reportCycle);
            this.setState({
                formData: {
                	//为空时需有首元素,否则页面不会渲染,故而为空赋值为[null]
                	// toMails: reportInfo.toMails.length > 0 ? reportInfo.toMails : [null],
                	//  toCcMails: reportInfo.toCcMails.length > 0  ? reportInfo.toCcMails : [null],
                	// 此种写法有BUG,当把接口数据设置到表单,编辑Form.List的原有其中任意一项数据,此时其他原有数据项直接置空。
                	// 请修改为如下写法,因为ObservableArray 与 Array 是有区别的,Form.list 期待的是Array。
                    toMails: reportInfo.toMails.length > 0 ? [...reportInfo.toMails] : [null],
                    toCcMails: reportInfo.toCcMails.length > 0  ? [...reportInfo.toCcMails] : [null],
                    reportCycle: initCycle,
                },
                formLoading: false,
            }, () => {
                this.onFill();
            });
        });
    }

    initReportCycle(reportCycle = []) {
        let allCycle = this.state.cycleOptions.map(item => item.value);
        if (reportCycle.includes('all') || ( !reportCycle.includes('all') &&  allCycle.length -1 === reportCycle.length ) ) {
            return  allCycle;
        }

        return reportCycle;
    }


    // checkout.group 修改值 里边的变更逻辑
    // 利用每次只会变更一个值的特点
    onChangeCycle = (currentCycle) => {
        let allCycle = this.state.cycleOptions.map(item => item.value);
        let originReportCycle = this.state.formData.reportCycle;

        // console.log('allCycle', allCycle, 'originReportCycle', this.state.originReportCycle, 'currentCycle', currentCycle);
        if (originReportCycle.length > currentCycle.length) { //减少勾选
        	//包含all,说明取消勾选非全选是其他选项,此时把全选去除
            if (currentCycle.includes('all')) { 
                currentCycle.splice(currentCycle.indexOf('all'), 1);
            }
  			//不包含all且剩余其他项,说明取消勾选的是全选,此时全部反选
            if (! currentCycle.includes('all') && currentCycle.length === allCycle.length - 1 ) { //包含all
                currentCycle = [];
            }

        } else { //增加勾选
        	//包含all,说明新增勾选的是全选,此时需选中全部选项
            if (currentCycle.includes('all')) {
                currentCycle = allCycle;
            }
			//不包含all且其他选项全部选中,此时需选中全部
            if (! currentCycle.includes('all') && currentCycle.length === allCycle.length - 1 ) {
                currentCycle = allCycle;
            }
        }
        
        //记录原始值
        this.setState({
            originReportCycle: currentCycle,
        }, () => {
        	this.onFill();
        });

    }

    goBack() {
        this.props.history.push('/yourPageName');
    }

    onCancel = () => {
        this.goBack();
    }

    onFinish = (values) => {
        let data = {
            reportCycle: values.reportCycle,
            toMails:values.toMails,
            toCcMails :values.toCcMails,
        }

        this.props.setSubscribeInfo(data, () => {
            this.goBack();
        });
    }


    onFill = () => {
        this.formRef.current.setFieldsValue({...this.state.formData});
    }

    render() {
        let {
            cycleOptions,
            cycleRules,
            mailRules,
            formLoading,
        } = this.state;

        return (
            <div className="trade-flow-report">
                <div className="title">
                    <span>设置交易流水报告邮件接收人</span>
                </div>
                {
                    formLoading
                        ? <Skeleton active={ true } title={ false } paragraph={{ rows: 15 }}/>
                        : <Form ref={this.formRef}  onFinish={ this.onFinish} scrollToFirstError>
                            <div className="content">
                                <div className="item-row">
                                    <div className="item-label">交易报告维度</div>
                                    <div className="item-info">
                                        <Form.Item name="reportCycle" rules={cycleRules}>
                                            <Checkbox.Group
                                                options={cycleOptions}
                                                onChange={this.onChangeCycle}
                                            />
                                        </Form.Item>
                                    </div>
                                </div>
                                <div className="item-row">
                                    <div className="item-label">报告收件人</div>
                                    <div className="item-info">
                                        <Form.List name="toMails">
                                            {
                                                ( fields, { add , remove } ) => {
                                                    return (
                                                        <div className="mails-list">
                                                            {
                                                                fields.map( (field, index) => (
                                                                    <span className="mails-box" key={field.key}>
                                                                <Form.Item {...field} validateTrigger={['onChange', 'onBlur']} rules={mailRules} className="user-mail">
                                                                    <Input placeholder="请输入邮箱地址" className="common-input" value={field.value}/>
                                                                 </Form.Item>
                                                                <span><img src={addIcon} alt="添加" onClick={() => add()}/></span>
                                                                <span>{index === 0 ? '' : <img src={subIcon} alt="删除" onClick={() => remove(field.name)}/>}</span>
                                                            </span>
                                                                ))
                                                            }
                                                        </div>
                                                    );
                                                }
                                            }
                                        </Form.List>
                                    </div>
                                </div>
                                <div className="item-row">
                                    <div className="item-label">报告抄送人</div>
                                    <div className="item-info">
                                        <Form.List name="toCcMails">
                                            {
                                                ( fields, { add , remove } ) => {
                                                    return (
                                                        <div className="mails-list">
                                                            {
                                                                fields.map( (field, index) => (
                                                                    <span className="mails-box" key={field.key}>
                                                                <Form.Item {...field} validateTrigger={['onChange', 'onBlur']} rules={mailRules} className="user-mail">
                                                                    <Input placeholder="请输入邮箱地址" className="common-input" value={field.value}/>
                                                                 </Form.Item>
                                                                <span><img src={addIcon} alt="添加" onClick={() => add()}/></span>
                                                                <span>{index === 0 ? '' : <img src={subIcon} alt="删除" onClick={() => remove(field.name)}/>}</span>
                                                            </span>
                                                                ))
                                                            }
                                                        </div>
                                                    );
                                                }
                                            }
                                        </Form.List>
                                    </div>
                                </div>
                            </div>
                            <Form.Item className="operate-box">
                                <Button className="operate-btn" onClick={this.onCancel }>取消</Button>
                                <Button  className="operate-btn" type="primary" htmlType="submit">提交</Button>
                            </Form.Item>
                        </Form>
                }
            </div>
        )
    }
}

export default Report

你可能感兴趣的:(WEB前端,react,antd,Form.List,Form.Item,CheckBox.Group,React.createRef)