展示:

动态表头 mysql数据库设计_动态表头 mysql数据库设计

图例说明:这个表格在模态框表单中,提交表单,将数据插入数据库。
需求说明:我的情景是一对多,表单填主表数据,表格写从表数据。页面为主表的数据列表,后边为编辑按钮,点击编辑弹出模态框(当然页面也有添加按钮,点击同样弹出模态框,实现新建功能)
技术栈:ajax、js、javaweb的表现层controller、H5、(bootsrap不重要)

现在说一下代码的实现:
增加:
模态框里有内容和一个表格(只有头),点击增加按钮js增加一行表格(多次点击增加多条),td内置input,填入数据,点击保存,js获取所有数据,发送给controller,存入数据库。
删除:
点击删除按钮,直接发送请求携带从表数据id,删除(删除按钮的点击事件其实可以将id放数组里,再点击保存时完整的去数据库修改主和从表,因为当时着急,没有想到,以后有机会再写吧。)
回显:
动态插入表格,将数据放入

一、增加代码如下

bootstrap模态框 重点在table (其他位置保留,方便理解)

<!-- 模态框(Modal) -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModallabel" aria-hidden="true"
     data-backdrop="static" data-keyboard="false">
    <div class="modal-dialog" style="width: 60%">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                <h4 class="modal-title" id="myModallabel">添加生产成品</h4>
            </div>
            <div class="modal-body">

                <fieldset>
                    <form class="form-horizontal" id="myform" role="form" action="" method="post">
                        <div class="form-group">
                            <label class="col-sm-2 control-label">设备编号
                            </label>
                            <div class="col-sm-10">
                                <input class="form-control" id="devNum" name="devNum" type="text">
                                <span style="color: red" id="col"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-sm-2 control-label">设备类型
                            </label>
                            <div class="col-sm-10">
                                <select id="devType" class="form-control" name="devType">
                                    <c:forEach items="${listBydev}" var="ls">
                                        <option>${ls.devType}</option>
                                    </c:forEach>
                                </select>
                            </div>
                        </div>

                        <div class="form-group">
                            <label class="col-sm-2 control-label">客户公司
                            </label>
                            <div class="col-sm-10">
                                <select id="customerUnitId" class="form-control" name="customerUnitId">
                                    <c:forEach items="${customerUnits}" var="cu">
                                        <option value="${cu.id}">${cu.companyName}</option>
                                    </c:forEach>
                                </select>
                            </div>
                        </div>

                        <div class="form-group">
                            <label class="col-sm-2 control-label">负责人:</label>
                            <div class="col-sm-4">
                                <input class="form-control" type="text" name="personCharge" id="personCharge"
                                       value="<%=request.getSession().getAttribute("username")%>" readonly>
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-sm-2 control-label">日期
                            </label>
                            <div class="col-sm-10">
                                <input class="form-control" id="createDate" name="createDate" type="text" readonly>
                            </div>
                        </div>

                        <table class="table table-striped table-hover table-bordered" border="1px;">
                            <thead class="thead-light">
                                <tr class="proSon">
                                    <td colspan="1">序号</td>
                                    <td>内容</td>
                                    <td>数量</td>
                                    <td>进度</td>
                                    <td>创建时间</td>
                                    <td>备注</td>
                                    <td>
                                        <button type="button" class="btn btn-success btn-sm" onclick="addProSon()">增加</button>
                                    </td>
                                </tr>
                            </thead>
                            <tbody id="proSon">
                               <%--如果是一个页面,并且使用jsp,那这样回显更好
                                <c:forEach items="${finProSonList}" var="ProSon">
                                    <tr>
                                        <td colspan="1">${ProSon.ordinal}</td>
                                        <td>${ProSon.content}</td>
                                        <td>${ProSon.amount}</td>
                                        <td>${ProSon.schedule}</td>
                                        <td>${ProSon.remarks}</td>
                                        <td>${ProSon.createDate}</td>
                                        <td>
                                            <input type="button" value="删除" class="btn btn-danger btn-sm"  onclick="del(${ProSon.id})">
                                        </td>
                                    </tr>
                                </c:forEach>--%>
                            </tbody>
                        </table>
                        <div class="form-group">
                            <label class="col-sm-2 control-label">
                                备注
                            </label>
                            <div class="col-sm-10">
                                <textarea class="form-control" rows="3" id="remarks" name=remarks></textarea>                            </div>
                        </div>
                        <input type="hidden" name="id" id="id"/>
                        </div>
                    </form>
                </fieldset>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                    <button type="button" id="upDev" class="btn btn-primary">提交更改</button>
                    <button type="button" id="addDev" class="btn btn-primary" onclick="create()">保存</button>
                </div>
            </div>

        </div>
    </div>
