项目实战,动态增删form表单

麦洛 等级 509 0 0

项目实战,动态增删form表单

前言

Hi,大家好,我是麦叔。今天老大让我做一个需求,我们的这个表单以前只支持录入一个检查器具。现在要求改为可以动态添加,满足录入多个器具。作为前端小菜的我来说,也是折腾了半天。在朋友的帮助下算是搞定了,顺利下思路,希望能帮到有需要的人。

效果图

首先,我们来看看效果图,点击“+”按钮,我们可以动态添加检查器具信息表单,理论上无限次动态添加。点击删除按钮,我们可以删除动态添加的表单。

项目实战,动态增删form表单

实现思路

页面

首先我们来页面方面

页面基本就是form表单基本写法,但是这里有一个细节,采用了嵌套form表单,分别是 id="applyForm"id="checkBody0" 的表单。

为什么要采用嵌套form表单?我们将需要动态添加的内容放到子form表单,可以利用Jquery.serializeArray()方法快速获取每个动态添加的form表单的值。

<div class="medical_treatment">
    <!--固定部分-->
    <form action="" method="post" autocomplete="off" id="applyForm">
        <table id="tableId" border="0" cellspacing="0" cellpadding="0">
            <tr>
                <th class="table_t" colspan="4">XXXXXXXXXXXXX</th>
            </tr>
            <tr>
                <th class="paragraph_t" colspan="4">主体信息</th>
            </tr>
            <tr>
                <th>单位名称</th>
                <td colspan="3"><input type="text" name="legalName" id="legalName" placeholder="请输入单位名称"/></td>
            </tr>
            <tr>
                <th>唯一性标识</th>
                <td colspan="3"><input type="text" name="uniCode" id="uniCode"placeholder="(组织机构代码或社会统一信用代码)" /></td>
            </tr>
            <tr>
                <th>市/州</th>
                <td>
                    <select name="parentAreaCode" id="parentAreaCode" onchange="getAreaByPId(this.value)">
                        <option value="">请选择</option>
                        <option th:each="item:${areaList}" th:value="${item.id}" th:text="${item.name}"></option>
                    </select>
                </td>
                <th>区/县</th>
                <td>
                    <select name="areaCode" id="areaCode">
                        <option value="">请选择</option>
                    </select>
                </td>
            </tr>
            <tr>
                <th>详细地址</th>
                <td colspan="3"><input type="text" name="address" id="address"  placeholder="请输入详细地址"/></td>
            </tr>
            <tr>
                <th>联系人</th>
                <td><input type="text" name="linker" id="linker" placeholder="请输入联系人"/></td>
                <th>联系电话</th>
                <td><input type="text" name="linkPhone" id="linkPhone" placeholder="请输入联系电话"/></td>
            </tr>
        </table>
    </form>
    <!--存储form表单数量-->
    <input type="hidden" name="num">
    <div id="milo">
        <form action="" method="post" autocomplete="off" id="checkBody0">
            <table>
                <tr>
                    <th class="paragraph_t" colspan="4" >检定器具信息
                        <div class="layui-btn-group" style="float:right">
                            <button type="button" class="layui-btn layui-btn-normal layui-btn-sm" onclick="addFrom();"><i class="layui-icon"></i></button>
                            <button id="deleteRow" style="display: none" type="button" class="layui-btn layui-btn-danger layui-btn-sm" onclick="deleteFrom();"><i class="layui-icon"></i></button>
                        </div>
                    </th>
                </tr>
                <!--第一份-->
                <tr>
                    <th>仪器名称</th>
                    <td><input type="text" name="instrumentName" id="instrumentName" placeholder="请输入仪器名称"/></td>
                    <th>仪器数量</th>
                    <td><input type="text" name="instrumentNum" id="instrumentNum" placeholder="请输入仪器数量"/></td>
                </tr>
                <tr>
                    <th>型号规格</th>
                    <td colspan="3"><input type="text" name="instrumentSpeci" id="instrumentSpeci" placeholder="请输入型号规格"/></td>
                </tr>
                <tr>
                    <th>出厂编号(选填)</th>
                    <td colspan="3"><input type="text" name="factoryNumber" id="factoryNumber" placeholder="请输入出厂编号"/></td>
                </tr>
                <tr>
                    <th>是否为强检计量器具</th>
                    <td colspan="3" style="text-align: center;">
                        <label><input type="radio" name="isForce" id="isForce1" value="1" checked/>是</label>
                        <label><input type="radio" name="isForce" id="isForce2" value="0" />否</label>
                    </td>
                </tr>
            </table>
        </form>
    </div>
    <button type="button" class="submit-button" onclick="saveMedical();">提交</button>
