引用form是第三方插件ant插件,官网网址:https://ant.design/。用到的antd的版本是@2.0.1。form(https://ant.design/components/form/)表单页面的大概样子如下:

组件讲解:

<Form></Form>表单,horizontal表示水平排列布局,数据类型是布尔,默认值为false;onSubmit表示数据验证成功后回调事件,数据类型是函;required表示必填,前面会显示红色的图标。

<FormItem></FormItem>中包含的是一个小小的组件,可以是文本框、单选按钮、多选按钮、下拉框等。{...formItemLayout}是reactjs中属性的写法{...props},formItemLayout标签布局,wrapperCol需要为输入控件设置布局样式时,和label 标签布局,通 <Col> 组件,设置 span offset 值,如{span: 3, offset: 12}。label标签的文本。getFieldDecorator用于和表单进行双向绑定,获取该组件的值:this.props.form.getFieldDecorator(id, options)。详细API如下:

其中详细讲解日期组件,

/**
     * 判断推荐时间是否选择
     */
    dateSelect(rule, value, callback) {
        if(!this.state.disabledDates){
            if(value===undefined){
                callback(new Error("请输入时间段!"));
            }else{
                callback();
            }
        }else if(this.state.disabledDates){
            callback();
        }
    }

//设置日期组件所选择的日期(所选择的日期只能是今天及今天以后的)
        const disabledDate = function (current) {
           return  current  <= (new Date()).getTime()-1000*60*60*24;
        };

const date = new Date();
const startDate=date.toLocaleDateString();//获取当前日期(年月日)

<FormItem wrapperCol={{span: 16, offset: 2}}>
       {getFieldDecorator('timeRange',
           {initialValue:[moment(startDate).startOf('day'),moment(startDate).endOf('day')]},
          {rules: [{validator: this.dateSelect.bind(this)},],},
         {validateTrigger:'onChange'})
        (<RangePicker disabled={this.state.disabledDates} disabledDate={disabledDate} />)}
</FormItem>

当form中的FormItem组件创建完毕,需要定义组件默认的属性值以及校验从父组件传递的属性,最后再将form表单包起来。代码如下:

//定义组件默认的属性值(如果父组见没有传递数据,使用默认数据)
CreateActivity.defaultProps = {};
//校验从父组件传递的属性值是否符合
CreateActivity.propTypes = {
    createDatas: React.PropTypes.object,
    createActions: React.PropTypes.object.isRequired
};
//将CreateActivity通过Form.create()包装起来
export default CreateActivity = Form.create()(CreateActivity);

图上有将form表单回显的方法:mapPropsToFields,类型是一个方法:Function(props): Object{ fieldName: Object{ value } }

例如以上日期的回显方法如下:

function mapPropsToFields(props) {
    if (props.editDatas.queryAtyDatas.atyQuerySuccess == 'yes') {
        var formData = props.editDatas.queryAtyDatas.ReturnDatas.data;
        //修改活动初始化操作
        return {
            "timeRange": {value: [moment(formData.startDate).startOf('day'), moment(formData.endDate).endOf('day')]}
        };
    }
}
//将初始化表单的方法mapPropsToFields包裹到EditActivity组件中
export default EditActivity = Form.create({
    mapPropsToFields: mapPropsToFields
})(EditActivity);

以上创建和修改就完成了。详细代码如下:

import {Row, Col, Select, Form, Input, Button, Checkbox, Radio, Tooltip, Icon,DatePicker} from 'antd';
import {Router, Route, browserHistory, hashHistory, IndexLink, Link} from 'react-router';
import React, {Component, PropTypes} from 'react'
import OperpConfig from './OperpConfig';

import css from '../css/activity.css';
import '../../../common/sass/operp/operp.scss';
var moment=require('moment');

const FormItem = Form.Item;
const RadioGroup = Radio.Group;
const RangePicker = DatePicker.RangePicker;