</div>

js

1、增加表格行的按钮点击方法
function addProSon() {
    //创建tr元素
    var trElemnet = document.createElement("tr");
    //创建td元素
    var td1Element = document.createElement("td");
    var td2Element = document.createElement("td");
    var td3Element = document.createElement("td");
    var td4Element = document.createElement("td");
    var td5Element = document.createElement("td");
    var td6Element = document.createElement("td");
    var td7Element = document.createElement("td");
    //将数据添加到td元素
    // td1Element.innerHTML = "";
    td2Element.innerHTML = "<input class='form-control content' >";
    td3Element.innerHTML = "<input class='form-control amount' type='number'>";
    td4Element.innerHTML = "<input class='form-control schedule' >";
    td5Element.innerHTML = "<input class='form-control createDate' type='date'>";
    td6Element.innerHTML = "<input class='form-control remarks' >";
    //创建按钮
    var delElement = document.createElement("input");
    delElement.type = "button";
    delElement.value = "删除";
    delElement.className = "btn btn-danger btn-sm";
    //为按钮添加单击事件
    delElement.onclick = function () {
        //删除按钮所在的tr对象
        trElemnet.parentNode.removeChild(trElemnet);
    };
    td7Element.appendChild(delElement);
    //将td元素添加到tr元素中
    trElemnet.appendChild(td1Element);
    trElemnet.appendChild(td2Element);
    trElemnet.appendChild(td3Element);
    trElemnet.appendChild(td4Element);
    trElemnet.appendChild(td5Element);
    trElemnet.appendChild(td6Element);
    trElemnet.appendChild(td7Element);
    //将tr元素添加到tbody元素中
    // let products = document.getElementById("products");
    // document.getElementById("mytable").insertBefore(trElemnet,products);
    document.getElementById("proSon").appendChild(trElemnet);
}
===========================================================================
2、表单提交按钮的触发方法:ajax发送数据进行保存
var add = [];
function create() {
    $("#proSon input:text,input[type=number],input[type=date]").each(
        function () {
            var val = $(this).val();
            // console.info(val);
            add.push(val);
        }
    );
    // console.info(add);
    var addpush = [];
    if (add.length != 0) {
        var countInLine = 5;//一行几个数
        for (var i = 0; i < add.length; i++) {
            if (i % countInLine == 0) {
                var obj = new Object();
                obj.content = add[i];
                obj.amount = add[i + 1];
                obj.schedule = add[i + 2];
                obj.createDate = add[i + 3];
                obj.remarks = add[i + 4];
                addpush.push(obj);
            }
        }
        // console.info(addpush)
    }
    $.ajax({
        type: "POST",
        url: path + "/site/savaFinPro",
        data: $('#myform').serialize()+ "&add=" + JSON.stringify(addpush),
        dataType: "text",
        success: function (data) {
            if (data == "success") {
                alertShow("添加成功", path + "/site/findFinPro");
            } else if (data == "err") {
                alertShow("添加失败");
            }
        },
        error: function () {
            alertShow("服务器忙");
        }
    });
}

表现层controller

