BootstrapTable表格数据左右移动功能遇到的问题(数据左右移动,列表拖拽排序,模糊查询列表数据定位)

  使用bootstrapTable实现数据左右移动的功能其实做过很多了,但原来实现的功能都是比较单一,都是选中单条数据进行移动。这次需要实现的功能比较全面,中间遇到不少的坑,此次正好在这里将所有的功能代码梳理一下。

实现以下功能:

1.选中单条数据进行左右移动

2.将列表中所有数据全部进行左右移动

3.左边的数据移动到右边后,为其增加一个序号列,并根据右侧列表的数据自动递增序号

4.右侧列表中的数据可以随意拖动排序,序号自动变更

5.在列表上的搜索框输入关键字,定位到列表中对应的数据并选中

html代码:

 1                 <div class="movebox clearfix box-padding10">
 2                     <div class="movebox-left fl">
 3                         <p>可选考核项目</p>
 4                         <div class="form-inline form-inline-auto" style="padding-right: 0;">
 5                             <div class="form-group t-right10">
 6                                 <select class="form-control" style="min- 110px" id="kaoheFW" name="kaoheFW">
 7                                     <option value="2">专科</option>
 8                                     <option value="1">公共</option>
 9                                 </select>
10                             </div>
11                             <div class="form-control-radio" style=" auto; min- 0;">
12                                 <input type="radio" class="radio" name="leixing" value="" checked>
13                                 <label class="f-left t-right10 t-lineheight28">全部</label>
14                                 <input type="radio" class="radio" name="leixing" value="2">
15                                 <label class="f-left t-right10 t-lineheight28">操作</label>
16                                 <input type="radio" class="radio" name="leixing" value="1">
17                                 <label class="f-left t-right10 t-lineheight28">理论</label>
18                             </div>
19                             <div class="form-group">
20                                 <input class="form-control" placeholder="请输入考核项目" type="text" value="" id="kaoheXM">
21                             </div>
22                         </div>
23                         <div class="clear"></div>
24                         <div class="form-table-height main-y-scroll" id="kaoheXMList">
25                             <table class="table table-striped table-bordered table-hover text-center" id="tableleft">
26                                 <thead>
27 
28                                 </thead>
29                                 <tbody></tbody>
30                             </table>
31                         </div>
32                         <div class="space"></div>
33                     </div>
34                     <div class="movebox-btn fl">
35                         <span id="add_all" class="icon iconfont icon-youshuangjiantou"></span>
36                         <span id="add" class="icon iconfont icon-jiantou-you" onclick="add_keShiKHXM()"></span>
37                         <span id="remove" class="icon iconfont icon-jiantou-zuo" onclick="remove_keShiKHXM()"></span>
38                         <span id="remove_all" class="icon iconfont icon-zuoshuangjiantou"></span>
39                     </div>
40                     <div class="movebox-right fl">
41                         <p>已选择考核项目</p>
42                         <div class="form-inline form-inline-auto" style="padding-right: 0;">
43                             <div class="form-group t-right10">
44                                 <select class="form-control" style="min- 110px" id="keshiKHFW" name="keshiKHFW">
45                                     <option value="2">专科</option>
46                                     <option value="1">公共</option>
47                                 </select>
48                             </div>
49                             <div class="form-control-radio" style=" auto; min- 0;">
50                                 <input type="radio" class="radio" name="keshiLX" value="" checked>
51                                 <label class="f-left t-right10 t-lineheight28">全部</label>
52                                 <input type="radio" class="radio" name="keshiLX" value="2">
53                                 <label class="f-left t-right10 t-lineheight28">操作</label>
54                                 <input type="radio" class="radio" name="keshiLX" value="1">
55                                 <label class="f-left t-right10 t-lineheight28">理论</label>
56                             </div>
57                             <div class="form-group" >
58                                 <input class="form-control" placeholder="请输入考核项目" type="text" value="" id="keshiKHXM" >
59                             </div>
60                         </div>
61                         <div class="clear"></div>
62                         <div class="form-table-height main-y-scroll" id="keshiKHXMList">
63                             <table class="table table-striped table-bordered table-hover text-center" id="tableright">
64                                 <thead>
65 
66                                 </thead>
67                                 <tbody>
68                                 </tbody>
69                             </table>
70                         </div>
71                         <p class="t-gray">说明:拖拽行进行排序</p>
72                     </div>
73                 </div>
View Code

