React+Antd implements an example of adding, deleting and modifying tables

React+Antd implements an example of adding, deleting and modifying tables

I recently wrote a small thing, imitating my original project written in Vue and changing it to react syntax. I wrote an editable table, and encountered some problems along the way. I plan to record the bugs. First, paste the effect diagram and code. The main use is react+antd

table, click edit, open the pop-up window, the pop-up window is a tab to switch to display different forms + editable tables, the operation bar "+" in the table, add a row of editable data in the table, edit, save, delete these operations will not be explained in detail nor the effect pictures

Table/index.js

import React, { useState }from 'react'
import { Row,Col,Card, Table, Tag, Divider, Modal, Button } from 'antd';
import ModalData from './model'


const App = (props) => {
 console.log(props,'----')
 const [isModalVisible, setIsModalVisible] = useState(false);
 const columns = [
  {
   title: 'Name',
   dataIndex: 'name',
   key: 'name',
   render: text => <a>{text}</a>,
  },
  {
   title: 'Age',
   dataIndex: 'age',
   key: 'age',
  },
  {
   title: 'Address',
   dataIndex: 'address',
   key: 'address',
  },
  {
   title: 'Tags',
   key: 'tags',
   dataIndex: 'tags',
   render: tags => (
    <label>
     {tags.map(tag => {
      let color = tag.length > 5 ? 'geekblue' : 'green';
      if (tag === 'loser') {
       color = 'volcano';
      }
      return (
       <Tag color={color} key={tag}>
        {tag.toUpperCase()}
       </Tag>
      );
     })}
    </label>
   ),
  },
  {
   title: 'Action',
   key: 'action',
   align:'center',
   render: (record) => (
    <label>
     <a onClick={() => showModal(record)}>Edit</a>
     <Divider type="vertical" />
     {/* <Button onClick={()=>showModal(record)} > Delete </Button> */}
     <a onClick={()=>showModal(record)} > Delete</a>
    </label>
   ),
  },
 ];
 const data = [
  {
   key: '1',
   name: 'John Brown',
   age: 32,
   address: 'New York No. 1 Lake Park',
   tags: ['nice', 'developer'],
  },
  {
   key: '2',
   name: 'Jim Green',
   age: 42,
   address: 'London No. 1 Lake Park',
   tags: ['loser'],
  },
  {
   key: '3',
   name: 'Joe Black',
   age: 32,
   address: 'Sidney No. 1 Lake Park',
   tags: ['cool', 'teacher'],
  }
 ];
 
 const showModal = (row) => {
  setIsModalVisible(true);
 };
 const handleCancel = () => {
  setIsModalVisible(false);
 }
 const handleOk = (form={},data) => {
  setIsModalVisible(false);
  console.log(form,data,'pp---')
 }

 

 return (
  <label>
   <Row gutter={16} className="gutter-row">
    <Col md={24}>
     <Card title="Basic table + simple pop-up box" bordered={false}>
      <Table columns={columns} dataSource={data} />
     </Card>
    </Col>
   </Row>
   {isModalVisible && <ModalData close={()=>{
    handleCancel()
   }} saveOk={(form,data)=>{ handleOk(form,data) }}/>}
   {/* {isModalVisible && <ModalData />} */}
  </label>
 );
};
const la = '111'
export default () => (
 <App/>
)

Table/model/index.js

import React from 'react'
import Basic from './modules/base'
import EditTableData from './modules/editTableData'
import { Modal, Tabs, Spin } from "antd";

export default class ModalData extends React.Component{
 constructor(){
  super()
  this.state = {
   isModalVisible:true,
   currentTab:'basicColumns',
   tableData:[]
  }
 }
 componentWillMount(){
  this.setState({
   isModalVisible: this.props.isModalVisible
  })
  this.basicColumns = [
   {title:'Operation type',editable:true,dataIndex:'name'},
   {title:'name',editable:true,dataIndex:'age'},
   {title:'description',editable:true,dataIndex:'address'}
  ]
  this.associationColumns = [
   {title:'Pre-operation',editable:true,dataIndex:'name'},
   {title:'Associated permissions',editable:true,dataIndex:'age'},
   {title:'Associated operations',editable:true,dataIndex:'address'}
  ]
  this.dataViewColumns = [
   {title:'field',editable:true,dataIndex:'name'},
   {title:'description',editable:true,dataIndex:'address'}
  ]
 }
 componentWillUpdate(){
  console.log(22)
 }
 componentDidMount(){
  console.log(11)
 }
 handleOk = () => {
  // console.log(this.tabData,'this.formRefThree.props')
  const form = this.formRef.props.form;
  form.validateFields((err, fieldsValue) => {
   if (!err) {
    console.log(this.tabData,'pp---00---');
    this.props.saveOk(fieldsValue,this.tabData)
   }
  });
 }
 saveTable(data){
  console.log(data,this.state.currentTab,'data---')
  this.tabData = {
   [this.state.currentTab]:data
  }

 }
 changeTab(key){
  console.log(key,'key---')
  this.setState({
   currentTab:key
  })
 }
 render(){
  
  return (
   <Modal
    title="Edit" 
    width={650}
    destroyOnClose
    visible
    onOk={ () => this.handleOk() } 
    onCancel={ () => this.props.close()}
   >
    <Tabs onChange={(key)=>this.changeTab(key)}>
     <Tabs.TabPane tab="Basic Information" key="basicColumns">
      <span>
       <Basic wrappedComponentRef={(form) => this.formRef = form}/>
       <EditTableData basicColumns={this.basicColumns} saveTable={(data)=>this.saveTable(data)}/>
      </span>
     </Tabs.TabPane>
 
     <Tabs.TabPane tab="Association Permissions" key="associationColumns">
      <EditTableData associationColumns={this.associationColumns} saveTable={(data)=>this.saveTable(data)}/>
     </Tabs.TabPane>
     <Tabs.TabPane tab="Data View" key="dataViewColumns">
      <EditTableData dataViewColumns={this.dataViewColumns} saveTable={(data)=>this.saveTable(data)}/>
     </Tabs.TabPane>
    </Tabs>
   </Modal>
  )
 }
}

