React Antd的验证- antd form表单一行多个组件并对其校验(一个FormItem中多个Input校验)

Posted 旋风小美女

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React Antd的验证- antd form表单一行多个组件并对其校验(一个FormItem中多个Input校验)相关的知识,希望对你有一定的参考价值。

实现效果如下:

当点击按钮的时候 对一个FormItem里的多个input/或者是input和select进行校验  同时通过Rol/Col实现布局

Rselect/input组件封装的组件如下field.js:

import React from \'react\';
import { Select, Input, Row, Col } from \'antd\';
import _ from \'underscore\';
import \'./index.less\';
const Option = Select.Option;
const uiPrefix = "certificate-field"
class CertificateField extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      yearlists: [],//时间下拉框列表
      cities: [],//城市下拉框列表
      years: undefined,
      cityId: undefined,
      warrantNumber: undefined,
    };
  }
  static defaultProps = {
    cities: [],
    yearlists: [],
    hasYear: true,
    hasCity: true,
    readonly: true,
    hasWarrantNum: true,
    years: (new Date()).getFullYear(),
    cityId: 1,
  }

  getStateFromProps(props) {
    let { value = {} } = props;
    return { ...this.parseDataFromInput(value) };
  }
  parseDataFromInput(value) {
    let { years, cityId, warrantNumber } = value;
    years = years ? (\'\' + years) : undefined;
    cityId = cityId ? (\'\' + cityId) : undefined;
    warrantNumber = warrantNumber ? (\'\' + warrantNumber) : undefined

    return { years, cityId, warrantNumber };
  }

  onBlur = () => {
    let { years, cityId, warrantNumber } = this.state;
    let yearlistsName = this.getTextFromValue("yearlist");
    let citieName = this.getTextFromValue("citie");
    const { onBlur } = this.props;
    if (onBlur) {
      const {
        hasYear,
        hasCity,
        hasWarrantNum,
      } = this.props;
      let unFull = true;
      if (unFull && hasYear == true && !years) {
        unFull = false;
      }
      if (unFull && hasCity == true && !cityId) {
        unFull = false;
      }
      if (unFull && hasWarrantNum == true && !warrantNumber) {
        unFull = false;
      }
      if (unFull) {
        onBlur(
          JSON.stringify({
            years,
            cityId,
            warrantNumber,
            // yearlistsName,
            // citieName,
          })
        )
      } else {
        onBlur(undefined)
      }
    }
  }

  getTextFromValue = (type) => {
    let resource;
    let value;
    let text = \'\';

    if (type === \'city\' || type === \'years\') {
      resource = this.state.cities;
      value = this.state.cityId;
    }
    else {
      resource = this.state[type + \'s\'];
      value = this.state[type + \'Id\'];
    }

    let item = null;
    if (resource !== undefined && resource.length > 0) {
      item = resource.find(({ id }) => id === +value);
    }

    text = text || \'\';
    return item ? item.text : text;
  }

  fireChange = () => {
    let { years, cityId, warrantNumber } = this.state;
    const { onChange } = this.props;
    if (onChange) {
      const {
        hasYear,
        hasCity,
        hasWarrantNum,
      } = this.props;
      let unFull = true;
      if (unFull && hasYear == true && !years) {
        unFull = false;
      }
      if (unFull && hasCity == true && !cityId) {
        unFull = false;
      }
      if (unFull && hasWarrantNum == true && !warrantNumber) {
        unFull = false;
      }
      if (unFull) {
        onChange(
          JSON.stringify({
            years,
            cityId,
            warrantNumber,
          }))
      } else {
        onChange(undefined)
      }
    }
  }
  getColSpan = () => {
    const result = {
      select: 4,
      input: 2
    }
    const {
      hasYear,
      hasCity,
    } = this.props;
    if (!hasYear) {
      result.input += 4
    }
    if (!hasCity) {
      result.input += 4
    }
    return result;

  }

  componentWillReceiveProps(nextProps) { // 父组件重传props时就会调用这个方法
    this.getStateFromProps(nextProps);
    const oldProps = this.props;
    let { years, cityId, warrantNumber } = nextProps;
    if (years != oldProps.years &&
      cityId != oldProps.cityId &&
      warrantNumber != oldProps.warrantNumber) {
      this.setState({
        years,
        cityId,
        warrantNumber
      }, () => {
        this.initData(nextProps)
        this.fireChange(nextProps)
      })
    }
  }

  componentDidMount() {
    let { years, cityId, warrantNumber } = this.props;
    this.setState({
      years,
      cityId,
      warrantNumber
    }, () => {
      this.initData(this.props)
      // this.fireChange(this.props)
    })
  }

  initData(props) {
    let { initSelectData = {} } = this.props;//获取初始化的值(时间/城市 下拉框的值)
    let { yearLists = [], cities = [] } = initSelectData;
    let currentYear = (new Date()).getFullYear();
    if (yearLists.length == 0) {
      const startYear = 2016;
      for (let i = 0; i <= currentYear - startYear; i++) {
        yearLists.push({ text: startYear + i, id: startYear + i })
      }
    }
    if (cities.length == 0) {
      cities = [{ text: "鹤岗市", id: 1 }]
    }
    this.setState({
      yearLists,
      cities,
    })
  }


  onyearsChange = (years, noEvent) => {
    years = \'\' + years;
    this.setState({ years },this.fireChange);
  }

  onCityChange = (cityId, noEvent) => {
    cityId = \'\' + cityId;
    this.setState({ cityId }, this.fireChange);
  }

  onwarrantNumberChange = (e) => {
    const warrantNumber = e.target.value;
    this.setState({ warrantNumber }, this.fireChange);
  }

  selectOptions = (constantsTypes, fieldOp) => {
    fieldOp = fieldOp || { key: \'id\', value: \'text\' };
    // {key: \'xxxx\', value: \'xxxx\'}
    if (!_.isArray(constantsTypes)) {
      const options = [];
      _.each(
        constantsTypes,
        (value, key) => {
          let trueValue;
          let disabled = false;
          if (_.isObject(value)) {
            trueValue = value.value;
            disabled = value.disabled;
          }
          else {
            trueValue = value;
          }
          return options.push(<Option key={key} value={key} disabled={disabled}>{trueValue}</Option>);
        }
      );
      return options;
    }
    // [{key: \'xxxx\', value: \'xxxx\'}]
    // [1, 3, 4]
    return constantsTypes.reduce(
      (options, value, key) => {
        let realKey;
        let display;
        if (_.isObject(value)) {
          realKey = `${value[fieldOp.key]}`;
          display = value[fieldOp.value];
        }
        else {
          realKey = `${key}`;
          display = value;
        }

        options.push(<Option key={realKey} value={realKey}>{display}</Option>);
        return options;
      },
      []
    );
  }


  render() {
    let {
      years,
      cityId,
      yearLists = [],
      cities = [],
      warrantNumber
    } = this.state;
    let {
      hasYear,
      hasCity,
      readonly = true,
      hasWarrantNum,
      detailPlaceholder,
    } = this.props;
    if (readonly) {
      cityId = this.getTextFromValue(\'city\')
    }
    const colSpan = this.getColSpan();
    return (
      <Row className={`${uiPrefix}`}>
        {hasYear &&
          <Col
            span={colSpan.select}
          >
            <Row>
              <Col span={22} style={{ paddingRigth: "0" }}>
                <Select
                  style={{ height: 32 }}
                  value={years}
                  placeholder="请选择"
                  onChange={this.onyearsChange}
                  onBlur={this.onBlur}
                >
                  {this.selectOptions(yearLists)}
                </Select>
              </Col>
            </Row>
          </Col>
        }
        {hasCity &&
          <Col span={colSpan.select}>
            <Row>
              <Col span={22}>
                <Select
                  disabled={readonly}
                  value={cityId}
                  placeholder="请选择"
                  onChange={this.onCityChange}
                  onBlur={this.onBlur}
                >
                  {this.selectOptions(cities)}
                </Select>
              </Col>
            </Row>
          </Col>
        }
        {
          hasWarrantNum &&
          <Col span={colSpan.select}>
            {/* <div className={`${uiPrefix}-select-item`}> */}
            {/* 不动产权第 */}
            <Input
              maxLength={16}
              // style={{ width: 120 }}
              value={warrantNumber}
              placeholder={detailPlaceholder}
              onChange={this.onwarrantNumberChange}
              onBlur={this.onBlur}
            />
            {/**/}
            {/* </div> */}
          </Col>
        }

      </Row>
    );
  }
}
export default CertificateField;

需要调用入口页面index.js:

import React from "react";
import { Form, Input, Button, Radio, message, Modal } from "antd";
import { CertificateField } from "components";
class Schhouse extends React.Component {
    onSearchHandle = () => {
        //注意validateFields里的fields,要和getFieldDecorator中的fields保持一致 否则拿不到值
        this.props.form.validateFields(["fields"], (err, fieldsValue) => {
            console.log(fieldsValue, "fieldsValue")
            if (err) {
                return;
            }
        })
    }

    render() {
        const { getFieldDecorator } = this.props.form;
        return (
            <>
                <Form>
                    <Form.Item label="标签">
                        {getFieldDecorator(\'fields\', {
                            rules: [{ required: true, message: \'请输入标签对应内容\' }],
                        })(
                            <CertificateField />
                        )}
                    </Form.Item>
                    <Form.Item>
                        <Button type="primary" htmlType="submit" onClick={this.onSearchHandle.bind(this)}>
                            查询并办理
                        </Button>
                    </Form.Item>
                </Form>
            </>
        )
    }
}

export default Form.create()(Schhouse);

非常完美!!!

 

以上是关于React Antd的验证- antd form表单一行多个组件并对其校验(一个FormItem中多个Input校验)的主要内容,如果未能解决你的问题,请参考以下文章

表单验证规则---antd

如何将redux与antd表单验证集成

antd 的 form resetFields

React-Antd4的Form表单校验

共享单车—— React后台管理系统开发手记:AntD Form基础组件

在 react-hook-form 中设置 DatePicker 的值(来自 antd)