来访人员登记系统(十二)动态增减html页面表格表单并获取表单值传递给C#后台

前置模块

来访人员登记系统(十)网页端使用websocket向C#服务端传送图片和文字

本文在上文的基础上增加了动态增减表格表单的功能,实现通过单击按钮增加或删除一列表格和其中的表单,用递增的id区分开每一个表单项,并获取其中的提交值传递给后台进行文字和图片处理。


HTML

HTML中增加了两个按钮,用于控制表格的增减,另外还增加了对每个需要提交的表单项的编号,方便后台进行处理。

<!DOCTYPE html>
<html lang="zh-cn" xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta http-equiv="content-type" content="text/html" charset="utf-8" />
    <title>XXXX股份有限公司主机房人员出入申请单</title>
    <link rel="stylesheet" href="style.css" />
    <script type="text/javascript" src="script.js" charset="utf-8"></script>
</head>

<body>
    <div id="caption">
        <h1>XXXX股份有限公司</h1>
        <h1>主机房人员出入申请单</h1>
    </div>

    <div>
        <input id="delcol" class="button leftbutton" type="button" value="减少列" />
        <input id="addcol" class="button rightbutton" type="button" value="增加列" />
    </div>

    <div id="maincontent">
        <form id="sendForm">
            <table id="formtable">
                <tr>
                    <td><input id="staff1" class="text" type="text" placeholder="弘业对接人员" required /></td>
                </tr>
                <tr>
                    <td><input id="name1" class="text" type="text" placeholder="外单位人员" required /></td>
                </tr>
                <tr>
                    <td><input id="company1" class="text" type="text" placeholder="单位名称" required /></td>
                </tr>
                <tr>
                    <td><input id="idcard1" class="text" type="text" placeholder="身份证号" required pattern="/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/" /></td>
                </tr>
                <tr>
                    <td><span class="imgtext">身份证国徽面照片:</span></td>
                </tr>
                <tr>
                    <td><img id="previewa_1" class="preview" /></td>
                </tr>
                <tr>
                    <td><input id="imga_1" class="file" type="file" accept="image/*" required /></td>
                </tr>
                <tr>
                    <td><span class="imgtext">身份证人像面照片:</span></td>
                </tr>
                <tr>
                    <td><img id="previewb_1" class="preview" /></td>
                </tr>
                <tr>
                    <td><input id="imgb_1" class="file" type="file" accept="image/*" required /></td>
                </tr>
                <tr>
                    <td><input id="phone1" class="text" type="text" placeholder="电话" required /></td>
                </tr>
                <tr>
                    <td><span>预约日期:</span><input id="date1" class="date" type="date" required /></td>
                </tr>
                <tr>
                    <td><input id="ETA1" class="text" type="text" placeholder="预期到达时间(hh:mm)" required pattern="^(?:(?:[0-2][0-3])|(?:[0-1][0-9])):[0-5][0-9]$" /></td>
                </tr>
                <tr>
                    <td><textarea id="intention1" placeholder="进出事由" required></textarea></td>
                </tr>
                <tr>
                    <td><textarea id="relevants1" placeholder="涉及设备/系统" required></textarea></td>
                </tr>
            </table>

            <div>
                <input class="button leftbutton" type="submit" value="提交" />
                <input class="button rightbutton" type="reset" value="重置" />
            </div>
        </form>
    </div>
</body>

</html>

CSS

css中在上文的基础上加入了一些优化,改了几个类的名字。

body {
    font-family: 'Microsoft YaHei';
    text-align: center;
}

#caption {
    margin-top: 60px;
    margin-bottom: 40px;
}

#maincontent {
    margin-bottom: 60px;
}

table {
    margin: 0 auto;
    margin-top: 5px;
    margin-bottom: 30px;
    text-align: center;
    font-size: 18px;
}

td {
    padding: 20px 20px 20px 20px;
}

input {
    font-size: 18px;
    font-family: 'Microsoft YaHei';
}

.text {
    width: 300px;
    height: 40px;
}

.imgtext {
    display: block;
    text-align: left;
}

.preview {
    width: 300px;
    height: 200px;
    overflow: hidden;
}

.file {
    font-size: 15px;
}

.date {
    width: 210px;
    height: 35px;
}

textarea {
    font-size: 18px;
    font-family: 'Microsoft YaHei';
    width: 300px;
    height: 100px;
    resize: none;
}

.button {
    width: 80px;
    height: 40px;
}

.leftbutton {
    margin-right: 30px;
}

.rightbutton {
    margin-left: 30px;
}

Javascript

js中增加了将图片预览事件的绑定封装成函数进行调用,增加了动态增减表单项的功能,每次增加时自动绑定图片的change事件。在与服务端通信时采用循环的方式,一次循环提交一组文字+图片,文字图片分离提交,图片对应的身份证号附在图片的base64码的末尾。

