具有值的行的重复功能

时间:2019-10-28 15:43:13

标签: javascript reactjs antd

我正在应用程序中重新创建此模块。我正在使用AntDesign。 但是我想拥有一个重复的功能,并获取已经填充的值。

enter image description here

这是我的代码,但是不起作用 Link

import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Form, Input, Icon, Button } from "antd";

let id = 0;

class DynamicFieldSet extends React.Component {
  remove = k => {
    const { form } = this.props;
    // can use data-binding to get
    const keys = form.getFieldValue("keys");
    // We need at least one passenger
    if (keys.length === 1) {
      return;
    }

    // can use data-binding to set
    form.setFieldsValue({
      keys: keys.filter(key => key !== k)
    });
  };

  add = () => {
    const { form } = this.props;
    // can use data-binding to get
    const keys = form.getFieldValue("keys");
    const nextKeys = keys.concat(id++);
    // can use data-binding to set
    // important! notify form to detect changes
    form.setFieldsValue({
      keys: nextKeys
    });
  };

  duplicate = k => {
    const { form } = this.props;
    const keys = form.getFieldValue("keys");
    form.setFieldsValue({
      keys: keys.find(key => key === k)
    });
  };

  handleSubmit = e => {
    e.preventDefault();
    this.props.form.validateFields((err, values) => {
      if (!err) {
        const { keys, names } = values;
        console.log("Received values of form: ", values);
        console.log("Merged values:", keys.map(key => names[key]));
      }
    });
  };

  render() {
    const { getFieldDecorator, getFieldValue } = this.props.form;
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 4 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 20 }
      }
    };
    const formItemLayoutWithOutLabel = {
      wrapperCol: {
        xs: { span: 24, offset: 0 },
        sm: { span: 20, offset: 4 }
      }
    };
    getFieldDecorator("keys", { initialValue: [] });
    const keys = getFieldValue("keys");
    const formItems = keys.map((k, index) => (
      <Form.Item
        {...(index === 0 ? formItemLayout : formItemLayoutWithOutLabel)}
        label={index === 0 ? "Passengers" : ""}
        required={false}
        key={k}
      >
        {getFieldDecorator(`names[${k}]`, {
          validateTrigger: ["onChange", "onBlur"],
          rules: [
            {
              required: true,
              whitespace: true,
              message: "Please input passenger's name or delete this field."
            }
          ]
        })(
          <Input
            placeholder="passenger name"
            style={{ width: "60%", marginRight: 8 }}
          />
        )}
        {keys.length > 1 ? (
          <div>
            <Icon
              className="dynamic-delete-button"
              type="minus-circle-o"
              onClick={() => this.remove(k)}
            />
            <Icon
              className="dynamic-delete-button"
              type="copy"
              onClick={() => this.duplicate(k)}
            />
          </div>
        ) : null}
      </Form.Item>
    ));
    return (
      <Form onSubmit={this.handleSubmit}>
        {formItems}
        <Form.Item {...formItemLayoutWithOutLabel}>
          <Button type="dashed" onClick={this.add} style={{ width: "60%" }}>
            <Icon type="plus" /> Add field
          </Button>
        </Form.Item>
        <Form.Item {...formItemLayoutWithOutLabel}>
          <Button type="primary" htmlType="submit">
            Submit
          </Button>
        </Form.Item>
      </Form>
    );
  }
}

const WrappedDynamicFieldSet = Form.create({ name: "dynamic_form_item" })(
  DynamicFieldSet
);
ReactDOM.render(
  <WrappedDynamicFieldSet />,
  document.getElementById("container")
);

1 个答案:

答案 0 :(得分:1)

在重复方法中,您将获得单击字段的keyindex。表单值中的keys数组可跟踪您拥有的字段数及其索引。表单值中的names数组跟踪这些字段中每个字段的值。在重复方法中,您需要通过添加到add one field数组来keys,然后通过添加到names数组来为该字段设置值。请参见下面的方法:

注意:在您的add方法中,使用keys.length而不是id进行递增。这将始终使所有键保持唯一性

add = () => {
    const { form } = this.props
    // can use data-binding to get
    const keys = form.getFieldValue("keys")
    const nextKeys = keys.concat(keys.length)
    // can use data-binding to set
    // important! notify form to detect changes
    form.setFieldsValue({
        keys: nextKeys
    })
}

duplicate = k => {
    const { form } = this.props

    // We are using keys to track number of fields
    // and using names to track the value of each field
    const { keys, names } = form.getFieldsValue()

    // We can use the key to access the value of the field for
    // for which the button was clicked
    const nameToDuplicate = names[k]

    /**
     * Add a key to 'keys' array in antd form to render extra field
     * Once the field is rendered we can add the name to the
     * 'names' array of antd form.
     *
     * Note: We add keys first and then add name in callback method because
     * we cannot set a value for a form field before rendering it.
     */
    const newKeys = [...keys, keys.length]

    form.setFieldsValue({ keys: newKeys }, () => {
        const newNames = [...names, nameToDuplicate]
        form.setFieldsValue({ names: newNames })
    })
}

Sandbox Link