Table/model/modules/base.js

import React from 'react'
import { Form, Input, Select, Radio } from 'antd';
const { Option } = Select;

// const Basic = (props) => {
class Basic extends React.Component{
 formRef = React.createRef();
 // const [form] = Form.useForm();
 onGenderChange(value){
  switch (value) {
   case 'male':
    this.props.form.setFieldsValue({
     note: 'Hi, man!',
    });
    return;

   case 'female':
    this.props.form.setFieldsValue({
     note: 'Hi, lady!',
    });
    return;

   case 'other':
    this.props.form.setFieldsValue({
     note: 'Hi there!',
    });
    return;
  }
 }
 onFinish(values){
  console.log(values);
  console.log(this.props.form.getFieldsValue,'09900--')
 }
 
 render(){
  console.log(this.props.form.getFieldValue('gender'),'990----')
  const { form } = this.props;
  const { getFieldDecorator, getFieldValue} = form; 
  return (
   <div>
    <Form ref={this.formRef} layout="inline" name="control-hooks" onFinish={this.onFinish.bind(this)}>
     <Form.Item label="Authorization ID" required>
      {getFieldDecorator("note")(<Input placeholder="Please enter"/>)}
     </Form.Item>
     <Form.Item label="Permission name" required>
     {getFieldDecorator("name")(<Input placeholder="Please enter"/>)}
     </Form.Item>
     <Form.Item label="requiredMark" name="Status" required>
      {getFieldDecorator("requiredMark")(
       <Radio.Group>
        <Radio.Button value="optional">Enable</Radio.Button>
        <Radio.Button value="disabled">Disable</Radio.Button>
       </Radio.Group>
      )}
     </Form.Item>
     <Form.Item name="gender" label="Category" required>
      {getFieldDecorator("gender")(
       <Select style={{width: '250px'}} placeholder="Please select" onChange={this.onGenderChange.bind(this)} allowClear >
        <Option value="male">api excuse</Option>
        <Option value="female">Tenant</Option>
        <Option value="other">System</Option>
       </Select>
      )}
     </Form.Item>
     {getFieldValue('gender') == 'other' && <Form.Item name="customizeGender" label="Note">
      {getFieldDecorator("customizeGender")(<Input />)}
     </Form.Item>} 
    </Form>
   </div>

  )
 }
}
export default Form.create()(Basic)

Table/model/modules/editTable.js

import React, { useState } from 'react';
import { Table, Input, InputNumber,Divider, Popconfirm, Form, Typography } from 'antd';
import {PlusSquareOutlined} from '@ant-design/icons';
const { Provider, Consumer } = React.createContext() // value transfer between components const originData = [];

for (let i = 0; i < 5; i++) {
 originData.push({
  key: i.toString(),
  name: `Edrward ${i}`,
  age: 32,
  address: `London Park no. ${i}`,
 });
}
class EditableCell extends React.Component{
 renderCell = ({getFieldDecorator}) => {
  const {
   editing, dataIndex, title, Inputs, record, index, children, ...restProps
  } = this.props
  return (
   <td {...restProps}>
    {editing ? (
     <Form.Item style={{ margin: 0, }} >
      {getFieldDecorator(dataIndex,{
       rules: [{
       required: true,
       message: 'Please enter'
      }],
      initialValue: record[dataIndex] 
      })(
      <Inputs />
      )}
     </Form.Item>
    ) : (
     children
    )}
   </td>
  );
 }
 render(){
  return <Consumer>{this.renderCell}</Consumer>
 }
}

class EditTableData extends React.Component{
 constructor(props){
  super(props)
  this.state = {
   data:originData,
   editingKey:''
  }
 }
 // Determine whether it is editable isEditing = record => record.key == this.state.editingKey