初始化bootstraptable:

 1         function Init_kaoHeXM() {
 2 
 3             //获取关键字
 4             var kaoHeFW = $('#kaoheFW option:selected').val();;
 5             var kaoHeLX = $('input[name="leixing"]:checked').val();
 6 
 7             $('#tableleft').bootstrapTable("destroy");
 8             //初始化table
 9             $('#tableleft').bootstrapTable({
10                 url: "/HLGL/ChengJiGL/GetkaoheXMList",
11                 postData: function () {
12                     return { "keShiID": keShiID, "kaoHeFW": kaoHeFW, "kaoHeLX": kaoHeLX }
13                 },
14                 columns: [
15                     { field: 'KAOHEXMID', title: "考核项目ID", visible: true },
16                     { field: 'XIANGMUMC', title: "项目名称", visible: true },
17                     { field: 'KAOHELX', title: "考核类型", visible: true, formatterType: 'JSON', formatter: { '1': '理论', '2': '操作' } }
18 
19                 ],
20                 pagination: false,
21                 autoSelectFirstRow: false,
22                 //height: $(window).height() - 117
23             });
24         }
25         function Init_keShiKHXM() {
26             //获取关键字
27             var kaoHeFW = $('#keshiKHFW option:selected').val();;
28             var kaoHeLX = $('input[name="keshiLX"]:checked').val();
29            
30             $('#tableright').bootstrapTable("destroy");
31             $('#tableright').bootstrapTable({
32                 url: "/HLGL/ChengJiGL/GetkeshiKHXMList",
33                 postData: function () {
34                     return { "keShiID": keShiID, "kaoHeFW": kaoHeFW, "kaoHeLX": kaoHeLX }
35                 },
36                 columns: [
37                     { field: 'PAIXUXH', title: "排序序号",  "5%", visible: true, class: "index", },
38                     { field: 'KESHIKHXMID', title: "科室考核项目ID", visible: false },
39                     { field: 'KAOHEXMID', title: "考核项目ID", visible: true },
40                     { field: 'XIANGMUMC', title: "项目名称", visible: true },
41                     { field: 'KAOHELX', title: "考核类型", visible: true, formatterType: 'JSON', formatter: { '1': '理论', '2': '操作' } }
42 
43                 ],
44                 pagination: false,//不分页
45                 autoSelectFirstRow: false//默认不选中第一行
46                 //height: $(window).height() - 117
47             })
48         }
View Code

初始化后定义了两个变量存放bootstrapTable:

$tableLeft = $('#tableleft').bootstrapTable();
$tableRight = $('#tableright').bootstrapTable();

下面就开始实现第一个功能:选中单条数据进行左右移动 ,右移时增加序号列并在原有基础上递增

这个功能比较简单,没有什么需要注意的地方

 1         //添加科室考核项目
 2         function add_keShiKHXM() {
 3 //注意getSelectedRow这个是内部重新封装的方法,原生获取选中行应该是$("#tableleft").bootstrapTable('getSelections');
 4             var selectContent = $tableLeft.bootstrapTable('getSelectedRow');
 5             if (selectContent == "" || selectContent==null || selectContent == undefined) {
 6                 HRP.AlertError("请先选择需要操作的数据!");
 7                 return false;
 8             }
 9             selectContent.KESHIID = keShiID;
10 
11             //获取到右侧列表的排序序号,给左侧选中行进行设置
12             var len = $('#tableright tr .index').length;
13             if (len == 1)
14             { selectContent.PAIXUXH = 1; }
15             else {
16                 selectContent.PAIXUXH = parseInt($('#tableright tr').eq(len - 1).children(0).eq(0)[0].innerText) + 1;//len-1 是因为有标题列
17             }
18             
19 
20             $tableRight.bootstrapTable("append", selectContent);
21             var selects = $tableLeft.bootstrapTable('getSelectedRow');
22 
23             var KAOHEXMID = selects.KAOHEXMID;
24 
25             $tableLeft.bootstrapTable('remove', {
26                 field: 'KAOHEXMID',
27                 values: [String(KAOHEXMID)]
28             });
29 
30         }
31 
32         //移除科室考核项目
33         function remove_keShiKHXM() {
34 //注意getSelectedRow这个是内部重新封装的方法,原生获取选中行应该是$("#tableright").bootstrapTable('getSelections');
35             var selectContent = $tableRight.bootstrapTable('getSelectedRow');
36             if (selectContent == "" || selectContent==null || selectContent == undefined) {
37                 HRP.AlertError("请先选择需要操作的数据!");
38                 return false;
39             }
40 
41 
42             $tableLeft.bootstrapTable("append", selectContent);
43             var selects = $tableRight.bootstrapTable('getSelectedRow');
44 
45             var daima = selects.KAOHEXMID;
46             $tableRight.bootstrapTable('remove', {
47                 field: 'KAOHEXMID',
48                 values: [String(daima)]
49             });
50         };