class CreateActivity extends React.Component {
    constructor(props) {
        super(props);
        //取消
        this.handleCancel = this.handleCancel.bind(this);
        //提交订单
        this.handleSubmit = this.handleSubmit.bind(this);
        //审批
        this.handleApprove = this.handleApprove.bind(this);
    }
    /*生命周期函数--->该方法在完成首次渲染之前被调用*/
    componentWillMount() {
        /* 设置推荐时段的状态*/
        this.setState({
            disabledDates: false
        });
    }
    /*首次使用组建类时,组件已经被渲染,DOM操作请放在这*/
    componentDidMount() {
        let editDefaultformData = this.props.form.getFieldsValue();
    }

    /*存在期:随着应用状态的改变,以及组件逐渐受到影响,你将会看到下面的方法一次被调用:*/
    componentWillReceiveProps(nextProps) {
        let formData = this.props.form.getFieldsValue();
        /*当formData.timeFlag-1,代表不限时段,日期组件即将不可用,1是限时段日期组件可以选用*/
        if (formData.timeFlag === '-1') {
            this.props.form.resetFields([['timeRange']]);
            this.setState({
                disabledDates: true
            });
        } else {
            this.setState({
                disabledDates: false
            });
        }

    }

    /**
     *条件:当组件确定要更新,在 render 之前调用
     *用处:这个时候可以确定一定会更新组件,可以执行更新前的操作
     *注意:方法中不能使用 setState ,setState 的操作应该在 componentWillReceiveProps 方法中调用
     * @param nextProps
     * @param nextState
     */
    componentWillUpdate(nextProps, nextState) {
    }

    /**
     * 组件已经被更新后的方法
     * @param nextProps
     * @param nextState
     */
    componentDidUpdate(nextProps, nextState) {
        /*创建活动成功后跳转活动主界面*/
        if (this.props.createDatas.submitDatas.createSubmitSuccess == 'yes') {
            browserHistory.push('/activity');
        }
    }
    

    handleSubmit(e) {
        e.preventDefault();
        this.props.form.validateFields((errors, values) => {
            if (errors) {
                console.log('Errors in form!!!');
                return;
            }
            //所有的form表单值,等同于values
            const formData = this.props.form.getFieldsValue();
            //从表单中获取日期timeRange的值(起始时间+结束时间)是个数组
            const timeRange = formData['timeRange'];
             /*若是不限时段 日期数组就为null*/
            if(timeRange===undefined || formData['timeFlag']==='-1'){
                formData.startDate=null;
                formData.endDate=null;
            }else if(timeRange!==undefined && formData['timeFlag']==='1'){
                //格式化时间数组为YYYYMMDD  startDate:起始时间 endDate:结束时间          
                formData.startDate=timeRange[0].format('YYYYMMDD');
                formData.endDate=timeRange[1].format('YYYYMMDD');
            }
            //默认添加创建人
            formData.createUser = '创建人1';
            this.props.createActions.createActivity(formData);
        });
    }

     /**
     * 判断推荐时间是否选择
     */
    dateSelect(rule, value, callback) {
        if(!this.state.disabledDates){
            if(value===undefined){
                callback(new Error("请输入时间段!"));
            }else{
                callback();
            }
        }else if(this.state.disabledDates){
            callback();
        }
    }

