一聚教程网:一个值得你收藏的教程网站

热门教程

react antd实现动态增减表单代码示例

时间:2022-06-29 02:23:59 编辑:袖梨 来源:一聚教程网

本篇文章小编给大家分享一下react antd实现动态增减表单代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。

用的是antd3的版本,3和4的表单有点不一样,不过差别应该不大。

需求:

1、选择类型切换展示固定的模板

2、通过新增字段可以动态增减表单里面的每一行

3、控制每一行的字段是否需要必填

4、编辑时候回填参数

效果图:

部分关键代码:

import React, { Component } from 'react';
import styles from './index.less';
import {
  Table,
  Button,
  Select,
  Popconfirm,
  Modal,
  Form,
  Input,
  Radio,
  Row,
  Col, Tooltip,
  Icon,
  message,
  Pagination, InputNumber,
} from 'antd';

const Option = Select.Option;
const FormItem = Form.Item;

let id = 0;

@Form.create()
class Index extends Component {
  marketId = 0;
  state = {
    selectType: '',
    orderType: 1,  //文章1  地图2
    typeLoading: false,
    isEdit: false,
    lookVisible: false,
    visible: false,
    pageSize: 10,
    pageNum: 1,
    keyWord: '',
    row: {},
    typeList: {},
    mock: {},
    mapType: [{
      'fieldName': 'name',
      'isImg': 0,
      'order': 0,
      'remarks': '名称',
    }, {
      'fieldName': 'label',
      'isImg': 0,
      'order': 0,
      'remarks': '标签',
    }, {
      'fieldName': 'lon',
      'isImg': 0,
      'order': 0,
      'remarks': '经度',
    }, {
      'fieldName': 'lat',
      'isImg': 0,
      'order': 0,
      'remarks': '纬度',
    }],
    articleType: [{
      'fieldName': 'name',
      'isImg': 0,
      'order': 0,
      'remarks': '名称',
    }, {
      'fieldName': 'label',
      'isImg': 0,
      'order': 0,
      'remarks': '标签',
    }],
  };
/**
   * 将动表单态值生成需要的数据格式
   * @param values
   * @returns {[]}
   */
  createValues = (values) => {
    const { row } = this.state;
    const data = [];
    const newValues = { // 用新的对象承载提交的数据
      ...values,
    };
    const fieldNameData = []; // 保存fieldName值
    const remarksData = []; // 保存remarks值
    const isImgData = []; // 保存isImg值
    const orderData = []; // 保存orderData值
    const fieldName = RegExp(/fieldName/);
    const remarks = RegExp(/remarks/);
    const isImg = RegExp(/isImg/);
    for (const key in newValues) {
      if (fieldName.test(key)) {
        fieldNameData.push(newValues[key]);
      }
    }
    for (const key in newValues) {
      if (remarks.test(key)) {
        remarksData.push(newValues[key]);
      }
    }
    for (const key in newValues) {
      if (isImg.test(key)) {
        isImgData.push(newValues[key]);
      }
    }
    for (const key in newValues) {
      if (isImg.test(key)) {
        orderData.push(newValues[key]);
      }
    }
    fieldNameData.forEach((item, index) => {
      data.push({
        fieldName: item,
        remarks: remarksData[index],
        isImg: isImgData[index],
        order: orderData[index],
        id: row.dataType ? row.dataType.id : '',
      });
    });
    return data;
  };

  handleOk = e => {
    this.props.form.validateFields((err, values) => {
      if (!err) {
        const { row, isEdit } = this.state;
        const params = {
          dataType: {
            name: values.name,
            type: values.type,
            id: row.dataType ? row.dataType.id : '',
          },
          typeFields: [],
        };
        params.typeFields = this.createValues(values);
        if (isEdit) {
          editType(params).then(res => {
            if (res.code === 0) {
              message.info('修改成功');
              this.setState({
                visible: false,
                isEdit: false,
              });
              this.fetchTypeList();
              this.props.form.resetFields();
            }
          });
        } else {
          addType(params).then(res => {
            if (res.code === 0) {
              message.info('新增成功');
              this.setState({
                visible: false,
                isEdit: false,
              });
              this.fetchTypeList();
              this.props.form.resetFields();
            }
          });
        }
      }
    });
  };