第二个功能:将列表所有数据进行左右移动

 1             $("#add_all").click(function () {
 2 
 3                 if ($("#tableleft tbody tr.no-records-found").length > 0) {
 4                     HRP.AlertError("当前没有可以操作的数据!");
 5                     return false;
 6                 }
 7                 $("#tableright tbody tr.no-records-found").remove();//这一句是删除掉表格中没有数据时的提示行
 8                 // $("#tableright").find(".no-records-found").remove();·
 9                 var len = 0;
10                 if ($("#tableright tbody tr").length == 0) {
11                     len = 1;
12                 }
13                 else {
14                     len = parseInt($("#tableright tbody tr:last-child .index").html()) + 1;
15                 }
16 
17                 //下面两个for循环不能合在一起,因为delete以后eq(i)获取的数据会随着改变,不是原来索引的数据
18                 for (var i = 0; i < $("#tableleft tbody tr").length; i++) {
19                     var content = {"PAIXUXH":len,"KAOHEXMID":$("#tableleft tbody tr").eq(i).find("td")[0].innerText,"XIANGMUMC":$("#tableleft tbody tr").eq(i).find("td")[1].innerText,"KAOHELX":$("#tableleft tbody tr").eq(i).find("td")[2].innerText}
20                     $tableRight.bootstrapTable("append", content);
21                     len++;
22                 }
23 
24                 //$("#tableleft tbody tr").remove(); 
25            //这里不能用remove,此时需要用bootstrapTable自带的删除,否则下次对表进行操作时remove的数据会再次出现
26                 //
27 
28                 var xiangMuLength = $("#tableleft tbody tr").length;
29                 for (var j = 0; j < xiangMuLength; j++) {
30                     var index = $("#tableleft tbody tr").eq(0).attr("data-index");
31                     $tableLeft.bootstrapTable('deleteRow',index.toNumber());
32                 }
33             });
34 
35             $("#remove_all").click(function () {
36                 if ($("#tableright tbody tr.no-records-found").length > 0) {
37                     HRP.AlertError("当前没有可以操作的数据!");
38                     return false;
39                 }
40                 $("#tableleft tbody tr.no-records-found").remove();
41                 $("#tableright tbody td.index").remove();
42 
43 
44                 //下面两个for循环不能合在一起,因为delete以后eq(i)获取的数据会随着改变,不是原来索引的数据
45                 for (var i = 0; i < $("#tableright tbody tr").length; i++) {
46 
47                     var content = {};
48                     content = {"KAOHEXMID":$("#tableright tbody tr").eq(i).find("td")[0].innerText,"XIANGMUMC":$("#tableright tbody tr").eq(i).find("td")[1].innerText,"KAOHELX":$("#tableright tbody tr").eq(i).find("td")[2].innerText}
49                     $tableLeft.bootstrapTable("append", content);
50                 }
51 
52                 var keShiXMLength = $("#tableright tbody tr").length;
53                 for (var j = 0; j < keShiXMLength; j++) {
54 
55                     var index = $("#tableright tbody tr").eq(0).attr("data-index");
56                     $tableRight.bootstrapTable('deleteRow',index.toNumber());
57                 }
58 
59 
60             });

  这里全部数据的左右移动我用的是遍历再使用bootstrapTable的append方法来进行插入,原本我是直接使用的html的appendto方法来进行实现,结果发现存在严重的bug。

  通过这种方式虽然在表面上是实现功能了,可以将数据移过去进行保存,但是如果先点击移动全部的按钮将数据转移后,再选中一条数据进行移动,会出现原本列表中被转移的数据会再次出现。经调试发现这种方式虽然被转移了,但数据所属的列表还是原列表,但具体的原理不太清楚。所以后来我通过遍历拼接json字符串最后通过bootstrapTable的append方法进行实现。这样没有出现上面的问题。

   下面是我原来的有bug的代码,以后当做反面事例:

 $("#add_all").click(function () {

                if ($("#tableleft tbody tr.no-records-found").length > 0) {
                    HRP.AlertError("当前没有可以操作的数据!");
                    return false;
                }
                $("#tableright tbody tr.no-records-found").remove();
               // $("#tableright").find(".no-records-found").remove();
                var len = 0;
                if ($("#tableright tbody tr").length == 0) {
                    len = 1;
                }
                else {
                    len = parseInt($("#tableright tbody tr:last-child .index").html()) + 1;
                }

                for (var i = 0; i < $("#tableleft tbody tr").length; i++) {

                    var tdNo = "<td class='index'>" + len + "</td>";
                    $("#tableleft tbody tr").eq(i).prepend(tdNo);
                    len++;
                }
              
                $("#tableleft tbody tr").appendTo($("#tableright tbody")).siblings().removeClass("td-active");
            });

            $("#remove_all").click(function () {
                if ($("#tableright tbody tr.no-records-found").length > 0) {
                    HRP.AlertError("当前没有可以操作的数据!");
                    return false;
                }
                $("#tableleft tbody tr.no-records-found").remove();
                $("#tableright tbody td.index").remove();
                //$("#tableright tbody td:last-child").remove();
                $("#tableright tbody tr").appendTo($("#tableleft tbody")).siblings().removeClass("td-active");
            });

