美文网首页
表单验证与回填以及表单常见bug解决方法

表单验证与回填以及表单常见bug解决方法

作者: 家有饿犬和聋猫 | 来源:发表于2019-10-30 10:43 被阅读0次
    import React, { Component } from 'react';
    import styles from './addMessage.scss';
    import {Input, Form, Table, message, Row, Col, Modal, Radio, Select, DatePicker, Button, Pagination} from 'antd';
    import cns from 'classnames';
    import bind from 'react-autobind';
    import {isNotEmpty, addressNum} from 'utils/util'; // 封装的公用方法
    import {getSession}  from   'utils/storage';
    import Bigmodal  from  './Modal';
    import {service}  from '../../../../services/messageManage';
    import {getArea, userMsg}  from '../../../../services/common';
    import {getEnterpriseUserList} from '../../../../services/systemManage';
    import Cookies from 'js-cookie';
    
    const { TextArea } = Input;
    
     // formItemLayout :表单行列格式
    
    const formItemLayout = {
        labelCol: { span: 6 },  // 左边留白大小
        wrapperCol: { span: 17 }  // 内容区大小(两者和不能!>24)
    };
    
    
    class addMessage extends Component {
        constructor(props){
            super(props);
            this.state = {
                title: '',
                sendName: '',
                allIndustry: '',
                allCity: [],
                allCounty: [],
                content: '',
                total: 0,
                selected: '',   
                visible: false,
                hint: '',
                bigModal: false,
                saveRequired: true,  // 点“暂存”的时候  只验证标题
                companyDataSource: [],  // 企业列表
                letterMsg: {},
                selectedRows: [],  // 选中的数据 回填
                selectedKeys: [],
                keys: 0
            };
            bind(this);
        }
        componentDidMount(){
            this.industryArr();
            this.getArea();
           
            let  type = addressNum(this.props).type;
          
            if(type === 'editor'){
                  // 编辑或修改 回填信息
                this.searchLetter();
            }else {
                // 新建  获取当前用户名
                this.setState({
                    sendName: getSession('USERINFO').name
                });
            }
          
                // 添加的时候获取企业列表
            this.getEnterpriseUserList({name: ''});
            // 企业总数不随筛选变化
            getEnterpriseUserList({name: ''}).then(
                rem=>{
                    if(rem.success && isNotEmpty(rem.data)){
                        this.setState({
                            total: rem.data.totalCount
                        });
                    }else{
                        this.setState({
                            total: 0
                        });
                    }
                }
            );
            
        }
    
        // 获取信息
        searchLetter=()=>{
            let id = addressNum(this.props).id;
            service.searchLetter({id: id}).then(
                rem=>{
                    if(rem.success){
                    
    
                        //  获取收件人列表
                        let selectedRows = [];
                        if(isNotEmpty(rem.data.sendToList)){
                            let v = rem.data.sendToList;
                            let selectedKeys = [];
                            
                            v.map(
                                p=>{
                                    // p 是用户名id
                                   
                                    selectedKeys.push(p.userId);
                                    userMsg({userId: p.userId}).then(
                                        msg=>{
                            
                                            if(msg.success){
                                                selectedRows.push(msg.data);
                                            }
                                        }
                                    ).then(
                                        ()=>{
                                            this.setState({
                                                selectedRows: selectedRows,   // 数据回填,选中的数据
                                                selectedKeys
                                            });
                                        }
                                        
                                    );
                        
                                }
                            );
                        }
                        this.setState({
                            sendName: rem.data.createName,
                            selected: rem.data.sendToList.length
                        });
                      
                        setTimeout(()=>{
                            
                            this.props.form.setFieldsValue({
                                title: rem.data.name,
                                content: rem.data.content,
                                selected: rem.data.sendToList.length === 0 ?  '' : rem.data.sendToList.length
                            });
                        }, 100);
                       
                    }else{
                        this.setState({
                            
                            letterMsg: {}
                        });
                    }
                }
            );
        }
        // 获取企业用户列表  弹框中的数据     
        getEnterpriseUserList=(params)=>{
            getEnterpriseUserList(params).then(
                rem=>{
                  
                    if(rem.success && isNotEmpty(rem.data)){
                        this.setState({
                            companyDataSource: Array.isArray(rem.data.data) ? rem.data.data.map(
                                (p, index)=>{
                                    let naso = JSON.parse(p.styleJson);
                                    p['letterName'] = isNotEmpty(naso) ? naso.contactName : '';
                                    p['key'] = `${p.id}`;     //表格的key值设为id值,方便回显数据
                                    return p;
                                }
                            ) : []
                           
                        });
                    }else{
                        this.setState({
                            companyDataSource: []
                           
                        });
                    }
                }
            );
        }
      
    
        // 提交审核
        handleSubmit=(e)=>{
            e.preventDefault();  // 阻止默认刷新      
            this.props.form.validateFields((err, values) => {
                const{title, content, selected} = values;      //validateFields()获取输入值,从state传回到表单,双向绑定
                this.setState({
                    title,
                    content,
                    selected
                });
                
                if (!err) {      
                    //验证通过时,调接口发送数据
                    let id = addressNum(this.props).id;
                    let params = {
                        id: id ? id : '',  // number    如果有id,为修改信,没有为新增信
                        content,
                        name: title,
                        sendToList: this.state.selectedRows.map(
                            p=>p.id
                        )
                    };
                    service.toSubmit(params).then(
                        rem=>{
                            if(rem.success){
                                this.setState({
                                    visible: true,
                                    hint: '站内信提交成功!' 
                                });
                            }
                        }
                    );
                    
                }
            });
        };
        // 暂存
        zanCun=(e)=>{
            //不需要验证通过时,直接获取表单值
            const values = this.props.form.getFieldsValue();
            
            const{title, content} = values;
            const {selectedKeys} = this.state;
            let id = addressNum(this.props).id;
            if(title){
                let params = {
                    id: id ? id : '',                 // number 如果有id,为修改,没有为新增
                    content,
                    name: title,
                    sendToList: selectedKeys
                };
                service.toSave(params).then(
                        rem=>{
                           
                            if(rem.success){
                                this.setState({
                                    visible: true,
                                    hint: '站内信暂存成功!'
                                });
                            }
                        }
                    );
                    
            }else{
                message.warning('标题必填');
            }
                
        };
    
        // 取消
        cancel=()=>{
            this.props.history.push('/systemManage/messageManage/message');
        }
        
        littleOk=()=>{
           
            this.props.history.push('/systemManage/messageManage/message');
        }
    
        littleCancel=()=>{
            this.setState({
                visible: false
            });
        }
    
        // 已选择的企业
        selectedData=(e)=>{
    
            this.setState({
                bigModal: false,
                selected: e.selectedRows.length,
                selectedRows: e.selectedRows,
                selectedKeys: e.selectedKeys
            });
            //数据回填时,需要在表单渲染完毕之后赋值,否则会报错,所以使用一个setTimeout
            setTimeout(
                ()=>{
                    this.props.form.setFieldsValue({
                        selected: e.selectedRows.length === 0 ? '' : e.selectedRows.length
                    });
                }, 30
            );
           
        }
        
        showBigModal=(e)=>{
            this.setState({
                bigModal: true,
                keys: Number(this.state.keys) + 1
            });
        }
    
        render() {
            let {total, title, content, keys, saveRequired, sendName, visible, selected, bigModal, hint} = this.state;
          
            const { getFieldDecorator } = this.props.form;
            return (
                <div   className={styles.addMessage}>
                    <div className={'titLine'}>添加站内信</div>
                    <div className={styles.FormBox}>
                    
                    <Form onSubmit={this.handleSubmit.bind(this.props.form)}    >
                        <Row>      //form表单需要用Row  Col  包起来,否则  formItemLayout 不生效
                            <Col>
                                <Form.Item label="发件人"  {...formItemLayout}>
                                    {getFieldDecorator('ema', {
                                        rules: [
                                            {
                                                required: false
                                            }
                                        ]
                                    })(<span>{sendName}</span>)}
                                </Form.Item>
                            </Col>
                        </Row>
                        <Row>
                            <Col>
                                <Form.Item label="标题" {...formItemLayout}  >
                                    {getFieldDecorator('title', {
                                        initialValue: title,
                                        rules: [
                                            {
                                                required: true,
                                                message: '请输入标题!'
                                            }
                                        ]
                                    })(<Input />)}
                                </Form.Item>
                            </Col>
                        </Row>
                        <Row>
                            <Col>
                                <Form.Item label="内容"  {...formItemLayout}>
                                    {getFieldDecorator('content', {
                                        initialValue: content,
                                        rules: [
                                            {
                                                required: saveRequired,
                                                message: '请输入内容!'
                                            }
                                        ]
                                    })(<TextArea  rows={4} />)}
                                </Form.Item>
                            </Col>
                        </Row>
                        <Row>
                            <Col>
                                <Form.Item label="收件人"  {...formItemLayout}>
                                    {getFieldDecorator('selected', {
                                        initialValue: selected === 0 ? '' : selected,          //自定义表单值
                                        rules: [
                                            {
                                                required: saveRequired,
                                                message: '请选择收件人!'
                                            }
                                        ]
                                    })(<p><Button   onClick={this.showBigModal}  className={'red-btn'} >选择</Button>&emsp; <span>共有{total}家企业,已选择<span  style={{color: '#0C61B7'}}>&nbsp;{selected ? selected : 0}&nbsp;</span>家</span></p>)}
                                </Form.Item>
                            </Col>
                        </Row>
                        <div className="longLine"> </div>
                        <div className={styles.botDiv}>
                            <Button  className="red-btn" htmlType="submit"   >提交审核</Button>
                            <Button  className="blue-btn"  onClick={this.zanCun.bind(this.props.form)}>暂存</Button>
                            <Button  className="cancel-btn"   onClick={this.cancel}>取消</Button>
                        </div>
                    </Form>
                    </div>
                    <Modal
                    title="系统提示"
                    wrapClassName="littleModal"
                    visible={visible}
                    onCancel={this.littleCancel}
                    footer={null}
                    >
                        <div  style={{textAlign: 'center'}}>
                            <img   src={require('../../../../images/success.svg')}       />
                            <p   className="hint"  >{hint}</p>
                            <div  className="btndiv"  >
                                <Button    className="red-btn"   onClick={this.littleOk}>确定</Button>
                            </div>
    
                        </div>
                       
                    </Modal>
                    {
                        bigModal ?
                        <Bigmodal  selectedData={this.selectedData}  keys={keys}  {...this.state}      getEnterpriseUserList={this.getEnterpriseUserList}  camcelModal={this.camcelModal}   />
                        :
                        ''
                    }
                </div>
            );
        }
    }
    
    export default Form.create()(addMessage);
    
    
    
    image.png

    表单的验证

    正则验证 pattern

    <Form.Item hasFeedback validateStatus={ !disabled ?  'success' : ''} >  
                                                                           
            {getFieldDecorator('projectName', {
                initialValue: projectName,
                      rules: [
                      { required: true, message: '请输入项目标题' },    //required为true表示必填项,false表示选填项
                      {pattern: /\s\S+|S+\s|\S/, message: '标题不能全为空格'}
                           ]
                           })(
                   <Input   className={cns(styles.comInt)} placeholder="请输入项目标题"  onChange={this.projectName}   /> 
                                        )}
                                    </Form.Item>
    

    自定义验证validator

     {getFieldDecorator('declareStartTime', {
                  initialValue: declareStartTime,
                rules: [{ required: true, message: '请选择开始日期和时间' },
                   { validator: (rule, value, callback) => {
                         if (value > this.props.form.getFieldsValue().declareEndTime) {
                                callback('起始时间不能大于结束时间');
                     }
                  callback();
                }}]
         })
    
    表单注意事项

    ~获取值,使用getFieldsValue(),获取出来的是所有值,数据类型为对象,需要自己结构
    this.props.form.getFieldsValue()
    ~设置值 ,使用 this.props.form.setFieldsValue({a:"1" }) ,但是他有一个bug,数据回填较慢,导致操作的时候数据为空, 如果需要实时操作,可以把数据存在state了,然后在函数中操作
    ~表单提交时,页面刷新,数据消失
    解决方法就是 使用 e.preventDefault();


    image.png
    image.png

    参数e最好从提交的时候绑定this.props.form
    ~点击button提交表单
    两种方式:
    1

     <Button type="primary"   className={cns(styles.view)}    onClick={this.handleSubmit.bind(this.props.form)}>预览</Button>
    

    2

         <Form onSubmit={this.handleSubmit.bind(this.props.form)}    >
          <Button  className="red-btn" htmlType="submit"   >提交审核</Button>
       // htmlType="submit" 
    

    如果一个表单,有几个提交按钮,可以添加key值区分

    onClick={this.handleSubmit.bind(this.props.form , key)}
    

    3
    两个地方联动验证
    比如先输入了开始时间(验证报错),再输入结束时间,输入完结束时间需要验证开始时间,去掉开始时间验证的报错,可以使用setFilesValues({}),它在赋值的时候会做验证

     <Form.Item>
                      {getFieldDecorator('declareEndTime', {
                         initialValue: declareEndTime,
                          rules: [{ required: true, message: '请选择结束日期和时间' },
                          { validator: (rule, value, callback) => {
                           this.props.form.setFieldsValue({declareStartTime });    //赋值完后,表单自动验证起始时间
                            if (value < this.props.form.getFieldsValue().declareStartTime) {
                             callback('起始时间不能大于结束时间');
    
                              }
                              callback();
                               }}
     
                                ]
                          })(                 
                        <DatePicker    placeholder="请选择结束日期和时间" 
                        disabled = {disabled}   
                        onChange={(v)=>{ this.setState({declareEndTime: v});}}    //提前将值保存起来,方便联动验证的时候赋值
                         showTime    />
                            )}
           </Form.Item>
    
    

    相关文章

      网友评论

          本文标题:表单验证与回填以及表单常见bug解决方法

          本文链接:https://www.haomeiwen.com/subject/zuznvctx.html