</div>

动态添加

动态添加过程中需要注意的问题:

  • 动态添加的form表单id要唯一,方面后期获取表单值
  • 动态添加的form表单input置为空
  • 删除按钮不能出现在第一个子form表单
    /**
     * 克隆form
     */
    function addFrom() {
        //子form表单的数量
        let length = $("form").length - 1;
        //要克隆的form表单
        let $form = $("#checkBody0");
        //克隆好的form表单
        let newForm = $form.clone();
        //设置动态id
        newForm.attr("id",'checkBody'+length)
        newForm.find(":input").not(":button").each(function (i) { //循环新克隆form表单在里边找到所有的input标签,
            if ($(this).not(":radio").length > 0) {
                $(this).val(""); //给不是radio框的inputvalue赋值为空
            }
        });
        //追加
        $("#milo").append(newForm);
        //重新获取子form表单的数量
        var showlength = $("form").length - 1;
        //如果数量大于2,删除按钮显示
        if (showlength >= 2) {
            let $id = $('[id=deleteRow]');
            $id.last().show();
        }
    }

我们来看看添加后的html页面

项目实战,动态增删form表单

动态删除

/**
 * 删除from
 */
    function deleteFrom() {
        //获取子form表单数量
        let length = $("form").length - 1;
        //获取最后一个子form表单位置
        let tab = $("form:eq(" + length + ")");
        tab.remove(); //删除
        let showlength = $("form").length - 1;
        //隐藏删除按钮
        if (showlength <= 1) {
            $("#deleteRow").hide();
        }
    }

表单提交

因为我们的页面是嵌套form表单,问题的难点就是如何获取动态添加子表单的值,我们是利用在动态添加时候设置的id来判断,所以要保证id具有规律性。

    function saveMedical() {
        //获取基础数据
        let basicData = $("#applyForm").serializeArray();
        //定义数组,接收动态添加的子form表单的值
        let newData = []
        let length = $("form").length - 1;
        //获取子form表单的值
        for (let i = 0; i < length; i++) {
            if ($("#checkBody"+i).serialize() !== '') {
                //根据id获取
                let newFormData = $("#checkBody"+i).serializeArray();
                //更加serializeArray获取后的格式重新拼装,方面后台处理数据
                let newFormObj = {};
                for (let j = 0; j <newFormData.length ; j++) {
                    let Element = newFormData[j];
                    let name1 = Element.name;
                    let value = Element.value;
                    newFormObj[name1] = value;
                }
                newData.push(JSON.stringify(newFormObj))//追加数组  只追加不为空的form(未删除的form)
            }
        }
        let checkBodyObj = {}
        checkBodyObj.name = 'checkBody'
        checkBodyObj.value = JSON.stringify(newData);
        basicData.push(checkBodyObj)
        console.dir(basicData)
        if(verifyData()){
            $.ajax({
                type: "post",
                cache: false,
                url: "",
                data: basicData,
                dataType: "json",
                success: function(data){
                    if("OK" == data.code){
                        setTimeout(reloadPage,3000);
                        top.layer.msg(data.msg, {icon: 1});
                    }else{
                        top.layer.msg(data.msg, {icon: 2});
                    }
                }
            });
        }
    }

处理后的数据:这里的name要和后台实体中的字段一一对应

项目实战,动态增删form表单

后台代码

MedicalApply实体中的字段和form表单提交的name一直,利用@ModelAttribute进行绑定

    @ResponseBody
    @PostMapping("/XXXXX")
    public Map<String, Object> saveMedical(@ModelAttribute MedicalApply medicalApply, Model model){
    //处理业务逻辑
    }

小结

本文主要介绍了利用Jquery的clone()方法来实现表单的动态增删,希望对有需要的伙伴有帮助。

收藏
评论区

相关推荐