第三个功能:右侧列表实现拖拽排序

            //拖拽排序
            var fixHelperModified = function (e, tr) {
                var $originals = tr.children();
                var $helper = tr.clone();
                $helper.children().each(function (index) {
                    $(this).width($originals.eq(index).width())
                });
                return $helper;
            },
                updateIndex = function (e, ui) {
                    $('td.index', ui.item.parent()).each(function (i) {
                        $(this).html(i + 1);
                    });

                };
            $("#tableright tbody").sortable({
                helper: fixHelperModified,
                stop: updateIndex
            }).disableSelection();

第四个功能:模糊查询定位数据位置

        function dinwei_keShiKHXM() {
         // 获取搜索框的值
            var kwds = $("#keshiKHXM").val();
            // 获取第一个列表内容
            var this_one = {};
            var real_name = '';
            // 定义数据列表
            var list = $("#tableright  tr");
            // 定义查找的起始值
            var true_one = 0;
            for (var i = 1; i < list.length; i++) {
              this_one = $(list[i]);
 
              real_name = this_one.text().toString();
              // 执行like匹配
              if(real_name.match(kwds)){
                // 处理第当前的结果
                if(true_one == active){

                  // 获取第一个坐标

                  var y_len = this_one.offset().top;
                  // 驱动滚动条滚动到指定的位置

                    $('#keshiKHXMList').mCustomScrollbar('scrollTo', y_len);
                  // 标记当前选中的结果
                  this_one.addClass('td-active');
                  this_one.removeClass('on');
                }else{
                  // 标记符合的结果
                  this_one.addClass('on');
                  this_one.removeClass('td-active');
                }
                // 累加真实的选择
                true_one++;
              }else{
                  this_one.removeClass('on');
                  this_one.removeClass('td-active');
              }
            }
            // 判断是否搜索完毕 如果搜索完毕 则从第一个开始 否则继续搜索下一个
            active = active >= true_one-1 ? 0 : active+1;
 
            return false;
    }

        function dinwei_kaoHeXM() {
         // 获取搜索框的值
            var kwds = $("#kaoheXM").val();
            // 获取第一个列表内容
            var this_one = {};
            var real_name = '';
            // 定义数据列表
            var list = $("#tableleft  tr");
            // 定义查找的起始值
            var true_one = 0;
            for (var i = 1; i < list.length; i++) {
              this_one = $(list[i]);
 
              real_name = this_one.text().toString();
              // 执行like匹配
              if(real_name.match(kwds)){
                // 处理第当前的结果
                if(true_one == active){

                  // 获取第一个坐标

                  var y_len = this_one.offset().top;
                  // 驱动滚动条滚动到指定的位置

                    $('#kaoheXMList').mCustomScrollbar('scrollTo', y_len);
                  // 标记当前选中的结果
                  this_one.addClass('td-active');
                  this_one.removeClass('on');
                }else{
                  // 标记符合的结果
                  this_one.addClass('on');
                  this_one.removeClass('td-active');
                }
                // 累加真实的选择
                true_one++;
              }else{
                  this_one.removeClass('on');
                  this_one.removeClass('td-active');
              }
            }
            // 判断是否搜索完毕 如果搜索完毕 则从第一个开始 否则继续搜索下一个
            active = active >= true_one-1 ? 0 : active+1;
 
            return false;
    }

  最后就是保存数据了,我因为后台业务原因,只是获取了列表中的主键进行拼接,然后传递到后台进行处理

        function Save() {

            if ($('#tableright').bootstrapTable().find("tbody td.index").length > 0) {
                var data = null;
                var tableTRs = $('#tableright').bootstrapTable().find("tbody tr");
                if (tableTRs != null && tableTRs != undefined) {
                    for (var i = 0; i < tableTRs.length; i++) {

                        var kaoHeXMID = tableTRs.eq(i).find("td").eq(1).text();
                        if (i == 0) {
                            data = kaoHeXMID;
                        } else {
                            data += "," + kaoHeXMID;
                        }
                    }
                }
            }
            else {
                 HRP.AlertError("请先选择操作数据,再进行保存!");
                 return false;
            }

            var kaoHeFW = $('#keshiKHFW option:selected').val();
            var kaoHeLX = $('input[name="keshiLX"]:checked').val();

            postUrl("/HLGL/ChengJiGL/SavekeshiKHXM", { data: data, keShiID: keShiID, kaoHeFW: kaoHeFW,kaoHeLX: kaoHeLX }, function (res) {
                if (res == true) {
                    HRP.Tip.success("操作成功!");
                    getParentWindow().doSearch();
                    closeWin();
                }
                else {
                    HRP.AlertError("操作失败!");
                }

            })
        }

原文地址:https://www.cnblogs.com/slsddy/p/11379143.html