@RequestMapping(value = "/savaFinPro")
    @ResponseBody
    public String savaFinPro(finPro f, String add) {
        try {
            int i = IndexService.savaFinPro(f);
            if (i > 0) {
                Map<String, Object> proSonMap = new HashMap<>();
                Map<String, Object> map = new HashMap<>();
                List<finPro> finProAll = IndexService.findFinProAll(map);
                proSonMap.put("finisproId",finProAll.get(0).getId());
                JSONArray json=  JSONArray.fromObject(add);
                for (int j = 0; j < json.size()-2; j++) {
                    net.sf.json.JSONObject js=  json.getJSONObject(j);
                    proSonMap.put("ordinal",j+1);
                    proSonMap.put("content",js.get("content"));
                    proSonMap.put("amount",js.get("amount"));
                    proSonMap.put("schedule",js.get("schedule"));
                    proSonMap.put("remarks",js.get("remarks"));
                    proSonMap.put("createDate",js.get("createDate"));
                    Integer k = IndexService.insertProSon(proSonMap);
                }
                return "success";
            } else {
                return "err";
            }
        } catch (Exception e) {
            logger.info(e.getMessage(), e);
        }
        return null;
    }

值得说明的是:获取刚插入最新一条数据的id不要去查,我这里有些特殊,先写了,建议:
xml中
将如下代码放入中的开始部分(mybaitis),打个debug,走一步运行完插入sql,回来看一下你的插入的实体类id,就是刚插入的数据的id。

<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
    SELECT LAST_INSERT_ID()
</selectKey>

具体想了解去查查,这边不多做介绍了,不然跑题了。。。

二、回显并删除代码如下

点击页面内数据的编辑按钮(也就是主表),弹出模态框之前,进行回显,并绑定删除

function del(id) {
    // console.info(id);
    $.ajax({
        type: "POST",
        url: path + "/site/deleteProSonByid",
        data: {
            id:id
        },
        success: function (data) {
            if (data == "success") {
                //删除按钮所在的tr对象
                trElemnet.parentNode.removeChild(trElemnet);
            } else if (data == "err") {

            }
        }
    });
}


