antd typescript 可编辑单元格

时间:2019-05-21
本文章向大家介绍antd typescript 可编辑单元格,主要包括antd typescript 可编辑单元格使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
import { Row, Col, Select, Table, Input, Popconfirm, Button, Form } from 'antd';
import * as React from 'react'
const FormItem = Form.Item;
const EditableContext = React.createContext({});

const EditableRow = ({ form, index, ...props }: any) => (
  <EditableContext.Provider value={form}>
    <tr {...props} />
  </EditableContext.Provider>
);

const EditableFormRow = Form.create()(EditableRow);

class EditableCell extends React.Component<any, any> {
  public state = {
    editing: false,
  }
  public editable: any;
  public input: any;
  public cell: any;
  public form: any;

  public componentDidMount() {
    console.log(this.props.editable);
    if (this.props.editable) {
      document.addEventListener('click', this.handleClickOutside, true);
    }
  }

  public componentWillUnmount() {
    if (this.props.editable) {
      document.removeEventListener('click', this.handleClickOutside, true);
    }
  }

  public toggleEdit = () => {
    const editing = !this.state.editing;
    this.setState({ editing }, () => {
      if (editing) {
        this.input.focus();
      }
    });
  }

  public handleClickOutside = (e: any) => {

    const { editing } = this.state;
    if (editing && this.cell !== e.target && !this.cell.contains(e.target)) {
      this.save();
    }
  }

  public save = () => {
    const { record, handleSave }: any = this.props;
    this.form.validateFields((error: any, values: any) => {
      if (error) {
        return;
      }
      this.toggleEdit();
      handleSave({ ...record, ...values });
    });
  }

  public render() {
    const { editing } = this.state;
    const {
      editable,
      dataIndex,
      title,
      record,
      index,
      handleSave,
      ...restProps
    }: any = this.props;
    console.log(this.props);
    return (
      <td ref={node => (this.cell = node)} {...restProps}>
        {editable ? (
          <EditableContext.Consumer>
            {(form) => {
              this.form = form;
              return (
                editing ? (
                  <FormItem style={{ margin: 0 }}>
                    {this.form.getFieldDecorator(dataIndex, {
                      rules: [{
                        required: true,
                        message: `${title} is required.`,
                      }],
                      initialValue: record[dataIndex],
                    })(
                      <Input
                        ref={node => (this.input = node)}
                        onPressEnter={this.save}
                      />
                    )}
                  </FormItem>
                ) : (
                    <div
                      className="editable-cell-value-wrap"
                      style={{ paddingRight: 24 }}
                      onClick={this.toggleEdit}
                    >
                      {restProps.children}
                    </div>
                  )
              );
            }}
          </EditableContext.Consumer>
        ) : restProps.children}
      </td>
    );
  }
}

export class InputContentConfigurator extends React.Component<any, any> {
  public dataSource: any;
  public columns: any;
  public constructor(props: any) {
    super(props);
    this.state = {
      dataSource: [{
        key: 0,
        name: 'Edward King 0',
        checkrules: '32',
        defaultValue: 'null',
      }, {
        key: 1,
        name: 'Edward King 1',
        checkrules: '32',
        defaultValue: 'null',
      }],
      count: 2,
    };


    this.columns = [{
      title: 'name',
      dataIndex: 'name',
      width: '30%',
      editable: true,
    }, {
      title: 'checkrules',
      dataIndex: 'checkrules',
      editable: true,
    }, {
      title: 'defaultValue',
      dataIndex: 'defaultValue',
      editable: true,
    }
      , {
      title: 'operation',
      dataIndex: 'operation',
      render: (text: any, record: any) => {
        return (
          this.state.dataSource.length >= 1
            ? (
              <Popconfirm title="Sure to delete?" onConfirm={() => this.handleDelete(record.key)}>
                <a href="javascript:;">Delete</a>
              </Popconfirm>
            ) : null
        );
      },
    }
    ];
  }

  public handleDelete = (key: any) => {
    console.log(this.props);
    const { dataSource }: any = { ...this.state };
    this.setState({ dataSource: dataSource.filter((item: any) => item.key !== key) });

  }

  public handleAdd = () => {
    const { count, dataSource }: any = { ...this.state };
    const newData = {
      key: count,
      name: count,
      checkrules: '请输入',
      defaultValue: '请输入',
    };
    this.setState({
      dataSource: [...dataSource, newData],
      count: count + 1,
    });
  }

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

  public render() {
    const { dataSource }: any = { ...this.state };
    const components = {
      body: {
        row: EditableFormRow,
        cell: EditableCell,
      },
    };

    const columns = this.columns.map((col: any) => {
      if (!col.editable) {
        return col;
      }
      return {
        ...col,
        onCell: (record: any) => ({
          record,
          editable: col.editable,
          dataIndex: col.dataIndex,
          title: col.title,
          handleSave: this.handleSave,
        }),
      };
    });
    return (
      <div>
        <h2>Input content configurator</h2>
        <Row>
          <Col span={6}>
            <Form.Item label="选择类型:" labelCol={{ span: 6 }} wrapperCol={{ span: 12 }} required={true}>
              <Select defaultValue={0}>
                <Select.Option value={0}>List</Select.Option>
                <Select.Option value={1}>String</Select.Option>
              </Select>
            </Form.Item>
          </Col>
          <Col span={6}>
            <Form.Item label="输入对象名字:" labelCol={{ span: 8 }} wrapperCol={{ span: 12 }} required={true}>
              <Input
                placeholder="请输入对象的名字"
              />
            </Form.Item>
          </Col>
        </Row>
        <Button onClick={this.handleAdd} type="primary" >
          Add a row
        </Button>
        <Table
          components={components}
          dataSource={dataSource}
          columns={columns}
        />
      </div>
    );
  }
}

原文地址:https://www.cnblogs.com/Denvue/p/10900892.html