首页 > 解决方案 > 有没有办法单独验证 ANT DESIGN Table 的每一列?

问题描述

我正在做的是我在 ant 设计表中呈现数据,现在当呈现错误数据时,每行的每一列都是可编辑的,例如电子邮件格式错误,应该有验证消息发送到电子邮件,表明电子邮件无效&当用户开始输入时,我还需要验证用于编辑的用户输入。就像当用户开始打字时,我还需要验证每个输入更改是正确的电子邮件还是错误的,同样,我需要为行的每一列使用自定义正则表达式,我希望我尽我所能来解决我的问题面对。

到目前为止我尝试过的内容如下。

1 - 当数据呈现到表中时,每行有两个可编辑的列。 数据被渲染

2 - 当用户开始编辑时 用户编辑

3 - 当文本框为空时验证失败我的目标是验证每个击键,验证通过错误消失时输入的电子邮件是否正确。 验证失败

以下是我到目前为止尝试过的代码

import React, { useContext, useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Table, Input, Button, Popconfirm, Form } from "antd";

const EditableContext = React.createContext();

const EditableRow = ({ index, ...props }) => {
  const [form] = Form.useForm();
  return (
    <Form form={form} component={false}>
      <EditableContext.Provider value={form}>
        <tr {...props} />
      </EditableContext.Provider>
    </Form>
  );
};

const EditableCell = ({
  title,
  editable,
  children,
  dataIndex,
  record,
  handleSave,
  ...restProps
}) => {
  const [editing, setEditing] = useState(false);
  const inputRef = useRef();
  const form = useContext(EditableContext);
  useEffect(() => {
    if (editing) {
      inputRef.current.focus();
    }
  }, [editing]);

  const toggleEdit = () => {
    setEditing(!editing);
    form.setFieldsValue({
      [dataIndex]: record[dataIndex]
    });
  };

  const save = async e => {
    try {
      const values = await form.validateFields();
      toggleEdit();
      handleSave({ ...record, ...values });
    } catch (errInfo) {
      console.log("Save failed:", errInfo);
    }
  };

  let childNode = children;

  if (editable) {
    childNode = editing ? (
      <Form.Item
        style={{
          margin: 0
        }}
        name={dataIndex}
        rules={[
          {
            required: true,
            message: `${title} is required.`
          }
        ]}
      >
        <Input ref={inputRef} onPressEnter={save} onBlur={save} />
      </Form.Item>
    ) : (
      <div
        className="editable-cell-value-wrap"
        style={{
          paddingRight: 24
        }}
        onClick={toggleEdit}
      >
        {children}
      </div>
    );
  }

  return <td {...restProps}>{childNode}</td>;
};

class EditableTable extends React.Component {
  constructor(props) {
    super(props);
    this.columns = [
      {
        title: "name",
        dataIndex: "name",
        width: "30%",
        editable: true
      },
      {
        title: "age",
        dataIndex: "age",
        editable: true
      },
      {
        title: "address",
        dataIndex: "address"
      },
      {
        title: "operation",
        dataIndex: "operation",
        render: (text, record) =>
          this.state.dataSource.length >= 1 ? (
            <Popconfirm
              title="Sure to delete?"
              onConfirm={() => this.handleDelete(record.key)}
            >
              <a>Delete</a>
            </Popconfirm>
          ) : null
      }
    ];
    this.state = {
      dataSource: [
        {
          key: "0",
          name: "Edward King 0",
          age: "32",
          address: "London, Park Lane no. 0"
        },
        {
          key: "1",
          name: "Edward King 1",
          age: "32",
          address: "London, Park Lane no. 1"
        }
      ],
      count: 2
    };
  }

  handleDelete = key => {
    const dataSource = [...this.state.dataSource];
    this.setState({
      dataSource: dataSource.filter(item => item.key !== key)
    });
  };

  handleAdd = () => {
    const { count, dataSource } = this.state;
    const newData = {
      key: count,
      name: `Edward King ${count}`,
      age: 32,
      address: `London, Park Lane no. ${count}`
    };
    this.setState({
      dataSource: [...dataSource, newData],
      count: count + 1
    });
  };

  handleSave = row => {
    const newData = [...this.state.dataSource];
    const index = newData.findIndex(item => row.key === item.key);
    const item = newData[index];
    newData.splice(index, 1, { ...item, ...row });
    this.setState({
      dataSource: newData
    });
  };