function updateDev(id) {
    $.ajax({
        type: "POST",
        url: path + "/site/finProSon",
        data: {"finisproId": id},
        dataType: "json",
        success: function (data) {
            delBaby();
            for (var i = 0; i < data.length; i++) {
                //创建tr元素
                var trElemnet = document.createElement("tr");
                //创建td元素
                var td0Element = document.createElement("td");
                td0Element.style.display='none';
                var td1Element = document.createElement("td");
                var td2Element = document.createElement("td");
                var td3Element = document.createElement("td");
                var td4Element = document.createElement("td");
                var td5Element = document.createElement("td");
                var td6Element = document.createElement("td");
                var td7Element = document.createElement("td");
                //将数据添加到td元素
                // td1Element.innerHTML = "";
                // console.info(data[i].id);
                td0Element.innerHTML = data[i].id;
                td1Element.innerHTML = i+1;
                td2Element.innerHTML = data[i].content;
                td3Element.innerHTML = data[i].amount;
                td4Element.innerHTML = data[i].schedule;
                td5Element.innerHTML = data[i].createDate;
                td6Element.innerHTML = data[i].remarks;
                //创建按钮
                var delElement = document.createElement("input");
                delElement.type = "button";
                delElement.value = "删除";
                delElement.className = "btn btn-danger btn-sm";
                //为按钮添加单击事件
                delElement.onclick = function () {
                    //删除按钮所在的tr对象
                    var i = this.parentNode.parentNode.rowIndex;
                    document.getElementById('proSon').deleteRow(i-1);
                    del(this.parentNode.parentNode.childNodes.valueOf()[0].innerText);
                };
                td7Element.appendChild(delElement);
                //将td元素添加到tr元素中
                trElemnet.appendChild(td0Element);
                trElemnet.appendChild(td1Element);
                trElemnet.appendChild(td2Element);
                trElemnet.appendChild(td3Element);
                trElemnet.appendChild(td4Element);
                trElemnet.appendChild(td5Element);
                trElemnet.appendChild(td6Element);
                trElemnet.appendChild(td7Element);
                //将tr元素添加到tbody元素中
                // let products = document.getElementById("products");
                // document.getElementById("mytable").insertBefore(trElemnet,products);
                document.getElementById("proSon").appendChild(trElemnet);
            }
        }
    });
//完全可以使用一条js来操作,下次改
    $("#upDev").show();
    $("#addDev").hide();
    //点击提交编辑按钮
    var add2 = [];
    $("#upDev").click(function () {
        $("#proSon input:text,input[type=number],input[type=date]").each(
            function () {
                var val = $(this).val();
                add2.push(val);
            }
        );
        // console.info(add2);
        var addpush2 = [];
        if (add2.length != 0) {
            var countInLine = 5;//一行几个数
            for (var i = 0; i < add2.length; i++) {
                if (i % countInLine == 0) {
                    var obj = new Object();
                    obj.content = add2[i];
                    obj.amount = add2[i + 1];
                    obj.schedule = add2[i + 2];
                    obj.createDate = add2[i + 3];
                    obj.remarks = add2[i + 4];
                    addpush2.push(obj);
                }
            }
            // console.info(addpush2);
        }
        $.ajax({
            type: "POST",
            url: path + "/site/updateFinPro",
            data: $('#myform').serialize()+ "&add=" + JSON.stringify(addpush2),
            dataType: "text",
            success: function (data) {
                if (data == "success") {
                    alertShow("修改成功", path + "/site/findFinPro");
                } else if (data == "err") {
                    alertShow("修改失败");
                }
            }
        });
    });
//回显表单数据
    $.ajax({
        type: "POST",
        url: path + "/site/findFinProUpdate",
        data: {"id": id},
        dataType: "json",
        success: function (data) {
            for (var i = 0; i < data.length; i++) {
                $("#devNum").val(data[i].devNum);
                $("#personCharge").val(data[i].personCharge);
                $("#createDate").val(data[i].createDate);
                $("#chargCurrent").val(data[i].chargCurrent);
                $("#personCharge").val(data[i].personCharge);
                $("#remarks").val(data[i].remarks);
                $("#devType option ").each(function () {
                    if($(this).val()== data[i].devType ){
                        $(this).attr("selected","selected");
                    }
                });
                $("#customerUnitId option ").each(function () {
                    if($(this).val()== data[i].customerUnitId ){
                        $(this).attr("selected","selected");
                    }
                });
            }
        }
    })
}

表现层和增加是一样的,只不过,传入主表id,不需要新建的时候映射会来而已。略过,不懂详看增加的表现层

@RequestMapping(value = "/updateFinPro")
@ResponseBody
public String updateFinPro(finPro fin, String add) {
    try {
        int i = IndexService.updateFinPro(fin);
        if (i > 0) {
            Map<String, Object> proSonMap = new HashMap<>();
            Map<String, Object> map = new HashMap<>();
            proSonMap.put("finisproId",fin.getId());
            JSONArray json=  JSONArray.fromObject(add);
            for (int j = 0; j < json.size()-2; j++) {
                net.sf.json.JSONObject js=  json.getJSONObject(j);
                proSonMap.put("ordinal",j+1);
                proSonMap.put("content",js.get("content"));
                proSonMap.put("amount",js.get("amount"));
                proSonMap.put("schedule",js.get("schedule"));
                proSonMap.put("remarks",js.get("remarks"));
                proSonMap.put("createDate",js.get("createDate"));
                Integer k = IndexService.insertProSon(proSonMap);
            }
            return "success";
        } else {
            return "err";
        }
    } catch (Exception e) {
        logger.info(e.getMessage(), e);

    }
    return null;
}

说明:表现层json.size()-2主要是因为,多携带了不必要数据

基本功能实现了,最佳实践还在摸索,若有同学已经完事,敬请骚扰。

人生如山,为梦而攀。