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

2019-10-30  本文已影响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>

上一篇下一篇

猜你喜欢

热点阅读