项目实战, 动态增删 form 表单
前言
Hi,大家好,我是麦叔。今天老大让我做一个需求,我们的这个表单以前只支持录入一个检查器具。现在要求改为可以动态添加,满足录入多个器具。作为前端小菜的我来说,也是折腾了半天。在朋友的帮助下算是搞定了,顺利下思路,希望能帮到有需要的人。
效果图
首先,我们来看看效果图,点击“+”按钮,我们可以动态添加检查器具信息表单,理论上无限次动态添加。点击删除按钮,我们可以删除动态添加的表单。
实现思路
页面
首先我们来页面方面
页面基本就是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
页面
动态删除
/** * 删除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要和后台实体中的字段一一对应
后台代码
MedicalApply
实体中的字段和form表单提交的name一直,利用@ModelAttribute
进行绑定
@ResponseBody @PostMapping("/XXXXX") public Map<String, Object> saveMedical(@ModelAttribute MedicalApply medicalApply, Model model){ //处理业务逻辑 }
小结
本文主要介绍了利用Jquery
的clone()方法来实现表单的动态增删,希望对有需要的伙伴有帮助。
关于作者
大家好,我是麦叔,目前从事Java开发,前端和后端略懂一点。希望喜欢我的伙伴关注我的个人公众号,方便获取一手文章信息。当然也可以加我个人微信(下方右侧),大家交个朋友,谢谢大家对我的支持。
版权声明: 本文为 InfoQ 作者【麦叔】的原创文章。
原文链接:【http://xie.infoq.cn/article/a6052c4715291a255b5a348a9】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
麦叔
与其等待未来,不如创造未来 2020.04.10 加入
非科班程序员
评论