// javascript
var start = function () {

    // 上传并预览图片
    var previewimg = function (imga, prea, imgb, preb) {

        var fileDom1 = document.getElementById(imga);
        var previewDom1 = document.getElementById(prea);
        var fileDom2 = document.getElementById(imgb);
        var previewDom2 = document.getElementById(preb);

        fileDom1.addEventListener("change", e => {
            var file = fileDom1.files[0];
            // 检查上传的文件是否为图片格式
            if (!file || file.type.indexOf("image/") < 0) {
                fileDom1.value = "";
                previewDom1.src = "";
                return;
            }
            var fileReader = new FileReader();
            fileReader.onload = e => {
                previewDom1.src = e.target.result;
            };
            fileReader.readAsDataURL(file);
        });

        fileDom2.addEventListener("change", e => {
            var file = fileDom2.files[0];
            if (!file || file.type.indexOf("image/") < 0) {
                fileDom2.value = "";
                previewDom2.src = "";
                return;
            }
            var fileReader = new FileReader();
            fileReader.onload = e => {
                previewDom2.src = e.target.result;
            };
            fileReader.readAsDataURL(file);
        });
    };
    // 绑定初始列的图片预览事件
    previewimg("imga_1", "previewa_1", "imgb_1", "previewb_1");


    // 动态增减表格的列
    var addcolumnbtn = document.getElementById("addcol");
    var delcolumnbtn = document.getElementById("delcol");
    var column_num = 1;  // 记录当前列的个数,提交时需要用此参数遍历

    addcolumnbtn.addEventListener('click', function (e) {
        var table = document.getElementById('formtable');
        var length_row = table.rows.length;
        var row0 = table.rows[0].cells;
        var length_col = row0.length;
        column_num += 1;

        // 填充表格内容并修改input的id
        for (var i = 0; i < length_row; i++) {
            var x = table.rows[i].insertCell(length_col);
            x.innerHTML = table.rows[i].cells[length_col - 1].innerHTML.replace(column_num - 1, column_num);
        }

        // 清空图片上传和图片预览绑定的资源
        document.getElementById("imga_" + column_num).value = "";
        document.getElementById("previewa_" + column_num).src = "";
        document.getElementById("imgb_" + column_num).value = "";
        document.getElementById("previewb_" + column_num).src = "";

        // 绑定图片上传事件
        previewimg("imga_" + column_num, "previewa_" + column_num, "imgb_" + column_num, "previewb_" + column_num);
    });

    delcolumnbtn.addEventListener('click', function (e) {
        var table = document.getElementById('formtable');
        var length_row = table.rows.length;
        var row0 = table.rows[0].cells;
        var length_col = row0.length - 1;

        if (length_col) {
            column_num -= 1;
            for (var i = 0; i < length_row; i++) {
                table.rows[i].deleteCell(length_col);
            }
        }
        else {
            alert("至少需要一个预约人,无法减少。");
        }
    });

    
    // 建立websocket通信
    var wsImpl = window.WebSocket || window.MozWebSocket;
    window.ws = new wsImpl('ws://192.168.204.43:7181/');

    var form = document.getElementById('sendForm');


    // 以base64格式发送图片文件,并把身份证号附在最后
    function sendFile(fileDom, idcard) {
        var file = fileDom.files[0];
        var reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function (e) {
            var base64Code = reader.result;
            ws.send(base64Code + "," + idcard);
        };
    }

    // 覆写提交事件
    form.addEventListener('submit', function (e) {
        e.preventDefault();

        for (var i = 1; i <= column_num; i++) {
            var staff = document.getElementById('staff' + i);
            var name = document.getElementById('name' + i);
            var company = document.getElementById('company' + i);
            var idcard = document.getElementById('idcard' + i);
            var phone = document.getElementById('phone' + i);
            var date = document.getElementById('date' + i);
            var ETA = document.getElementById('ETA' + i);
            var intention = document.getElementById('intention' + i);
            var relevants = document.getElementById('relevants' + i);
            var fileDom1 = document.getElementById('imga_' + i);
            var fileDom2 = document.getElementById('imgb_' + i);

            var msg = staff.value + ',' + name.value + ',' + company.value + ',' + idcard.value + ',' + phone.value + ',' + date.value + ',' +
                      ETA.value + ',' + intention.value + ',' + relevants.value;
            ws.send(msg);
            sendFile(fileDom1, idcard.value);
            sendFile(fileDom2, idcard.value);
        }

        alert("您的申请已提交。");
        form.reset();

        for (var i = 1; i <= column_num; i++) {
            document.getElementById('previewa_' + i).src = "";
            document.getElementById('previewb_' + i).src = "";
        }
    });
};

window.onload = start;

C#服务端

C#中取消了采用static变量current_idcard确定图片对应身份证号信息的方式,换用为将身份证号信息写入图片末尾的方式,用逗号分隔。

        // 将客户端发来的身份证照片的base64码复原成图片,并存储到本地文件夹
        private void saveidcardImage(string msg)
        {
            // base64码预处理
            string hz = msg.Split(',')[0].Split(';')[0].Split('/')[1];
            string[] str = msg.Split(',');
            byte[] imageBytes = Convert.FromBase64String(str[1]);
            string idcard = str[2];

            //读入MemoryStream对象
            MemoryStream memoryStream = new MemoryStream(imageBytes, 0, imageBytes.Length);
            memoryStream.Write(imageBytes, 0, imageBytes.Length);
            
            //  保存图片
            Image image = Image.FromStream(memoryStream);
            string filename = image_directory + idcard + "_a." + hz;

            if (!File.Exists(filename))
            {
                image.Save(filename);
            }
            else
            {
                filename = image_directory + idcard + "_b." + hz;
                image.Save(filename);
            }
        }

总结

将事件的操作封装为函数以方便调用,比直接写事件逻辑性更好;
对id进行编号后,用循环可以很方便地控制多组数据的分别发送。

posted @ 2020-09-29 15:55  老鼠司令  阅读(581)  评论(0编辑  收藏  举报