    /**
     * 取消跳转到活动主界面
     */
    handleCancel() {
        console.log('取消跳转');
        browserHistory.push('/activity');
    }
    /**
     * 提交审批
     */
     handleApprove(e){
        alert('提交审批');
        console.log('提交审批');
     }
    render() {
        const {getFieldDecorator, getFieldError, isFieldValidating} = this.props.form;
        const formItemLayout = { labelCol: {span: 2}, wrapperCol: {span: 10},};
        //设置日期组件所选择的日期(所选择的日期只能是今天及今天以后的)
        const disabledDate = function (current) {
           return  current  <= (new Date()).getTime()-1000*60*60*24;
        };
        const date = new Date();
        const startDate=date.toLocaleDateString();
        const endDate = date.toLocaleDateString()+1;
        return (
            <div>
                <Row>
                    <Col span={24}>
                        <h1>新增推荐活动</h1>
                    </Col>
                </Row>
                <Row >
                    <Col span={24}>
                        <div className="edit-underline"></div>
                    </Col>
                </Row>
                <div className="text_dom">
                    <span className="span_text"><Icon type="exclamation-circle-o" className="icon_css"/>
                    设置完成后,系统自动对同一运营位不同位置输出内容去重。
                    </span>
                </div>
                <Form horizontal onSubmit={this.handleSubmit}>
                    <FormItem
                        {...formItemLayout}
                        label="活动名称"
                        required
                    >
                        {getFieldDecorator('activityName', {
                            rules: [
                                {required: true,
                                  message: '活动名称不能为空!'},
                            ],

                        })(
                            <Input type="text" placeholder="请输入活动名称..."/>
                        )}
                    </FormItem>
                    <FormItem
                        {...formItemLayout}
                        label="活动类型"
                    >
                        {getFieldDecorator('activityType', {initialValue: '1'})(
                            <RadioGroup>
                                <Radio value="1">正式运营</Radio>
                                <Radio value="2">A/B测试</Radio>
                            </RadioGroup>
                        )}
                    </FormItem>
                     <FormItem
                        {...formItemLayout}
                        label="推荐时段"
                    >
                        {getFieldDecorator('timeFlag', {initialValue: '1'})(
                            <RadioGroup>
                                <Radio value="1">限时段&nbsp;&nbsp;&nbsp;</Radio>
                                <Radio value="-1">不限时段</Radio>
                            </RadioGroup>
                        )}
                    </FormItem>
                     <FormItem wrapperCol={{span: 16, offset: 2}}>
                      {getFieldDecorator('timeRange',
                            {initialValue:[moment(startDate).startOf('day'),moment(startDate).endOf('day')]},
                            {rules: [{validator: this.dateSelect.bind(this)},],},
                            {validateTrigger:'onChange'})
                      (<RangePicker disabled={this.state.disabledDates} disabledDate={disabledDate} />)}
                    </FormItem>
                    <FormItem {...formItemLayout} label="备注">
                        {getFieldDecorator('comments')(<Input type="textarea" />)}
                    </FormItem>
                    <FormItem wrapperCol={{span: 16, offset: 2}} style={{marginTop: 24}}>
                        <Button type="primary" htmlType="submit">保存</Button>
                        &nbsp;&nbsp;&nbsp;
                        <Button type="primary" onClick={this.handleApprove.bind(this)}>提交审批
                        </Button>
                        &nbsp;&nbsp;&nbsp;
                        <Button type="ghost" onClick={this.handleCancel}>取消</Button>
                    </FormItem>
                </Form>
            </div>
        )
            ;
    }
}
//定义组件默认的属性值(如果父组见没有传递数据,使用默认数据)
CreateActivity.defaultProps = {};
//校验从父组件传递的属性值是否符合
CreateActivity.propTypes = {
    createDatas: React.PropTypes.object,
    createActions: React.PropTypes.object.isRequired
};

export default CreateActivity = Form.create()(CreateActivity);

react引用antd的form表单的更多相关文章

  1. 【antd】form表单默认值设置

    问题: 在antd的form表单的api里面有个"initialValues"可以设置默认值.但是表单没有更新 <Form name="test" for ...

  2. 封装react antd的form表单组件

    form表单在我们日常的开发过程中被使用到的概率还是很大的,比如包含了登录.注册.修改个人信息.新增修改业务数据等的公司内部管理系统.而在使用时这些表单的样式如高度.上下边距.边框.圆角.阴影.高亮等 ...

  3. antd做form表单的组件共用,利用mapPropsToFields填写默认值

    做单页应用,不管是用Vue还是React,或者其他,有一个重要的原则,就是:组件重用. 既然组件可以重用,那么当添加一个信息,和修改该信息的布局必然是一致的,这时候,最好的方法自然是利用同一个组件,在 ...

  4. ant-pro使用Form表单验证上传图片出现的问题

    1.复现:用antd的Form表单验证上传图片必填项时出现问题:复现过程,先提交,提示图片需要上传,上传成功后,依旧提示:图片未上传 2.表单验证原理:先理解一下antd的Form表单验证的表层原理, ...

  5. React利用Antd的Form组件实现表单功能(转载)

    一.构造组件 1.表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等. 这里先引用了封装的表单域 <Form.Item /> 2.使用Form.create处 ...

  6. 前端笔记:React的form表单全部置空或者某个操作框置空的做法

    1.全部置空的做法,一般在弹出框关闭后,需要重置该form所有表单: this.props.form.resetFields(); 2.针对某个操作框置空的做法 例如,form表单里有一个部门和一个张 ...

  7. antd中的form表单 initialValue导致数据不更新问题

    初步理解 : initialValue就是所谓的defaultValue,只会在第一次赋值的时候改变,却又有一些不同,因为 initialValue又会因其他改动而改变. 然而当获取的数据重新上来要渲 ...

  8. And Design:拓荒笔记——Form表单

    And Design:拓荒笔记——Form表单 Form.create(options) Form.create()可以对包含Form表单的组件进行改造升级,会返回一个新的react组件. 经 For ...

  9. React-Antd4的Form表单校验

    之前很少用react做项目,最近入职新公司,用的react,在自己的摸索过程中,慢慢会记录一些使用方法.今天简单记录一下使用antd 4.0版本的Form表单校验,直接代码. 需要购买阿里云产品和服务 ...

