您的位置:首页 > Web前端 > JQuery

jquery sortable实现table拖拽排序,更新时只更新受影响的行

2016-07-19 11:21 906 查看
最开始使用时,我是参考这篇文章:

http://www.oschina.net/code/snippet_203508_7090

可以点击“全屏查看所有代码”,可以看得更清楚。

1、引入:jQuery文件和jquery-ui.js

<script src="@{'/public/javascripts/jquery-1.11.1.min.js'}" charset="UTF-8"></script>
<script src="@{'/public/javascripts/jquery-ui.min.js'}" charset="UTF-8"></script>


其中jquery-ui.min.js可以去官网下载:http://jqueryui.com/download/all/

假设我们有这么一个table:

<table class="table table-striped table-bordered table-hover" id="sortable">
<thead>
<tr>
<th style="text-align: center;">序号</th>
<th style="text-align: center;">名称</th>
<th style="text-align: center;">类型代码</th>
<th style="text-align: center;">含义</th>
<th style="text-align: center;">是否显示</th>
<th style="text-align: center;">操作</th>
</tr>
</thead>
<tbody>
#{list items:eventTypeList, as:'n'}
#{if n.status ==1}
<tr class="item" aid="${n.id}" id="${n.id}" sort="${n.sort}">
<td>${n.sort}</td>
<td>${n.radar_name}</td>
<td>${n.radar_code}</td>
<td>${n.remark}</td>
<td>显示</td>
<td><button class="btn btn-primary edit" tid="${n.id}">修改</button></td>
</tr>
#{/if}
#{/list}
</tbody>
</table>


给table中id随便去个名字,我去的名字是:sortable

如果我进行任何操作,仅仅只是拖拽的话,以下两行代码就可以啦;

$( "#sortable").sortable();
$( "#sortable").disableSelection();


但是我们往往是希望能把我们排好的顺序通过发送请求保存到后台数据库里面去!

所以我们需要以下的配置;

var fixHelper = function(e, ui) {
//console.log(ui)
ui.children().each(function() {
$(this).width($(this).width());  //在拖动时,拖动行的cell(单元格)宽度会发生改变。在这里做了处理就没问题了
});
return ui;
};

$(function() {
$( "#sortable tbody").sortable({
cursor: "move",
helper: fixHelper,                  //调用fixHelper
axis:"y",
start:function(e, ui){
ui.helper.css({"background":"#fff"})     //拖动时的行,要用ui.helper
return ui;
},
sort:function(e, ui){
array = [];
select_item = ui.item; //当前拖动的元素
var select_id = select_item.attr("id");
select_sort = select_item.attr("sort"); //当前元素的顺序
//alert(select_item);
place_item = $(this).find('tr').filter('.ui-sortable-placeholder').next('tr');//新位置下的下一个元素
place_sort = place_item.attr('sort');

place_sx = parseInt(place_sort);
select_sx = parseInt(select_sort);

if(select_sx > place_sx){ //说明是 向上移动
//array.push(select_id);
temp = place_sort;
place_sx = select_sort;//最大
select_sx = temp;//最小
flag = false;
}else{ //向下移动
place_sort = $(this).find('tr').filter('.ui-sortable-placeholder').prev('tr').attr('sort');
place_sx = parseInt(place_sort);
flag = true;
}
},
stop:function(e, ui){
//ui.item.removeClass("ui-state-highlight"); //释放鼠标时,要用ui.item才是释放的行
//发送请求,对sort字段进行修改
//alert(ui.item.attr("id"));//可以拿到id
//alert(ui.position.top);//可以拿到id
var temp = "";
#{list items:eventTypeList, as:'n'}
var sort = parseInt(${n.sort});
if(sort >= select_sx && sort <= place_sx){

if(sort == parseInt(select_sort)){//当前拖拽的元素 向上拖拽,当前元素放在数组第一个,向下,放在数组最后一个
if(flag){//向下 - 按顺序来
temp = ${n.id};
}else{//向上排序
array.splice(0,0,${n.id});
}
}else{
array.push(${n.id});
}
}
#{/list}
if(flag){
array.splice(place_sx-select_sx,0,temp);
}

if(window.confirm("确定这么排吗?")){
$.ajax({
url:'/EventAction/sortTable',
type:'POST',
async: false,
data:{'ids':array, selectSx:select_sx, placeSx:place_sx},
datatype:'json',
success:function(data){
alert(data.data);
window.location.reload();
},
error:function(){
alert('保存排序异常');
}
});
}else{
$(this).sortable( 'cancel' );
}

return ui;
},
});
$( "#sortable" ).disableSelection();
});


