博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS组件系列——Bootstrap Table 表格行拖拽
阅读量:6233 次
发布时间:2019-06-22

本文共 17462 字,大约阅读时间需要 58 分钟。

原文:

前言:之前一直在研究DDD相关知识,好久没更新JS系列文章了。这两天做了一个简单的业务需求,觉得效果还可以,今天在这里分享给大家,欢迎拍砖~~

一、业务需求及实现效果

项目涉及到订单模块,那天突然接到一个需求,说是两种不同状态的订单之间要实现插单的效果,页面上呈现方式是:左右两个Table,左边Table里面是状态为1的订单,右边Table里面是状态为2订单,左边Table里面的行数据拖动到右边Table里面指定行的位置,拖动完成后,左边表格减少一行,右边表格增加一行。除此之外,还需要撤销操作(相当于Ctrl + Z操作),能够返回到上一步的状态。可能描述会让大家模拟两可,反正已经实现了,先来看看效果图吧。

1、先看看拖动之前的效果

2、这是拖动左边表格行数据的效果

3、拖动一行完成之后表格数据的效果

4、第二次、第三次拖动完成后效果

5、右边表格上面撤销操作点击效果

6、多次点击撤销,表格回到初始状态

二、代码示例

初初接到需求,博主的第一感觉是应该上Bootstrap table api里面找一下,毕竟开源的力量是强大的,或许有相关的示例呢。经过一番查找,很可惜,Bootstrap Table没有这种两张表格之间的操作。想想其实也可以理解,Bootstrap Table是针对某个动态表格数据绑定的,它的侧重点是表格内部的功能,比如表格内部行的拖拽排序(Reorder Rows)有很好的解决方案,对于像博主这样的特殊需求,似乎也应该自己去实现。

1、需求分析

既然决定自己去写,博主开始分析需求,似乎这个操作里面比较困难的是拖拽效果,说到拖拽效果,原来使用JsPlumb的时候那使用太多了,于是就想到了我们神奇的JQuery UI里面的draggable.js 和droppable.js。拖拽的问题解决了,那么还有一个难点,就是撤销操作怎么办?我们知道Ctrl+z的意思是还原,什么叫还原?就是返回到上一步的操作,那么前提是要能够保存上一步的状态,说到保存某一步的状态,博主就知道怎么做了,需要一个全局变量Json,里面要有三个键值对,分别是当前步骤的索引、左边表格的数据、右边表格的数据。似乎也不太难嘛,博主就此着手,开干。

2、代码示例

 2.1 cshtml页面代码

    
@ViewBag.Title @Styles.Render("~/Content/css") @Styles.Render("~/Content/table-css") @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/knockout") @Scripts.Render("~/bundles/bootstrap") @Scripts.Render("~/bundles/bootstrap-table") @RenderSection("Scripts", false) @RenderBody()
母版_layout.cshtml
@{    ViewBag.Title = "订单插单";    Layout = "~/Views/Shared/_Layout.cshtml";}@Scripts.Render("~/bundles/Order/InsertOrder")@Styles.Render("~/bundles/Order/css")@Scripts.Render("~/Content/bootstrap/datepicker/js")@Styles.Render("~/Content/bootstrap/datepicker/css")
查询条件
展开
@*
*@
订单插单页面.cshtml

 2.2 js代码