随机推荐

  1. WebAPi返回类型到底应该是什么才合适,这是个问题?

    前言 有些问题只有真正遇到或者用到并且多加思考才会想到,平常若作为自学的心态去学习则不会考虑太多,我慢慢明白对于那些有太多要学的东西或者说的更加明确而且具体一点的话,如果对于你现在不是迫切要学或者需要 ...

  2. 苹果系统安装虚拟机 Mac如何安装虚拟机教程

    1.前言    大家在用 Mac 系统的时候,可能有时难免还是要用到 Windows 系统.在 Mac 上使用 Windows 系统有二种方法.一种是在 Mac上安装双系统,适合要在机器上处理一些大型 ...

  3. C语言之通过冒泡排序浅谈编程思想

    写这篇博文的目的是想起到抛砖引玉的作用,还请大牛们留下一些先进的思想,让小菜学习一下.下面入正题. 复习C语言怎么能少的了冒泡呢,记得刚学C语言那会,感觉冒泡排序真的太复杂了,理解不大了,嗯!还是当时 ...

  4. 精彩 .NET 2015

    英文原文:Understanding .NET 2015 Understanding 翻译为了解或理解,对于 .NET 来说,2015 年注定会更加精彩,所以标题就用了"精彩"这个 ...

  5. js 调用百度地图,并且定位用户地址,显示省市区街,经纬度

    网上的一些百度地图例子,基本上没有连套的 定位 例子.下面我分享一套我自己弄的,废话不多说,看代码,里面有注释! <!DOCTYPE html> <html> <head ...

  6. 记录一则ORA-00054,ORA-00031解决过程

    生产环境:AIX 5.3 + Oracle 10.2.0.5 任务要求:普通表改造分区表,历史数据不要   这个需求很简单: pl/sql导出建表语句,依次修改成分区的建表语句,注意将索引修改成本地索 ...

  7. RAC某节点启动遭遇ORA-01105,ORA-01606

    环境:RHEL6.5 + Oracle11.2.0.4 双节点RAC 故障现象:节点1实例没有启动成功,节点2正常启动. 1.故障现象 2.解决过程 3.总结 1.故障现象 尝试启动RAC 节点1,遭 ...

  8. ASP.NET MVC 概述

    目标:学习ASP.NET MVC 和ASP.NET WebForm的不同之处.学习在合适的地方使用ASP.NET MVC. MVC(Model-View-Controller)结构模式把一个对象分离成 ...

  9. SFC中的故障管理

    1.SFC中包的格式 网络服务包头,当Obit被设置为1时,表示一个SFC OAM消息 OAM Type:SFC OAM的类型(1.连接认证,2.持续性检验,3.路由跟踪,4.性能度量) SFC OA ...

  10. 11.struts2文件上传

    文件上传 1.上传单个文件 2.上传多个文件   1.上传单个文件 实现步骤: (1)导入一个Jar包:commons-io-1.3.2.jar.只所以要导入这个Jar包,是因为要用到一个工具类Fil ...