写点什么

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

用户头像
麦叔
关注
发布于: 2020 年 09 月 25 日
项目实战,动态增删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开发,前端和后端略懂一点。希望喜欢我的伙伴关注我的个人公众号,方便获取一手文章信息。当然也可以加我个人微信(下方右侧),大家交个朋友,谢谢大家对我的支持。





发布于: 2020 年 09 月 25 日阅读数: 75
用户头像

麦叔

关注

与其等待未来,不如创造未来 2020.04.10 加入

非科班程序员

评论

发布
暂无评论
项目实战,动态增删form表单