乐趣区

关于javascript:基于antd动态增减表单进行新增和编辑操作

以下为最终展现款式:

antd 的版本用的是 3.X 的版本,各位依据版本批改对应的代码
上代码:

import React from "react";
import {Input, Form, Button, Icon} from "antd";
import styles from '../index.scss'
const formItemLayout = {labelCol: { span: 6},
    wrapperCol: {span: 18}
};
let id = 0;

class K8S extends React.Component {componentDidMount() {const {data, form} = this.props;
        this.props.onRef && this.props.onRef(this);
        // 初始化 id
        id = 0; 
        // 赋值 
        form.setFieldsValue({'namespace': data.namespace}); }

    // 新增 namespace
    add = (k) => {const { form} = this.props;
        let keys = form.getFieldValue('keys');
        // 这里依据点击的下标进行插入操作
        keys.splice(indexOf(keys,k) + 1, 0, id++);
        form.setFieldsValue({keys: keys,});
     };

    // 移除 namespace
    remove = k => {const { form} = this.props;
        const keys = form.getFieldValue('keys');
        if (keys.length === 1) {return;}
        form.setFieldsValue({keys: keys.filter(key => key !== k),
        });
    };
    
    // 初始化获取 key
    getInitialKeys(){const {data} = this.props;
        let nextKeys = [];
        for(let i = 0; i < data.namespace.length; i ++){nextKeys.push(i)
            id++;
        }
        return nextKeys;
    }
    
    // form 表单数据
    getFields() {const { getFieldDecorator, getFieldValue} = this.props.form;
        const {data} = this.props;
        const formItemLayoutWithOutLabel = {
            wrapperCol: {xs: { span: 24, offset: 0},
                sm: {span: 20, offset: 4},
            },
        };
        // 判断是否有值传进来
        if (data.namespace) {getFieldDecorator('keys', {'initialValue': this.getInitialKeys()});
        } else {getFieldDecorator('keys', {'initialValue': [0]});
            id++;
        }
        const keys = getFieldValue('keys');
        const formItems = keys.map((k, index) => (<Form.Item style={{position: 'relative'}}
                {...(index === 0 ? formItemLayout : formItemLayoutWithOutLabel)}
                label={index === 0 ? 'namespace' : ''}
                required={true}
                key={k}
            >
                 {getFieldDecorator(`namespace[${k}]`, {validateTrigger: ['onChange', 'onBlur'],
                    rules: [
                        {
                            required: true,
                            whitespace: true,
                            message: "请输出 namespace",
                        },
                    ],
                })(<Input placeholder="请输出 namespace" style={{width: '450px'}} />)}
                <Icon className={styles.dynamicAddButton} type="plus-circle" onClick={() => this.add(k)}/>
                {keys.length > 1 ? (<Icon className={styles.dynamicDeleteButton} type="minus-circle-o" onClick={() => this.remove(k)}/>) : null}
            </Form.Item>
        ));
        return (
            <>
                {formItems}
                <Form.Item {...formItemLayoutWithOutLabel}></Form.Item>
            </>
        )
    }
    handleSubmit = (e) => {e && e.preventDefault && e.preventDefault();
        this.props.form.validateFields((err, values) => {if (!err) {console.log(values)
                this.props.onSubmit(values);
            }
        })
    }
    render() {
        return (<div className={styles.k8s}>
                <Form onSubmit={this.handleSubmit} {...formItemLayout} >
                    {this.getFields()}
                    <div style={{height: '32px'}}>
                        <div style={{float: 'right'}}>
                            <Button type="primary" htmlType="submit"> 确认 </Button>
                        </div>
                    </div>
                </Form>
            </div>
        )
    }
}
const K8SDetail = Form.create()(K8S);
export default K8SDetail;

css 款式批改

.k8s{
    :global{
        .anticon-minus-circle-o, .anticon-plus-circle {
            cursor: pointer;
            position: absolute;
            top: -1px;
            right: -65px;
            font-size: 24px;
            color: #999;
            transition: all 0.3s;
        }
        .anticon-plus-circle{right: -30px;}
        .anticon-minus-circle-o:hover,.anticon-plus-circle:hover {color: #777;}
        .anticon-minus-circle-o[disabled],.anticon-plus-circle[disabled] {
            cursor: not-allowed;
            opacity: 0.5;
        }
        .ant-form-item-control{
            width: 450px;
            float: right;
        }
    }
}

这样就实现了以上的需要,依照可进行编辑和新增两种模式,默认显示一个空的输出。可依据地位插入和删除。
留神:有个小 bug 残留,每次 id 新增都会以 + 2 的状态递增,因为不影响应用也没认真排查

退出移动版