  lookOrEditTypeModal = (flag, record) => {
    const { articleType, mapType } = this.state;
    if (flag === 'add') {  //添加默认为文章模板
      this.marketId = articleType.length + 1;  //设置动态key标记长度
      this.setState({
        visible: true,
        row: { typeFields: articleType },
      });
    } else if (flag === 'edit') {
      this.setState({
        visible: true,
      });
      getType({ dataTypeId: record.id }).then(res => {
        if (res.code === 0) {
          this.marketId = res.data.typeFields.length + 1;  //设置动态key标记长度
          this.setState({
            row: res.data,
            isEdit: flag === 'edit',
          });
        }
      });
    } else {
      this.setState({
        lookVisible: true,
      });
      getType({ dataTypeId: record.id }).then(res => {
        if (res.code === 0) {
          this.setState({
            row: res.data,
          });
        }
      });
    }
  };


  onChangeType = (value) => {
    const { form } = this.props;
    const { orderType, row, articleType, mapType } = this.state;
    this.props.form.resetFields();

    const params = {};
    if (value === 1) {  //文章类型
      params['typeFields'] = articleType;
      this.marketId = articleType.length + 1;
    } else {
      params['typeFields'] = mapType;
      this.marketId = mapType.length + 1;
    }
    this.setState({
      row: params,
      orderType: value,
    });
  };
//删除方法!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  removeFile = k => {
    const { form } = this.props;
    const keys = form.getFieldValue('keys');
    if (keys.length === 1) {
      return;
    }
    form.setFieldsValue({
      keys: keys.filter(key => key !== k),
    });
  };
//添加方法!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  addFile = () => {
    const { form } = this.props;
    const keys = form.getFieldValue('keys');
    const nextKeys = keys.concat(this.marketId++);
    form.setFieldsValue({
      keys: nextKeys,
    });
  };

  judgeIsTemplet = (data) => {
    if (!data) {
      return false;
    }
    if ((data.fieldName === 'lat') || (data.fieldName === 'lon') || (data.fieldName === 'label') || (data.fieldName === 'name')) {
      return true;
    }
  };
  handleValidator = (rule, val, callback) => {
    if (!val) {
      callback();
    }
    let validateResult = /^[5A-Za-z0-9-_]+$/.test(val);
    if (!validateResult) {
      callback('请输入正确表字段');
    }
    callback();
  };

  columns = [
    {
      title: '类型名称',
      dataIndex: 'name',
      key: 'name',
      width: 500,
    },
    {
      title: '所属类型',
      dataIndex: 'type',
      key: 'type',
      render: (text) => {
        return text === 1 ? '文章' : '地图';
      },
    },
    {
      title: '操作',
      dataIndex: 'address',
      key: 'address',
      render: (text, record) => {
        return 
this.deleteTypeClick(record)}>
; }, }, ]; render() { const { selectType, typeLoading, mock, row, isEdit, typeList, keyWord, lookVisible } = this.state; const { getFieldDecorator, getFieldValue } = this.props.form; let typeFields = row.typeFields || []; const initData = []; typeFields.forEach((item, index) => {//根据真实数据,设置默认keys数组 initData.push(index); }); getFieldDecorator('keys', { initialValue: initData }); //给表单增加keys字段,并设置默认值,这里编辑时候可以生成编辑回填的效果。 const keys = getFieldValue('keys'); const formItems = keys.map((k) => ( {getFieldDecorator(`fieldName_${k}`, { initialValue: row.typeFields[k] ? row.typeFields[k].fieldName : '', validateTrigger: ['onChange', 'onBlur'], //校验子节点值的时机 rules: [{ required: true, message: '请输入英文字段!', }, { validator: this.handleValidator, }], })()} {getFieldDecorator(`remarks_${k}`, { initialValue: row.typeFields[k] ? row.typeFields[k].remarks : '', validateTrigger: ['onChange', 'onBlur'], rules: [{ required: true, message: '请输入中文名称!', }], })()} {getFieldDecorator(`order_${k}`, { initialValue: row.typeFields[k] ? row.typeFields[k].order : 0, })()} {getFieldDecorator(`isImg_${k}`, { initialValue: row.typeFields[k] ? row.typeFields[k].isImg : 0, rules: [{ required: true, }], })( )} {!this.judgeIsTemplet(row.typeFields[k]) ? ( this.removeFile(k)} title='删除'/> ) : null} )); return (
{getFieldDecorator('type', { initialValue: row.dataType ? row.dataType.type : 1, rules: [{ required: true, }], })()} {getFieldDecorator('name', { initialValue: row.dataType ? row.dataType.name : '', rules: [{ required: true, message: '请输入类型名称!', }], })()} {formItems}
); } } export default Index;

关键地方是设置一个marketID作为动态添加的key,然后用他的值作为动态key。(千万不要用数组的下标index来作为key)!

热门栏目