前言
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()方法来实现表单的动态增删,希望对有需要的伙伴有帮助。