  render() {
    const { dataSource } = this.state;
    const components = {
      body: {
        row: EditableRow,
        cell: EditableCell
      }
    };
    const columns = this.columns.map(col => {
      if (!col.editable) {
        return col;
      }

      return {
        ...col,
        onCell: record => ({
          record,
          editable: col.editable,
          dataIndex: col.dataIndex,
          title: col.title,
          handleSave: this.handleSave
        })
      };
    });
    return (
      <div>
        <Button
          onClick={this.handleAdd}
          type="primary"
          style={{
            marginBottom: 16
          }}
        >
          Add a row
        </Button>
        <Table
          components={components}
          rowClassName={() => "editable-row"}
          bordered
          dataSource={dataSource}
          columns={columns}
        />
      </div>
    );
  }
}

ReactDOM.render(<EditableTable />, document.getElementById("container"));

CODESANDBOX 链接

我的目标:

1 - 呈现数据时,我需要在那里进行验证,就好像电子邮件不正确一样,那么该无效电子邮件将有效。

2 - 当用户开始输入时,它会在电子邮件正确验证消失时验证 Keystore。

3 - 会有更多的列,如电话,地址将有正则表达式我需要使用正则表达式分别验证每一行中的每一列。

我尽我所能描述我的问题任何我能提供的东西告诉我谢谢

标签: javascriptregexreactjsvalidation

解决方案