1 Java内存区域与内存溢出异常
1 java虚拟机对内存的管理 java虚拟机在执行java程序的时候把内存分为若干个不同的区,这些区各自有不同的用处,以及创建和销毁时间. 有的区随着虚拟机的启动而启动,有的区则依赖用户线程的启动和结束而启动和结束. 根据java虚拟机规范,java虚拟机将内存分为下面几个部分:如下图 image(https://imghelloworld.o
项目实战,动态增删form表单
前言 Hi,大家好,我是麦叔。今天老大让我做一个需求,我们的这个表单以前只支持录入一个检查器具。现在要求改为可以动态添加,满足录入多个器具。作为前
一文搞懂什么是HTTP与HTTPS
(https://blog.csdn.net/petterp/article/details/102779257)Http与Https的区别。 在最近的开发中,深感网络相关基础知识薄弱,于是趁周末好好总结一
Java核心技术 之安装环境 踏出第一步
Java JDK安装与配置 1、下载 官网地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html (1)点击DOWNLOAD 这里写图片描述(https://imghelloworld.osscnbeijing.aliyuncs.com/4
20 张图彻底弄懂 HTTPS 的原理
前言 近年来各大公司对信息安全传输越来越重视,也逐步把网站升级到 HTTPS 了,那么大家知道 HTTPS 的原理是怎样的吗,到底是它是如何确保信息安全传输的?网上挺多介绍 HTTPS,但我发现总是或多或少有些点有些遗漏,没有讲全,今天试图由浅入深地把 HTTPS 讲明白,相信大家看完一定能掌握 HTTPS 的原理,本文大纲如下: HTTP 为什么不安全
二 Java利用等待/通知机制实现一个线程池
接着上一篇博客的 一Java线程的等待/通知模型(http://www.cnblogs.com/start1225/p/5866575.html "一 java线程的等待/通知模型")  ,没有看过的建议先看一下。下面我们用等待通知机制来实现一个线程池. (https://www.helloworld.net/p/XJXfgbimvcjd) 本
关于 Ant Design Form 校验无效的问题
关键词: Ant Design v4.0.2 Form Validation Invalid 校验无效<a name"9pt4x"</a 情景使用 React Typescript Ant Design 重构公司一反洗钱平台部分页面,其一表单需要验证,但是按照 Ant Design Form 中的 Demo 实现后并不效果。<a n
【Flutter实战】输入框和表单
3.7 输入框及表单Material组件库中提供了输入框组件TextField和表单组件Form。下面我们分别介绍一下。 3.7.1 TextFieldTextField用于文本输入,它提供了很多属性,我们先简单介绍一下主要属性的作用,然后通过几个示例来演示一下关键属性的用法。dartconst TextField({ ...
https://cloud.tencent.com/developer/article/write/1830331
一、目标今天的目标是这个sign和appcode 二、步骤 Jadx没法上了app加了某梆的企业版,Jadx表示无能为力了。 FRIDADEXDumpDexDump出来,木有找到有效的信息。 Wallbreaker葫芦娃的Wallbreaker可以做些带壳分析,不过这个样本,用Frida的Spawn模式可以载入,Attach模式会失败。而直接用Objecti
cpu分析利器 — async-profiler
本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star。 简介asyncprofiler是一款采集分析java性能的工具,翻译一下github上的项目介绍:asyncprofiler是一款没有Safepoint bias problem的低开销java采集分析器,它利用HotSpot特殊的api来收集栈信息以及
Java面试真题解析火爆全网,讲的太透彻了
8.15 一面 (60min) 自我介绍,为什么投客户端 python和java有什么区别 java内存模型 gc讲讲 http https区别 cookie,session https握手过程 对称非对称加密算法?哪个效率高? tcp握手要三次,挥手要几次,为什么 进程和线程,描述一下 进程通信方式 线程同步
BAT这种大厂履历意味着什么?面试篇
8.15 一面 (60min) 自我介绍,为什么投客户端 python和java有什么区别 java内存模型 gc讲讲 http https区别 cookie,session https握手过程 对称非对称加密算法?哪个效率高? tcp握手要三次,挥手要几次,为什么 进程和线程,描述一下 进程通信方式 线程同步
一篇文章浅析Django Form组件相关知识
前言在上一篇时,我们小试牛刀了以下Django Form组件的使用,,没来得及的小伙伴可以一起看看。但是你可能会有很多疑问,并不知道怎么使用。并且知道Form组件的功能。 生成HTML标签。 验证提交的数据。 保留提交之前的数据。 所以本篇就接着上次的继续,来一起学习以下Django Form组件如何使用。 Form组件的
AtomicStampedReference是怎样解决CAS的ABA问题
本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star。 什么是ABA问题但凡对Java有一点深入就会知道 CAS,即 compareAndSwap。在Java中使用 Unsafe 类提供的native方法可以直接操作内存,其中就有对compareAndSwap的实现。javapublic final nati
一篇文章带你了解Django Form组件(入门篇)
前言Hey,大家好呀,我是码农,星期八。本次咱们来get一个新技能,Form组件。Form组件主要用于验证表单数据。为什么需要Form组件注:Form组件,只适用于,前后端未分离的项目中,主要用于验证表单数据,所以,关键字是表单!!!比如像哔哩哔哩的注册界面。我点击注册,它不仅仅可以知道我的注册昵称是否存在,密码是否小于6位,手机号格式错误。 还会把错误信