
前言
Hi,大家好,我是麦叔。今天老大让我做一个需求,我们的这个表单以前只支持录入一个检查器具。现在要求改为可以动态添加,满足录入多个器具。作为前端小菜的我来说,也是折腾了半天。在朋友的帮助下算是搞定了,顺利下思路,希望能帮到有需要的人。
效果图
首先,我们来看看效果图,点击“+”按钮,我们可以动态添加检查器具信息表单,理论上无限次动态添加。点击删除按钮,我们可以删除动态添加的表单。

实现思路
页面
首先我们来页面方面
页面基本就是form表单基本写法,但是这里有一个细节,采用了嵌套form表单,分别是 id="applyForm" 和 id="checkBody0" 的表单。
为什么要采用嵌套form表单?我们将需要动态添加的内容放到子form表单,可以利用Jquery.serializeArray()方法快速获取每个动态添加的form表单的值。
1<div class="medical_treatment"> 2 <!--固定部分--> 3 <form action="" method="post" autocomplete="off" id="applyForm"> 4 <table id="tableId" border="0" cellspacing="0" cellpadding="0"> 5 <tr> 6 <th class="table_t" colspan="4">XXXXXXXXXXXXX</th> 7 </tr> 8 <tr> 9 <th class="paragraph_t" colspan="4">主体信息</th> 10 </tr> 11 <tr> 12 <th>单位名称</th> 13 <td colspan="3"><input type="text" name="legalName" id="legalName" placeholder="请输入单位名称"/></td> 14 </tr> 15 <tr> 16 <th>唯一性标识</th> 17 <td colspan="3"><input type="text" name="uniCode" id="uniCode"placeholder="(组织机构代码或社会统一信用代码)" /></td> 18 </tr> 19 <tr> 20 <th>市/州</th> 21 <td> 22 <select name="parentAreaCode" id="parentAreaCode" onchange="getAreaByPId(this.value)"> 23 <option value="">请选择</option> 24 <option th:each="item:${areaList}" th:value="${item.id}" th:text="${item.name}"></option> 25 </select> 26 </td> 27 <th>区/县</th> 28 <td> 29 <select name="areaCode" id="areaCode"> 30 <option value="">请选择</option> 31 </select> 32 </td> 33 </tr> 34 <tr> 35 <th>详细地址</th> 36 <td colspan="3"><input type="text" name="address" id="address" placeholder="请输入详细地址"/></td> 37 </tr> 38 <tr> 39 <th>联系人</th> 40 <td><input type="text" name="linker" id="linker" placeholder="请输入联系人"/></td> 41 <th>联系电话</th> 42 <td><input type="text" name="linkPhone" id="linkPhone" placeholder="请输入联系电话"/></td> 43 </tr> 44 </table> 45 </form> 46 <!--存储form表单数量--> 47 <input type="hidden" name="num"> 48 <div id="milo"> 49 <form action="" method="post" autocomplete="off" id="checkBody0"> 50 <table> 51 <tr> 52 <th class="paragraph_t" colspan="4" >检定器具信息 53 <div class="layui-btn-group" style="float:right"> 54 <button type="button" class="layui-btn layui-btn-normal layui-btn-sm" onclick="addFrom();"><i class="layui-icon"></i></button> 55 <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> 56 </div> 57 </th> 58 </tr> 59 <!--第一份--> 60 <tr> 61 <th>仪器名称</th> 62 <td><input type="text" name="instrumentName" id="instrumentName" placeholder="请输入仪器名称"/></td> 63 <th>仪器数量</th> 64 <td><input type="text" name="instrumentNum" id="instrumentNum" placeholder="请输入仪器数量"/></td> 65 </tr> 66 <tr> 67 <th>型号规格</th> 68 <td colspan="3"><input type="text" name="instrumentSpeci" id="instrumentSpeci" placeholder="请输入型号规格"/></td> 69 </tr> 70 <tr> 71 <th>出厂编号(选填)</th> 72 <td colspan="3"><input type="text" name="factoryNumber" id="factoryNumber" placeholder="请输入出厂编号"/></td> 73 </tr> 74 <tr> 75 <th>是否为强检计量器具</th> 76 <td colspan="3" style="text-align: center;"> 77 <label><input type="radio" name="isForce" id="isForce1" value="1" checked/>是</label> 78 <label><input type="radio" name="isForce" id="isForce2" value="0" />否</label> 79 </td> 80 </tr> 81 </table> 82 </form> 83 </div> 84 <button type="button" class="submit-button" onclick="saveMedical();">提交</button> 85</div>
动态添加
动态添加过程中需要注意的问题:
- 动态添加的form表单id要唯一,方面后期获取表单值
- 动态添加的form表单input置为空
- 删除按钮不能出现在第一个子form表单
1 /** 2 * 克隆form 3 */ 4 function addFrom() { 5 //子form表单的数量 6 let length = $("form").length - 1; 7 //要克隆的form表单 8 let $form = $("#checkBody0"); 9 //克隆好的form表单 10 let newForm = $form.clone(); 11 //设置动态id 12 newForm.attr("id",'checkBody'+length) 13 newForm.find(":input").not(":button").each(function (i) { //循环新克隆form表单在里边找到所有的input标签, 14 if ($(this).not(":radio").length > 0) { 15 $(this).val(""); //给不是radio框的inputvalue赋值为空 16 } 17 }); 18 //追加 19 $("#milo").append(newForm); 20 //重新获取子form表单的数量 21 var showlength = $("form").length - 1; 22 //如果数量大于2,删除按钮显示 23 if (showlength >= 2) { 24 let $id = $('[id=deleteRow]'); 25 $id.last().show(); 26 } 27 }
我们来看看添加后的html页面

动态删除
1/** 2 * 删除from 3 */ 4 function deleteFrom() { 5 //获取子form表单数量 6 let length = $("form").length - 1; 7 //获取最后一个子form表单位置 8 let tab = $("form:eq(" + length + ")"); 9 tab.remove(); //删除 10 let showlength = $("form").length - 1; 11 //隐藏删除按钮 12 if (showlength <= 1) { 13 $("#deleteRow").hide(); 14 } 15 }
表单提交
因为我们的页面是嵌套form表单,问题的难点就是如何获取动态添加子表单的值,我们是利用在动态添加时候设置的id来判断,所以要保证id具有规律性。
1 function saveMedical() { 2 //获取基础数据 3 let basicData = $("#applyForm").serializeArray(); 4 //定义数组,接收动态添加的子form表单的值 5 let newData = [] 6 let length = $("form").length - 1; 7 //获取子form表单的值 8 for (let i = 0; i < length; i++) { 9 if ($("#checkBody"+i).serialize() !== '') { 10 //根据id获取 11 let newFormData = $("#checkBody"+i).serializeArray(); 12 //更加serializeArray获取后的格式重新拼装,方面后台处理数据 13 let newFormObj = {}; 14 for (let j = 0; j <newFormData.length ; j++) { 15 let Element = newFormData[j]; 16 let name1 = Element.name; 17 let value = Element.value; 18 newFormObj[name1] = value; 19 } 20 newData.push(JSON.stringify(newFormObj))//追加数组 只追加不为空的form(未删除的form) 21 } 22 } 23 let checkBodyObj = {} 24 checkBodyObj.name = 'checkBody' 25 checkBodyObj.value = JSON.stringify(newData); 26 basicData.push(checkBodyObj) 27 console.dir(basicData) 28 if(verifyData()){ 29 $.ajax({ 30 type: "post", 31 cache: false, 32 url: "", 33 data: basicData, 34 dataType: "json", 35 success: function(data){ 36 if("OK" == data.code){ 37 setTimeout(reloadPage,3000); 38 top.layer.msg(data.msg, {icon: 1}); 39 }else{ 40 top.layer.msg(data.msg, {icon: 2}); 41 } 42 } 43 }); 44 } 45 }
处理后的数据:这里的name要和后台实体中的字段一一对应

后台代码
MedicalApply实体中的字段和form表单提交的name一直,利用@ModelAttribute进行绑定
1 @ResponseBody 2 @PostMapping("/XXXXX") 3 public Map<String, Object> saveMedical(@ModelAttribute MedicalApply medicalApply, Model model){ 4 //处理业务逻辑 5 }
小结
本文主要介绍了利用Jquery的clone()方法来实现表单的动态增删,希望对有需要的伙伴有帮助。
