JS组件Bootstrap Table表格多行拖拽效果实现代码

前言:前天刚写了篇JS组件Bootstrap Table表格行拖拽效果,今天接到新的需要,需要在之前表格行拖拽的基础上能够同时拖拽选中的多行。用了半天时间研究了下,效果是出来了,但是感觉不尽如人意。先把它分享出来,以后想到更好的办法再优化吧。

一、效果展示

1、拖动前

2、拖动中

3、拖动后

4、撤销回到拖动前状态

二、需求分析
通过上篇我们知道,如果要实现拖拽,必须要有一个可以拖拽的标签,或者叫容器,比如上篇里面的tr就是一个拖拽的容器,那么如果要实现选择行的拖拽,那么博主的第一反应是将选中的行放到一个容器里面,比如放到一个div中,然后注册这个div的可拖拽,可是实际情况是,tr是在table里面的标签,如果将tr用div包起来,势必将table里面的样式打乱,这个界面就真的是乱掉了。很显然,这条路走不通。然后通过谷歌浏览器审核元素知道,用Bootstrap table生成的表格tr的父级元素实际上是tbody,于是在想是否可以注册tbody的拖拽,实践证明,此法可行。于是就此开干。

三、代码示例
cshtm的代码就不再重复,和上篇相同。我们重点来看看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();
 if (data.total > 0) {
 var iheight = $('#div_tableleft').find(".fixed-table-container").height();
 $('#div_tableleft').find(".fixed-table-container").height(iheight + 36);
 }
 },
 onCheckAll: function (rows) {
 $("#tb_order_left tbody tr").addClass("selected");
 },
 onUncheckAll: function (rows) {
 $("#tb_order_left tbody tr").removeClass("selected");
 }
 });

 $('#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();
 }
 });
 };

 oTableInit.InitDrag = function () {
 $('#tb_order_left tbody').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) {
 }
 });
 };

 oTableInit.InitDrop = function () {
 $("#div_tableright div[class=fixed-table-container]").droppable({
 drop: function (event, ui) {
 var arrtr = $(ui.helper[0]).find("tr[class=selected]");
 if (arrtr.length <= 0) {
 alert("请先选中要插单的行");
 return;
 }
 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);
 }
 for (var i = 0; i < arrtr.length; i++) {
 var arrtd = $(arrtr[i]).find("td");
 var uniqueid = $(arrtr[i]).attr("data-uniqueid");
 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: uniqueid

 };
 $("#tb_order_right").bootstrapTable("insertRow", { index: rowIndex++, row: rowdata });
 $('#tb_order_left').bootstrapTable("removeByUniqueId", 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_insertorder").click(function () {

 });

 //撤销操作点击事件
 $("#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();
 });
 };

 return oInit;
};

还是重点看看部分代码

1、注册左边可拖拽

$('#tb_order_left tbody').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) {
 }
 });

这里代码很简单,主要做了两件事:

(1)注册tbody的可拖拽,同样适用的JQuery UI的draggable事件。

(2)在开始拖拽前,保存两边表格的数据,用于还原的操作。

2、注册右边drop

    $("#div_tableright div[class=fixed-table-container]").droppable({
 drop: function (event, ui) {
 var arrtr = $(ui.helper[0]).find("tr[class=selected]");
 if (arrtr.length <= 0) {
 alert("请先选中要插单的行");
 return;
 }
 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);
 }
 for (var i = 0; i < arrtr.length; i++) {
 var arrtd = $(arrtr[i]).find("td");
 var uniqueid = $(arrtr[i]).attr("data-uniqueid");
 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: uniqueid

 };
 $("#tb_order_right").bootstrapTable("insertRow", { index: rowIndex++, row: rowdata });
 $('#tb_order_left').bootstrapTable("removeByUniqueId", uniqueid);
 }

 oTableInit.InitDrag();
 }
 });

这里代码和之前有点变化

(1)注册#div_tableright div[class=fixed-table-container]标签的droppable,这个标签是Bootstrap Table表格初始化后自动生成的,为什么不直接注册表格#tb_order_right的droppable,是因为这个标签作用域太小,会导致拖过来的tbody捕捉不到drop事件。而注册表格外部的#div_tableright div[class=fixed-table-container]这个div标签可以解决问题。

(2)通过var arrtr = $(ui.helper[0]).find("tr[class=selected]");找到拖过来tbody里面选中的行,然后将数据取出依次插入右边表格,左边表格则依次删除行数据。

(3)这里有点麻烦的是找drop的位置,我们知道,要想将左边选中的行放到右边指定的位置,那么就得得到当前鼠标drop的位置,这里通过ui.helper[0].offsetTop属性来获得鼠标的Y轴位置,通过计算得到要插入的位置。

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();
 //m_oTable.InitDrop();
 });

撤销操作和之前也基本相同。

四、总结
效果是完成了,美中不足的是每次拖过去的都是整个tbody,而不是选中的行,奈何多个选中的行无法用某一个容器包起来。暂时没找到合适的解决方案。先这样吧,等以后想到好的方案了再优化吧。

五、优化方案

