react实现动态增减表单项

在做项目的时候,甲方给的信息有限,网页的备案信息写成固定的,如下图所示
在这里插入图片描述
之后验收的时候,甲方要求把这个备案信息写成动态的,可以自增减,就去react组件库看看有没有具体的实现,果真有,具体实现如下:

import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Button, Form, Input, Card, Space, message} from 'antd';
import CustomForm from '@/components/Form';
import { FormattedMessage, useIntl } from 'umi';
import { saveRecordInfomation, getRecordInfomation } from '@/services/record'
import { useEffect } from 'react';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';

const formItemLayout = {
    labelCol: {
        xs: {
            span: 24,
        },
        sm: {
            span: 6,
        },
    },
    wrapperCol: {
        xs: {
            span: 24,
        },
        sm: {
            span: 14,
        },
    },
};

const RecordInformation = () => {

    const intl = useIntl()
    const [form] = Form.useForm();

    const onReset = () => {
        form.resetFields();
    };
    useEffect(() => {
        getRecordInfo()
        return () => { };
    }, []);

    const getRecordInfo = async () => {
        getRecordInfomation().then((res) => {
            if (res.code === 0) {
                form.setFieldsValue({
                    recordsInformation: res.data.map((item, index) => ({
                        ...item,
                        key: index,
                    })),
                });
            }
        });
    }

    const onFinish = async (forms) => {
        const res = await saveRecordInfomation(forms.recordsInformation)
        if (res.code === 0) {
            message.success(intl.formatMessage({ id: 'pages.cms.save.success' }))
            getRecordInfo()
        } else {
            message.error(intl.formatMessage({ id: 'pages.cms.save.fail' }))
        }
    }


    return (
        <PageHeaderWrapper ghost={false}>
            <div>
                <Card style={{ height: '95%', }}>
                    <Form
                        {...formItemLayout}
                        variant="filled"
                        style={{
                            maxWidth: 1000,
                        }}
                        form={form}
                        onFinish={onFinish}
                    >
                        <Form.List name="recordsInformation">
                            {(fields, { add, remove }) => (
                                <>
                                    {fields.map(({ key, name, ...restField }) => (
                                        <Space key={key} style={{ display: 'flex', marginBottom: 8, marginRight: 0, }} align="baseline" >
                                            <Form.Item
                                                {...restField}
                                                name={[name, 'label']}
                                                rules={[{ required: true, message: 'Missing first name' }]}
                                            >
                                                <Input placeholder={intl.formatMessage({ id: 'pages.record.info.content.public.net.example.filing'})} style={{ width:105,  textAlign: 'right', border:'none' }} />
                                            </Form.Item>
                                            <Form.Item
                                                {...restField}
                                                name={[name, 'value']}
                                                rules={[{ required: true, message: 'Missing last name' }]}
                                            >
                                                <Input placeholder={intl.formatMessage({ id: 'pages.record.info.content.public.net.example.filing.url'})} style={{ width:300,  }}/>
                                            </Form.Item>
                                            <MinusCircleOutlined onClick={() => remove(name)} />
                                        </Space>
                                    ))}
                                    <Form.Item >
                                        <Button style={{width: 405}} type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
                                            <FormattedMessage id='pages.record.info.content.add' />
                                        </Button>
                                    </Form.Item>
                                </>
                            )}
                        </Form.List>

                        <Form.Item
                            
                        >
                            <Space>
                                <Button type="primary" htmlType="submit">
                                    <FormattedMessage id='pages.save' />
                                </Button>
                            </Space>
                        </Form.Item>
                    </Form>
                </Card>

            </div>
        </PageHeaderWrapper>
    );
};

export default RecordInformation;

// record.js文件
import { request } from 'umi';
import { formatReqUrl } from '../../common';

export async function saveRecordInfomation(data) {
    console.log(data)
    return request('/beian',{method:'POST', data: data});
}

export async function getRecordInfomation() {
    return request('/beian',{method:'GET'});
}
    

前端向后端传送的是一个对象数组,也就是这种格式:[{label: ‘xxx’, value: ‘xxx’}]
后端用Go实现,因为每次新增的信息可能不一样,所以每次新增的时候,会先删除旧的数据,再插入。
代码如下:

// 定义结构体
type Beian struct {
	Label        string `bson:"label" json:"label"`
	Value        string `bson:"value" json:"value"`
	DefaultField `bson:",inline"`
}

// controller
func (ctl *BeianController) Post(c *gin.Context) resp.JSON {
	c.Set("log-opt", "创建beian")

	doc := []models.Beian{}
	if err := c.ShouldBind(&doc); err != nil {
		return resp.Error(http.StatusBadRequest, gin.H{}, err)
	}
	c.Set("log-content", models.Doc2string(doc))
	id, err := ctl.srv.Insert(doc)
	if err != nil {
		return resp.Error(http.StatusInternalServerError, gin.H{}, err)
	}

	return resp.Success(gin.H{"id": id})
}

//service
func (i *BeianServiceImpl) Insert(doc []models.Beian) (primitive.ObjectID, error) {
	ctx := context.Background()

	// 先删除
	_, err := i.m.DB.Collection(BeianColl).RemoveAll(ctx, bson.M{})
	if err != nil {
		return primitive.NilObjectID, err
	}

	// 再保存
	var insertedID primitive.ObjectID
	for _, info := range doc {
		result, err := i.m.DB.Collection(BeianColl).InsertOne(ctx, &info)
		if err != nil {
			return primitive.NilObjectID, err
		}
		if insertedID.IsZero() {
			insertedID = result.InsertedID.(primitive.ObjectID)
		}
	}

	return insertedID, nil
}

最终效果图如下:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用state来管理表单,通过setState方法动态添加或删除表单。 示例代码: ```jsx import React, { useState } from 'react'; function DynamicForm() { const [formFields, setFormFields] = useState([{ name: '', age: '' }]); // 初始表单 const handleAddFields = () => { setFormFields([...formFields, { name: '', age: '' }]); // 添加一表单 }; const handleRemoveFields = (index) => { const newFormFields = [...formFields]; newFormFields.splice(index, 1); // 删除指定位置的表单 setFormFields(newFormFields); }; const handleChange = (index, event) => { const { name, value } = event.target; const newFormFields = [...formFields]; newFormFields[index][name] = value; // 修改指定位置的表单的指定属性值 setFormFields(newFormFields); }; const handleSubmit = (event) => { event.preventDefault(); console.log(formFields); // 提交表单数据 }; return ( <form onSubmit={handleSubmit}> {formFields.map((formField, index) => ( <div key={index}> <input type="text" name="name" value={formField.name} onChange={(event) => handleChange(index, event)} /> <input type="text" name="age" value={formField.age} onChange={(event) => handleChange(index, event)} /> <button type="button" onClick={() => handleRemoveFields(index)}>删除</button> </div> ))} <button type="button" onClick={handleAddFields}>添加</button> <button type="submit">提交</button> </form> ); } export default DynamicForm; ``` 在上面的示例中,我们使用useState来管理表单的状态。初始表单为一个包含name和age属性的对象数组。通过handleAddFields和handleRemoveFields方法来动态添加和删除表单,这些方法都是通过setState方法更新表单状态来实现的。handleChange方法用于修改表单中的属性值,这个方法也是通过setState方法更新表单状态来实现的。handleSubmit方法用于提交表单数据。最后,我们在render函数中使用map方法遍历表单数组,动态渲染表单。每个表单都有一个删除按钮,点击按钮时会调用handleRemoveFields方法删除对应的表单。添加按钮则会调用handleAddFields方法添加一表单。提交按钮则会调用handleSubmit方法提交表单数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值