 // Initialization init(){
  console.log(this.props,'pp--')
  const data = this.props.basicColumns || this.props.dataViewColumns || this.props.associationColumns || []
  this.columns = [
   ...data,
   {
    title: ()=>{
     return <span>action<Divider type="vertical" /><PlusSquareOutlined style={{color:"#333"}} onClick={()=>this.addColumns()}/></span>
    },
    width:'20%',
    dataIndex: 'operation',
    render: (_, record) => {
     const { editingKey } = this.state
     const editable = this.isEditing(record);
     return editable ? (
      <span>
       <Consumer>
        {
         form => (
         <a onClick={() => this.save(form,record.key)} >
          Save
        }
       </Consumer>
       <Divider type="vertical" />
       <Popconfirm okText="Confirm" cancelText="Cancel" title="Are you sure you want to cancel?" onConfirm={this.cancel}>
        Cancel
       </Popconfirm>
      </span>
     ) : (
       <span>
        <a disabled={editingKey != ''} onClick={()=>this.edit(record.key)}>Edit</a>
        <Divider type="vertical" />
        <Popconfirm okText="Confirm" cancelText="Cancel" title="Are you sure you want to cancel?" onConfirm={()=>this.delete(record.key)}>
         <a>Delete</a>
        </Popconfirm>
       </span>
     );
    },
   },
  ]; 
 }
 // add addColumns = () => {
  const newData = [...this.state.data]
  newData.push({
   key: newData.length,
   name: ``,
   age: '',
   address: ``
  })
  this.setState({
   data:newData
  })
 }
 // Edit edit = (key) => {
  this.setState({
   editingKey:key
  })
 }
 // delete delete = (key) => {
  const newData = [...this.state.data]
  const index = newData.findIndex(item=>item.key == key)
  newData.splice(index,1)
  this.setState({
   data:newData
  })
 }
 // Save save = (form,key) => {
  form.validateFields((error,row)=>{
   if(error){
    return
   }
   const newData = [...this.state.data]
   const index = newData.findIndex(item=>item.key == key)
   if(index > -1){
    const item = newData[index]
    newData.splice(index,1,{
     ...item,...row
    })
   }
   this.setState({
    editingKey:'',
    data:newData
   })
   this.props.saveTable(newData)
  })

 }

 // Cancel cancel = () => {
  this.setState({
   editingKey: ''
  })
 }

 render(){
  this.init()
  console.log(this.columns,'columns')
  const columns = this.columns.map(col => {
   if(!col.editable){
    return col
   }
   return {
    ...col,
    onCell:record => ({
     record,
     Inputs:Input,
     dataIndex:col.dataIndex,
     title:col.title,
     editing:this.isEditing(record)
    })
   }
  })
  return (
   <Provider value={this.props.form}>
    <Table bordered style={{marginTop:'30px'}} components={{
     body:{
      cell:EditableCell
     }
    }} columns={columns} dataSource={this.state.data} pagination={false}/>
   </Provider>
  )
 }
}


export default Form.create()(EditTableData)

The above is the details of the example of using React+Antd to implement a table that can be added, deleted, and modified. For more information about how to use React+Antd to implement a table that can be added, deleted, and modified, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Detailed explanation of how to implement login function by combining React with Antd's Form component
  • React antd tabs switching causes repeated refresh of subcomponents
  • react+antd recursively implements tree directory operations
  • React uses antd form assignment to modify the operation of the pop-up box
  • React antd table rendering one or more pictures
  • How to pass pop-up form content to parent component in react-antd
  • Use antd's form component in the react project to dynamically set the value of the input box
  • Solve the Can't resolve ''./locale'' problem in React after installing antd (recommended)
  • React implements dynamic switching of antd online themes
  • React+Antd+Redux method to implement to-do events
  • Solution to invalid style loading on demand using antd in create-react-app

<<:  Upgrade MySQL 5.1 to 5.5.36 in CentOS

>>:  Summary of nginx configuration location method

Recommend

Detailed explanation of docker version es, milvus, minio startup commands

1. es startup command: docker run -itd -e TAKE_FI...

Summary of Linux Logical Volume Management (LVM) usage

Managing disk space is an important daily task fo...

How to build your own Nexus private server in Linux

This article describes how to build a Nexus priva...

javascript realizes 10-second countdown for payment

This article shares the specific code of javascri...

ES6 loop and iterable object examples

This article will examine the ES6 for ... of loop...

Steps for Django to connect to local MySQL database (pycharm)

Step 1: Change DATABASES in setting.py # Configur...

React implements the sample code of Radio component

This article aims to use the clearest structure t...

MySql 5.6.36 64-bit green version installation graphic tutorial

There are many articles about MySQL installation ...

Detailed explanation of MySQL redo log (redo log) and rollback log (undo logo)

Preface: The previous article described several c...

Robots.txt detailed introduction

Basic introduction to robots.txt Robots.txt is a p...

Nexus uses API to operate

Nexus provides RestApi, but some APIs still need ...

HTML basics - CSS style sheets, style attributes, format and layout details

1. position : fixed Locked position (relative to ...

ReactRouter implementation

ReactRouter implementation ReactRouter is the cor...

How to choose the right index in MySQL

Let’s take a look at a chestnut first EXPLAIN sel...