我只是通过在我的可编辑单元函数中使用 switch case 语句来解决这个问题,如下所示

 EditableCell = ({
    title,
    editable,
    children,
    dataIndex,
    record,

    ...restProps
  }) => {
    const [editing, setEditing] = useState(false);
    const inputRef = useRef();
    const form = useContext(EditableContext);
    useEffect(() => {
      if (editing) {
        inputRef.current.focus();
      }
    }, [editing]);

    const toggleEdit = () => {
      setEditing(!editing);
      form.setFieldsValue({
        [dataIndex]: record[dataIndex]
      });
    };

    let childNode = children;

    if (editable) {
      switch (dataIndex) {
        case "cName":
          {
            if (editing) {
              childNode = (
                <Form.Item
                  style={{
                    margin: 0
                  }}
                  name={dataIndex}
                  rules={[
                    {
                      required: true,

                      message: "Enter Name Please"
                    }
                  ]}
                >
                  <Input
                    ref={inputRef}
                    onChange={e => {
                      this.onChangeExelField(
                        record.key,
                        "cName",
                        e.target.value
                      );
                    }}
                  />
                </Form.Item>
              );
            } else {
              childNode = (
                <div
                  className="editable-cell-value-wrap"
                  style={{
                    paddingRight: 24
                  }}
                  onClick={toggleEdit}
                >
                  {children}
                </div>
              );
            }
          }
          break;
        case "cEmail":
          {
            if (editing) {
              childNode = (
                <Form.Item
                  style={{
                    margin: 0
                  }}
                  name={dataIndex}
                  rules={[
                    {
                      required: true,
                      type: "email",
                      message: "Enter Valid Email Address"
                    }
                  ]}
                >
                  <Input
                    ref={inputRef}
                    onChange={e => {
                      this.onChangeExelField(
                        record.key,
                        "cEmail",
                        e.target.value
                      );
                    }}
                  />
                </Form.Item>
              );
            } else if (
              !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(childNode[1])
            ) {
              childNode = (
                <div
                  className="editable-cell-value-wrap"
                  style={{
                    paddingRight: 24,
                    borderRadius: "3px",
                    border: "red solid 1px"
                  }}
                  onClick={toggleEdit}
                >
                  {children}
                </div>
              );
            } else {
              childNode = (
                <div
                  className="editable-cell-value-wrap"
                  style={{
                    paddingRight: 24
                  }}
                  onClick={toggleEdit}
                >
                  {children}
                </div>
              );
            }
          }
          break;
        case "cPhone":
          {
            if (editing) {
              childNode = (
                <Form.Item
                  style={{
                    margin: 0
                  }}
                  name={dataIndex}
                  rules={[
                    {
                      required: true,
                      pattern: new RegExp("^3[0-9+]{9}$"),
                      message: "Enter Correct Phone ( 3xxxxxxxxx )"
                    }
                  ]}
                >
                  <Input
                    ref={inputRef}
                    onChange={e => {
                      this.onChangeExelField(
                        record.key,
                        "cPhone",
                        e.target.value
                      );
                    }}
                  />
                </Form.Item>
              );
            } else if (!/^3[0-9+]{9}$/i.test(childNode[1])) {
              childNode = (
                <div
                  className="editable-cell-value-wrap"
                  style={{
                    paddingRight: 24,
                    borderRadius: "3px",
                    border: "red solid 1px"
                  }}
                  onClick={toggleEdit}
                >
                  {children}
                </div>
              );
            } else {
              childNode = (
                <div
                  className="editable-cell-value-wrap"
                  style={{
                    paddingRight: 24
                  }}
                  onClick={toggleEdit}
                >
                  {children}
                </div>
              );
            }
          }
          break;
        case "cAddress":
          {
            if (editing) {
              childNode = (
                <Form.Item
                  style={{
                    margin: 0
                  }}
                  name={dataIndex}
                  rules={[
                    {
                      required: true,
                      pattern: new RegExp("^[a-zA-Z0-9 _/#&+-||]{25,}$"),
                      message: "Address Must be 25 letters"
                    }
                  ]}
                >
                  <Input
                    ref={inputRef}
                    onChange={e => {
                      console.log(record);
                      this.onChangeExelField(
                        record.key,
                        "cAddress",
                        e.target.value
                      );
                    }}
                  />
                </Form.Item>
              );
            } else if (!/^[a-zA-Z0-9 _/#&+-||]{25,}$/i.test(childNode[1])) {
              childNode = (
                <div
                  className="editable-cell-value-wrap"
                  style={{
                    paddingRight: 24,
                    borderRadius: "3px",
                    border: "red solid 1px"
                  }}
                  onClick={toggleEdit}
                >
                  {children}
                </div>
              );
            } else {
              childNode = (
                <div
                  className="editable-cell-value-wrap"
                  style={{
                    paddingRight: 24
                  }}
                  onClick={toggleEdit}
                >
                  {children}
                </div>
              );
            }
          }
          break;
        case "cCity":
          {
            if (editing) {
              const options = [];
              this.props.cities.fetchedCities.docs.map(p => {
                options.push({ value: p._id, label: p.cityName });
              });

              childNode = (
                <Form.Item
                  style={{
                    margin: 0
                  }}
                  name={dataIndex}
                  rules={[
                    {
                      required: true
                    }
                  ]}
                >
                  <Select
                    ref={inputRef}
                    options={options}
                    onChange={e => {
                      this.onChangeExelField(record.key, "cCity", e.label);
                    }}
                  />
                </Form.Item>
              );
            } else if (record.invalidFields.includes("cCity")) {
              const options = [];
              this.props.cities.fetchedCities.docs.map(p => {
                options.push({ value: p._id, label: p.cityName });
              });
              childNode = (
                <div>
                  <Select
                    ref={inputRef}
                    options={options}
                    onChange={e => {
                      console.log(e);
                      this.onChangeExelField(record.key, "cCity", e.label);
                    }}
                  />
                </div>
              );
            } else {
              childNode = (
                <div
                  className="editable-cell-value-wrap"
                  style={{
                    paddingRight: 24
                  }}
                  onClick={toggleEdit}
                >
                  {children}
                </div>
              );
            }
          }
          break;
        case "cAmount":
          {
            if (editing) {
              childNode = (
                <Form.Item
                  style={{
                    margin: 0
                  }}
                  name={dataIndex}
                  rules={[
                    {
                      required: true,

                      message: "Enter Valid Amount"
                    }
                  ]}
                >
                  <Input
                    ref={inputRef}
                    onChange={e => {
                      this.onChangeExelField(
                        record.key,
                        "cAmount",
                        e.target.value
                      );
                    }}
                  />
                </Form.Item>
              );
            } else {
              childNode = (
                <div
                  className="editable-cell-value-wrap"
                  style={{
                    paddingRight: 24
                  }}
                  onClick={toggleEdit}
                >
                  {children}
                </div>
              );
            }
          }
          break;

        default:
          return null;
      }
    }

    return <td {...restProps}>{childNode}</td>;
  };

推荐阅读