1、注册drap的方法

oTableInit.InitDrag = function () {
 $('#tb_order_left tbody').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);
 $(ui.helper[0]).find("tr[class!=selected]").remove();
 },
 stop: function (event, ui) {
 }
 });
 };

增加了这一句$(ui.helper[0]).find("tr[class!=selected]").remove();这样在拖动的时候就看不到未选中的行了。
2、精准定位到右边表格指定位置:

oTableInit.InitDrop = function () {
 $("#div_tableright div[class=fixed-table-container]").droppable({
 drop: function (event, ui) {
 var arrtr = $(ui.helper[0]).find("tr[class=selected]");
 if (arrtr.length <= 0) {
 toastr.warning('请先选中要插单的行');
 return;
 }
 var oTop = ui.helper[0].offsetTop;
 //因为表格每行的高度可能不一致,所以这里取插入行位置的办法是:取右边表格的行高依次累加,计算行索引。
 var rowIndex = 0;
 var bIsBottom = true;
 var iRowHeadHeight = 40;
 var addHeight = iRowHeadHeight;
 var trs = $("#tb_order_right tbody tr");
 for (var i = 0; i < trs.length; i++) {
 addHeight += $(trs[i]).height();
 if (addHeight > oTop) {
 rowIndex = i;
 bIsBottom = false;//这里参数用来定义拖动到右边表格最下面的情况,这时没有进入到此条件判断里面。
 break;
 }
 }
 if (bIsBottom) {
 rowIndex = trs.length;
 }

 for (var i = 0; i < arrtr.length; i++) {
 var arrtd = $(arrtr[i]).find("td");
 var uniqueid = $(arrtr[i]).attr("data-uniqueid");
 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_NAME: $(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: uniqueid,
 ORDER_STATUS:0

 };
 $("#tb_order_right").bootstrapTable("insertRow", { index: rowIndex++, row: rowdata });
 $('#tb_order_left').bootstrapTable("removeByUniqueId", uniqueid);
 }

 oTableInit.InitDrag();

 }
 });
 };

因为每一行的行高不确定,是由行里面的数据动态撑出来的,所以这里也动态计算drop的位置。

至此,这个小的功能基本告一段落,基本的效果和待优化点也完成了。

源码下载:Bootstrap Table表格多行拖拽效果

如果大家还想深入学习,可以点击这里进行学习,再为大家附两个精彩的专题:Bootstrap学习教程 Bootstrap实战教程

以上就是本文的全部内容,希望本文所述对大家学习javascript程序设计有所帮助。

(0)

