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

2,439 阅读2分钟

在这里插入图片描述

前言

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开发,前端和后端略懂一点。希望喜欢我的伙伴关注我的个人公众号,方便获取一手文章信息。当然也可以加我个人微信(下方右侧),大家交个朋友,谢谢大家对我的支持。