var i_statuindex = 0;//此数组用于保存撤销操作每一步的数据var arrdata = [];var m_oTable = null;$(function () {    //1.初始化表格    m_oTable = new TableInit();    m_oTable.Init();    //2.初始化按钮事件    var oButtonInit = new ButtonInit();    oButtonInit.Init();    //3.日期控件的初始化    $(".datetimepicker").datetimepicker({        format: 'yyyy-mm-dd hh:ii',        autoclose: true,        todayBtn: true,    });});//表格相关事件和方法var TableInit = function () {    var oTableInit = new Object();    oTableInit.Init = function () {     //初始化左边表格        $('#tb_order_left').bootstrapTable({            url: '/api/OrderApi/get',            method: 'get',            striped: true,            cache: false,            striped: true,            pagination: true,            height: 600,            uniqueId:"TO_ORDER_ID",            queryParams: oTableInit.queryParams,            queryParamsType: "limit",            sidePagination: "server",            pageSize: 10,            pageList: [10, 25, 50, 100],            search: true,            strictSearch: true,            showColumns: true,            showRefresh: true,            minimumCountColumns: 2,            clickToSelect: true,            columns: [{                checkbox: true            },            {                field: 'ORDER_NO',                title: '订单号'            },            {                field: 'BODY_NO',                title: '车身号'            }, {                field: 'VIN',                title: 'VIN码'            }, {                field: 'TM_MODEL_MATERIAL_ID',                title: '整车编码'            },            {                field: 'ORDER_TYPE',                title: '订单类型'            },            {                field: 'ORDER_STATUS',                title: '订单状态'            },            {                field: 'CREATE_DATE',                title: '订单导入时间'            },            {                field: 'PLAN_DATE',                title: '订单计划上线日期'            },            {                field: 'VMS_NO',                title: 'VMS号'            },            {                field: 'ENGIN_CODE',                title: '发动机号'            },            {                field: 'TRANS_CODE',                title: '变速箱号'            },            {                field: 'OFFLINE_DATE_ACT',                title: '实际下线日期'            },            {                field: 'HOLD_RES',                title: 'hold理由'            },            {                field: 'SPC_FLAG',                title: '特殊标记'            },            ],            onLoadSuccess: function (data) {                 //表格加载完成之后初始化拖拽          oTableInit.InitDrag();            }        });     //初始化右边表格        $('#tb_order_right').bootstrapTable({            url: '/api/OrderApi/get',            method: 'get',            toolbar: '#toolbar_right',            striped: true,            cache: false,            striped: true,            pagination: true,            height: 600,            queryParams: oTableInit.queryParamsRight,            queryParamsType: "limit",            //ajaxOptions: { departmentname: "", statu: "" },            sidePagination: "server",            pageSize: 10,            pageList: [10, 25, 50, 100],            search: true,            strictSearch: true,            showRefresh: true,            minimumCountColumns: 2,            columns: [            {                field: 'ORDER_NO',                title: '订单号'            },            {                field: 'BODY_NO',                title: '车身号'            }, {                field: 'VIN',                title: 'VIN码'            }, {                field: 'TM_MODEL_MATERIAL_ID',                title: '整车编码'            },            {                field: 'ORDER_TYPE',                title: '订单类型'            },            {                field: 'ORDER_STATUS',                title: '订单状态'            },            {                field: 'CREATE_DATE',                title: '订单导入时间'            },            {                field: 'PLAN_DATE',                title: '订单计划上线日期'            },            {                field: 'VMS_NO',                title: 'VMS号'            },            {                field: 'ENGIN_CODE',                title: '发动机号'            },            {                field: 'TRANS_CODE',                title: '变速箱号'            },            {                field: 'OFFLINE_DATE_ACT',                title: '实际下线日期'            },            {                field: 'HOLD_RES',                title: 'hold理由'            },            {                field: 'SPC_FLAG',                title: '特殊标记'            },            ],            onLoadSuccess: function (data) {                oTableInit.InitDrop();            }        });    };    //注册表格行的draggable事件    oTableInit.InitDrag = function () {        $('#tb_order_left tr').draggable({            helper: "clone",            start: function (event, ui) {                var old_left_data = JSON.stringify($('#tb_order_left').bootstrapTable("getData"));                var old_right_data = JSON.stringify($('#tb_order_right').bootstrapTable("getData"));                var odata = { index: ++i_statuindex, left_data: old_left_data, right_data: old_right_data };                arrdata.push(odata);            },            stop: function (event, ui) {                            }        });    };    //注册右边表格的droppable事件    oTableInit.InitDrop = function () {        $("#tb_order_right").droppable({            drop: function (event, ui) {                var arrtd = $(ui.helper[0]).find("td");                var rowdata = {                    ORDER_NO: $(arrtd[1]).text(),                    BODY_NO: $(arrtd[2]).text(),                    VIN: $(arrtd[3]).text(),                    TM_MODEL_MATERIAL_ID: $(arrtd[4]).text(),                    ORDER_TYPE: $(arrtd[5]).text(),                    ORDER_STATUS: $(arrtd[6]).text(),                    CREATE_DATE: $(arrtd[7]).text() == "-" ? null : $(arrtd[7]).text(),                    PLAN_DATE: $(arrtd[8]).text() == "-" ? null : $(arrtd[8]).text(),                    VMS_NO: $(arrtd[9]).text(),                    ENGIN_CODE: $(arrtd[10]).text(),                    TRANS_CODE: $(arrtd[11]).text(),                    OFFLINE_DATE_ACT: $(arrtd[12]).text() == "-" ? null : $(arrtd[12]).text(),                    HOLD_RES: $(arrtd[13]).text(),                    SPC_FLAG: $(arrtd[14]).text(),                    TO_ORDER_ID: $(ui.helper[0]).attr("data-uniqueid")                };                var oTop = ui.helper[0].offsetTop;                var iRowHeadHeight = 40;                var iRowHeight = 37;                var rowIndex = 0;                if (oTop <= iRowHeadHeight + iRowHeight / 2) {                    rowIndex = 0;                }                else {                    rowIndex = Math.ceil((oTop - iRowHeadHeight) / iRowHeight);                }          //插入右边表格指定位置行数据                $("#tb_order_right").bootstrapTable("insertRow", { index: rowIndex, row: rowdata });                $('#tb_order_left').bootstrapTable("removeByUniqueId", $(ui.helper[0]).attr("data-uniqueid"));                oTableInit.InitDrag();            }        });    };    oTableInit.queryParams = function (params) {  //配置参数        var temp = {   //这里的键的名字和控制器的变量名必须一直,这边改动,控制器也需要改成一样的            limit: params.limit,   //页面大小            offset: params.offset,  //页码            strBodyno: $("#txt_search_bodynumber").val(),            strVin: $("#txt_search_vinnumber").val(),            strOrderno: $("#txt_search_ordernumber").val(),            strEngincode: $("#txt_search_engin_code").val(),            strOrderstatus: 0,            strTranscode: $("#txt_search_trans_code").val(),            strVms: $("#txt_search_vms").val(),            strCarcode: $("#txt_search_carcode").val(),            strImportStartdate: $("#txt_search_import_startdate").val(),            strImportEnddate: $("#txt_search_import_enddate").val(),            strSendStartdate: $("#txt_search_send_startdate").val(),            strSendEnddate: $("#txt_search_send_enddate").val(),        };        return temp;    };    oTableInit.queryParamsRight = function (params) {  //配置参数        var temp = {   //这里的键的名字和控制器的变量名必须一直,这边改动,控制器也需要改成一样的            limit: params.limit,   //页面大小            offset: params.offset,  //页码            strBodyno: "",            strVin: "",            strOrderno: "",            strEngincode: "",            strOrderstatus: 5,            strTranscode: "",            strVms: "",            strCarcode: "",            strImportStartdate: "",            strImportEnddate: "",            strSendStartdate: "",            strSendEnddate: "",        };        return temp;    };    return oTableInit;};//页面按钮初始化事件var ButtonInit = function () {    var oInit = new Object();    var postdata = {};    oInit.Init = function () {        //查询点击事件        $("#btn_query").click(function () {            $("#tb_order_left").bootstrapTable('refresh');        });        //重置点击事件        $("#btn_reset").click(function () {            $(".container-fluid").find(".form-control").val("");            $("#tb_order_left").bootstrapTable('refresh');        });        //撤销操作点击事件        $("#btn_cancel").click(function () {            if (i_statuindex <= 0) {                return;            }            for (var i = 0; i < arrdata.length; i++) {                if (arrdata[i].index != i_statuindex) {                    continue;                }                var arr_left_data = eval(arrdata[i].left_data);                var arr_right_data = eval(arrdata[i].right_data);                $('#tb_order_left').bootstrapTable('removeAll');                $('#tb_order_right').bootstrapTable('removeAll');                $('#tb_order_left').bootstrapTable('append', arr_left_data);                for (var x = 0; x < arr_right_data.length; x++) {                    $("#tb_order_right").bootstrapTable("insertRow", { index: x, row: arr_right_data[x] });                }                                //$('#tb_order_right').bootstrapTable('append', arr_right_data);//append之后不能drop                break;            }            i_statuindex--;            //重新注册可拖拽            m_oTable.InitDrag();            //m_oTable.InitDrop();        });        //搜索栏展开收起点击事件        $("#span_collapse").click(function () {            if ($(this).text() == "收起") {                $(this).html('展开');                $("#div_more_search").collapse('hide');            }            else {                $(this).html('收起');                $("#div_more_search").collapse('show')            }        });    };    return oInit;};
全部JS代码

 我们重点来看几个地方的代码:

2.2.1  左边表格加载成功之后执行表格行的可拖拽。

$('#tb_order_left tr').draggable({            helper: "clone",            start: function (event, ui) {                var old_left_data = JSON.stringify($('#tb_order_left').bootstrapTable("getData"));                var old_right_data = JSON.stringify($('#tb_order_right').bootstrapTable("getData"));                var odata = { index: ++i_statuindex, left_data: old_left_data, right_data: old_right_data };                arrdata.push(odata);            },            stop: function (event, ui) {
} });

在draggable的start事件中,我们将拖拽之前的左右表格中的数据全部保存到arrdata变量中,i_statuindex这个全局变量用于记录当前这一步的索引,用于撤销操作。

 

2.2.2 右边表格在加载成功之后注册表格的droppable事件

    $("#tb_order_right").droppable({            drop: function (event, ui) {                var arrtd = $(ui.helper[0]).find("td");                var rowdata = {                    ORDER_NO: $(arrtd[1]).text(),                    BODY_NO: $(arrtd[2]).text(),                    VIN: $(arrtd[3]).text(),                    TM_MODEL_MATERIAL_ID: $(arrtd[4]).text(),                    ORDER_TYPE: $(arrtd[5]).text(),                    ORDER_STATUS: $(arrtd[6]).text(),                    CREATE_DATE: $(arrtd[7]).text() == "-" ? null : $(arrtd[7]).text(),                    PLAN_DATE: $(arrtd[8]).text() == "-" ? null : $(arrtd[8]).text(),                    VMS_NO: $(arrtd[9]).text(),                    ENGIN_CODE: $(arrtd[10]).text(),                    TRANS_CODE: $(arrtd[11]).text(),                    OFFLINE_DATE_ACT: $(arrtd[12]).text() == "-" ? null : $(arrtd[12]).text(),                    HOLD_RES: $(arrtd[13]).text(),                    SPC_FLAG: $(arrtd[14]).text(),                    TO_ORDER_ID: $(ui.helper[0]).attr("data-uniqueid")                };                var oTop = ui.helper[0].offsetTop;                var iRowHeadHeight = 40;                var iRowHeight = 37;                var rowIndex = 0;                if (oTop <= iRowHeadHeight + iRowHeight / 2) {                    rowIndex = 0;                }                else {                    rowIndex = Math.ceil((oTop - iRowHeadHeight) / iRowHeight);                }                $("#tb_order_right").bootstrapTable("insertRow", { index: rowIndex, row: rowdata });                $('#tb_order_left').bootstrapTable("removeByUniqueId", $(ui.helper[0]).attr("data-uniqueid"));                oTableInit.InitDrag();            }        });

