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

最开始使用时,我是参考这篇文章:
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();//防止拖拽时选中文本内容!

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山鬼谣me

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值