Recently I wrote a little thing that mimics my original project written in Vue and changes it to react grammar. I wrote an editable form, stumbled along the way, and wanted to record the bugs. First the renderings and code paste up, the main use is react+ ANTd
Click “Edit” to open the popover window. In the popover window, TAB switches to display different forms, form + editable table. The operation bar “+” in the table adds a row of editable data in the table
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,The '-')
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 popup" 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/>
)
Copy the code
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(a)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:'Front operation',editable:true,dataIndex:'name'},
{title:'Associated permissions',editable:true,dataIndex:'age'},
{title:'Associated operations',editable:true,dataIndex:'address'}]this.dataViewColumns = [
{title:'fields',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="Associated 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>
)
}
}
Copy the code
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="Permission identification" 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="State" 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="Classification" required>
{getFieldDecorator("gender")(
<Select style={{width: '250px'}} placeholder="Please select" onChange={this.onGenderChange.bind(this)} allowClear >
<Option value="male"</Option> <Option value="female"> Tenant </Option> <Option value="other"} </Form.Item> {getFieldValue();'gender') = ='other' && <Form.Item name="customizeGender" label="Note">
{getFieldDecorator("customizeGender")(<Input />)}
</Form.Item>}
</Form>
</div>
)
}
}
export default Form.create()(Basic)
Copy the code
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()// Pass values 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]
})(
)}
</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 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> Operation <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={() => thisDivider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider"vertical" />
<Popconfirm okText="Confirm" cancelText="Cancel" title="Are you sure to cancel?" onConfirm={this<span> <a disabled={editingKey! <span> <a disabled={editingKey! =' '} onClick={()=>thisDivider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider type= Divider Divider"vertical" />
<Popconfirm okText="Confirm" cancelText="Cancel" title="Are you sure to cancel?" onConfirm={()=>thisDelete (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)
Copy the code