相关推荐

  • JS组件系列之Bootstrap table表格组件神器【二、父子表和行列调序】

    Bootstrap Table是轻量级的和功能丰富的以表格的形式显示的数据,支持单选,复选框,排序,分页,显示/隐藏列,固定标题滚动表,响应式设计,Ajax加载JSON数据,点击排序的列,卡片视图等.今天就结合Bootstrap table的父子表和行列调序的用法再来介绍下它稍微高级点的用法. bootstrap table系列: JS表格组件神器bootstrap table详解(基础版) JS组件系列之Bootstrap table表格组件神器[终结篇] JS组件系列之Bootstrap t

  • JS组件系列之Bootstrap table表格组件神器【终结篇】

    bootstrap table系列: JS表格组件神器bootstrap table详解(基础版) JS组件系列之Bootstrap table表格组件神器[终结篇] JS组件系列之Bootstrap table表格组件神器[二.父子表和行列调序] Bootstrap Table是轻量级的和功能丰富的以表格的形式显示的数据,支持单选,复选框,排序,分页,显示/隐藏列,固定标题滚动表,响应式设计,Ajax加载JSON数据,点击排序的列,卡片视图等.那么本文给大家介绍JS组件系列之Bootstrap

  • JS组件Bootstrap Table使用实例分享

    学习使用bootstrap表格是对客户端进行分页的时候,在朋友的帮助下,找到了文档http://bootstrap-table.wenzhixin.net.cn/examples/                  找到了传到后台的每页条数Limit,和记录开始数Offset.              开始封装,分享一下我的代码,从bootstrap table 获取页码和页数,并交给后台处理. $('#table').bootstrapTable({ url: '<%=path%>/Fee

  • JS表格组件神器bootstrap table详解(基础版)

    一.Bootstrap Table的引入 关于Bootstrap Table的引入,一般来说还是两种方法: 1.直接下载源码,添加到项目里面来. 由于Bootstrap Table是Bootstrap的一个组件,所以它是依赖Bootstrap的,我们首先需要添加Bootstrap的引用. 2.使用我们神奇的Nuget 打开Nuget,搜索这两个包 Bootstrap已经是最新的3.3.5了,我们直接安装即可. 而Bootstrap Table的版本竟然是0.4,这也太坑爹了.所以博主建议Boot

  • 以BootStrap Tab为例写一个前端组件

    介绍 本文以Bootstrap标签页组件为例,介绍如何编写或者封装一个前端组件,以下是实现效果: 原生的Bootstrap-tab组件主要有html,css组成,开发者使用时,需要写很多代码,不易于使用,对bootstrap-tab封装后,可以更方便地使用,同时提供关闭.增加tab页.指定当前选中页.即使加载等功能,这样组件可以适配更多的场景. 原生bootstrap-tab组件使用可参考https://www.runoob.com/bootstrap/bootstrap-tab-plugin.

  • JS表格组件神器bootstrap table详解(强化版)

    一.Bootstrap Table的引入 关于Bootstrap Table的引入,一般来说还是两种方法: 1.直接下载源码,添加到项目里面来. 由于Bootstrap Table是Bootstrap的一个组件,所以它是依赖Bootstrap的,我们首先需要添加Bootstrap的引用. 2.使用我们神奇的Nuget 打开Nuget,搜索这两个包 Bootstrap已经是最新的3.3.5了,我们直接安装即可. 而Bootstrap Table的版本竟然是0.4,这也太坑爹了.所以博主建议Boot

  • JS组件Bootstrap Table布局详解

    Bootstrap 提供了一个清晰的创建表格的布局.下表列出了 Bootstrap 支持的一些表格元素: 表格类 下表样式可用于表格中: <tr>, <th> 和 <td> 类 下表的类可用于表格的行或者单元格: 基本的表格 如果您想要一个只带有内边距(padding)和水平分割的基本表,请添加 class .table,如下面实例所示: <div class="row"> <table class="table"

  • JS组件Bootstrap Table使用方法详解

    最近客户提出需求,想将原有的管理系统,做下优化,通过手机也能很好展现,想到2个方案: a方案:保留原有的页面,新设计一套适合手机的页面,当手机访问时,进入m.zhy.com(手机页面),pc设备访问时,进入www.zhy.com(pc页面) b方案:采用bootstrap框架,替换原有页面,自动适应手机.平板.PC 设备 采用a方案,需要设计一套界面,并且要得重新写适合页面的接口,考虑到时间及成本问题,故项目采用了b方案 一.效果展示 二.BootStrap table简单介绍 bootStra

  • JS组件Bootstrap Table表格行拖拽效果实现代码

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

  • JS组件Bootstrap Table表格多行拖拽效果实现代码

    前言:前天刚写了篇JS组件Bootstrap Table表格行拖拽效果,今天接到新的需要,需要在之前表格行拖拽的基础上能够同时拖拽选中的多行.用了半天时间研究了下,效果是出来了,但是感觉不尽如人意.先把它分享出来,以后想到更好的办法再优化吧. 一.效果展示 1.拖动前 2.拖动中 3.拖动后 4.撤销回到拖动前状态 二.需求分析 通过上篇我们知道,如果要实现拖拽,必须要有一个可以拖拽的标签,或者叫容器,比如上篇里面的tr就是一个拖拽的容器,那么如果要实现选择行的拖拽,那么博主的第一反应是将选中的

  • BootStrap table实现表格行拖拽效果

    本文实例为大家分享了BootStrap table实现表格行拖拽的具体代码,供大家参考,具体内容如下 不上图了 首先还是得添加三个文件,自己上网搜搜就行 <script src="~/Content/bootstrap-table/jquery.tablednd.js"></script> <script src="~/Content/bootstrap-table/bootstrap-table-reorder-rows.js">

  • js实现弹出框的拖拽效果实例代码详解

    具体代码如下所示: //HTML部分 <div class="wrap"></div> <div class="popUpBox"> <div class="layer-head"><div class="layer-head-text">弹出框</div><div class="layer-close"></div&

  • bootstrap table实现iview固定列的效果实例代码详解

    因为bootstrap自带的固定列效果满足不了公司需求,所以借助fixed-table这个插件完成了iview固定列的效果 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>左右两侧固定列,中间内容可以横向拖动</title> <link rel="stylesheet" hr

  • Android仿美团拖拽效果实例代码

    效果图 如上图,实现了拖拽事件的无缝过渡.效果很流畅很自然,之所以写轮子因为实在找不到好用的库,该库参考了https://github.com/woxingxiao/SlidingUpPanelLayout ,其实在大神的开源库里就有Issues提到内嵌 scrollView 时滑动冲突的问题.再加上最近项目里面的详情页就有这样的拖拽效果需求,只好自己实现一遍. 在实现的过程中,就遇到几个比较棘手的问题,也经过了一番挣扎才想出解决的方案. 困难 拖拽释放的时机,如下拉1/6就自动收缩否则回弹,上

  • js最简单的拖拽效果实现代码

    其实对于弹出层而言,拖拽最初的目的很单纯,就是为了通过拉开层,使被弹出层挡住的内容可见,(当然,后来关于拖拽的功能不断被优化,使得拖拽的应用有了别的意义,最典型的如igoogle的自定义首页,通过拖放的形式满足用户自定义想要的内容模块顺序和位置). 本文讨论的重点不是iGoogle的拖放效果,那属于进阶篇,本文是拖拽的"第一阶",如题,实现最简单的拖拽. 这里的"最简单"即不考虑多个拖拽层的堆叠顺序,不考虑拖拽范围限制,不考虑类似iGoogle的"drag

随机推荐