在drop事件时,取到当前拖过来的行数据,计算当前鼠标所在的位置,在右边表格指定位置插入拖过来的行数据。然后删除左边表格拖过来的行数据。

 

2.2.3 撤销操作代码

     //撤销操作点击事件        $("#btn_cancel").click(function () {            if (i_statuindex <= 0) {                return;            }            for (var i = 0; i < arrdata.length; i++) {                if (arrdata[i].index != i_statuindex) {                    continue;                }                var arr_left_data = eval(arrdata[i].left_data);                var arr_right_data = eval(arrdata[i].right_data);                $('#tb_order_left').bootstrapTable('removeAll');                $('#tb_order_right').bootstrapTable('removeAll');                $('#tb_order_left').bootstrapTable('append', arr_left_data);                for (var x = 0; x < arr_right_data.length; x++) {                    $("#tb_order_right").bootstrapTable("insertRow", { index: x, row: arr_right_data[x] });                }                //$('#tb_order_right').bootstrapTable('append', arr_right_data);//append之后不能drop                break;            }            i_statuindex--;            //重写注册可拖拽            m_oTable.InitDrag();        });

撤销操作主要是通过全局变量arrdata里面的索引判断撤销到哪一步,然后根据索引取出当前步骤的左右表格数据,依次向两表格插入数据,然后i_statuindex依次递减,直至等于零,由于左边表格行数据全部重写加载过,所以需要重新注册可拖拽事件。就是这么简单的三步就能实现想要的效果,是不是很简单~~

 

转载地址:http://rdqna.baihongyu.com/

你可能感兴趣的文章
Secret Code
查看>>
Vue动态组件
查看>>
ES2017异步函数现已正式可用
查看>>
DBA-io
查看>>
【转】批处理常用符号详解
查看>>
Uncaught TypeError: jQuery.i18n.browserLang is not a function
查看>>
JavaScript中的闭包详解
查看>>
【JSP】JSP Action动作标签
查看>>
iOS:CoreText的常用语法
查看>>
dropify,不错的图片上传预览插件
查看>>
为什么都不写博
查看>>
希腊字母表
查看>>
httpd配置文件httpd.conf规则说明和一些基本指令
查看>>
python中self cls init的理解
查看>>
java:类集操作总结
查看>>
Flake8学习
查看>>
SpringBoot项目eclipse运行正常maven install打包启动后报错ClassNotFoundException
查看>>
ASP.NET Core的身份认证框架IdentityServer4(9)-使用OpenID Connect添加用户认证
查看>>
[Python] String Formatting
查看>>
lapis 处理接收到的json 数据
查看>>