以上是我的代码;

其中名为fixHelper的函数方法是为了在拖拽行时,单元格的宽度保持不变!

主要的部分就是:

$( "#sortable tbody").sortable({
...
});


这里面一些固定的配置:

cursor: "move",
helper: fixHelper,                  //调用fixHelper
axis:"y", //拖拽方向是上下拖拽,x就是横向拖拽


以上配置没什么好说的,都是常用的固定配置。

之后,我的方法里面写了start:function(e,ui){},sort:function(e,ui){},stop:function(e,ui){}事件。

start事件是:当排序动作开始时触发此事件。

我的设置是
ui.helper.css({"background":"#fff"})     //拖动时的行,要用ui.helper

return ui;


sort事件是:当元素发生排序时触发此事件

在这里我进行业务逻辑的处理;

当前拖拽的元素我可以通过ui.item来获取。

如果我们向上拖拽,那么我就要获取拖拽后新位置的下一个元素。

如果我们向下拖拽,那么我就要获取拖拽后新位置的上一个元素。

为什么要这样获取呢?因为要获取到底哪些行受到了影响。

举例 table表格总共有1,2,3,4,5,6,7,8,9,10行。

假设我拖住的是第6行,把6移到了3的位置,也就是受到影响的行时3,4,5,6.

并且新的顺序是6,3,4,5.其他行没有受到影响,就不用进行处理。那么我怎么知道哪些行受到影响呢!当你移到新的位置时,你可以通过新的位置去找它的下一个元素,这里就是3这个元素。这样我们就知道是3到6行受到影响;这个是向上拖拽。向下拖拽同理。

我们还要知道两点:

1、当我们在进行拖拽时,被拖拽的当前行的样式class是会发生改变的!插件会给它添加一个名为:ui-sortable-helper类。如果不使用ui.item来获取当前元素,也可以通过这个类来获取。

2、当我们移动的时候,该插件会在新的位置,放置一个起到占位符的元素,该元素的class为:ui-sortable-placeholder。所以在拖拽过程的事件中,我们可以通过该类来获取新位置的上一个元素或者下一个元素。

插件添加的class在拖拽结束后都会移除掉!

代码如下:

$(this).find('tr').filter('.ui-sortable-placeholder').prev('tr');//上一个元素
$(this).find('tr').filter('.ui-sortable-placeholder').next('tr');//下一个元素


stop事件是:当排序动作结束时触发此事件。

在这个事件里依然也是业务逻辑的处理。

sort事件里我只是获取到了当前元素位置、新位置的上一个或者下一个元素的位置(也就是两个参数)。在stop事件里,我将通过这两个参数来把受影响的行组装成新的顺序,并放到array数组中去。再通过ajax发送到后台保存到数据库里去!stop事件中逻辑处理代码:

var temp = "";
#{list items:eventTypeList, as:'n'}
var sort = parseInt(${n.sort});
if(sort >= select_sx && sort <= place_sx){

if(sort == parseInt(select_sort)){//当前拖拽的元素 向上拖拽,当前元素放在数组第一个,向下,放在数组最后一个
if(flag){//向下 - 按顺序来
temp = ${n.id};
}else{//向上排序
array.splice(0,0,${n.id});
}
}else{
array.push(${n.id});
}
}
#{/list}
if(flag){
array.splice(place_sx-select_sx,0,temp); //第一个参数是添加/删除项目的位置,第二个参数是:删除的项目数量 0就是不会删除项目 第三个参数添加新项目
}


数据库表中有个sort字段,专门用来记录顺序的!

最后$(“#sortable”).disableSelection();//防止拖拽时选中文本内容!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: