项目有一组数据,展示给前端时顺序可以任意调整,这时就不能简单的根据发布时间或更新时间来排序了,我的做法是给表增加一个排序字段,数值越大,显示越靠前。拖动调整无疑是最方便的设置的方式了,使用的是jquery-ui的sortable插件。
先引入js文件,其他js文件省略:
<script type="text/javascript" src="../script/plugin/jquery-ui-1.10.3.custom/js/jquery-1.9.1.js"></script>
<script type="text/javascript" src="../script/plugin/jquery-ui-1.10.3.custom/js/jquery-ui-1.10.3.custom.min.js"></script>
<script type="text/javascript" src="../script/plugin/jquery-ui-1.10.3.custom/development-bundle/ui/jquery.ui.sortable.js"></script>
html部分,其他无关代码省略:
<table class="listTable" id="sort">
<thead>
<tr>
<th class="check">
<input type="checkbox" class="allCheck" />
</th>
<th>
<span class="">id</span>
</th>
<th>
<span class="">问题</span>
</th>
<th>
<span class="">排序值</span>
</th>
<th>
<span class="">创建时间</span>
</th>
<th>
<span class="sort">修改时间</span>
</th>
<th>
<span class="sort" >操作人</span>
</th>
</tr>
</thead>
<tbody class="sortable">
<s:iterator value="pager.list" id="list" status="status">
<tr id="${list.id}" title="拖动表格可交换排序">
<td>
<input type="checkbox" name="ids" id="ids" ids="${list.id}" value="${list.id}"/>
</td>
<td>${list.id}</td>
<td>${list.question}</td>
<td>${list.sort}</td>
<td><fmt:formatDate value="${list.createDate}" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formatDate></td>
<td><fmt:formatDate value="${list.modifyDate}" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formatDate></td>
<td>${list.admin.name}</td>
</tr>
</s:iterator>
</tbody>
</table>
留意下table加了id属性,tbody加了class属性,tbody下tr有id属性,这在js部分有用。脚本处理:
$(document).ready(function() {
var $dom = $(".sortable");
var old=null;//旧的顺序
$dom.sortable({
cursor: "move",
items: "tr", //只是tr可以拖动
axis:"y",//只允许垂直方向拖动,
containmentType:"parent",
opacity: 0.6, //拖动时,透明度为0.6
revert: true, //释放时,增加动画
start:function(event, ui){//开始排序时调用
old = $(this).sortable("toArray");
},
update: function(event, ui) { //更新排序完成之后
var news = $(this).sortable("toArray");//新的顺序
var $this = $(this);
$.ajax({
url: 'helpdoc!editSaveSort.action',
type: 'POST',
traditional:true,
data: {old:old,news:news},
success: function(data) {
if (data.code != 1) {
$this.sortable("cancel");
alert("移动失败:"+data.msg);
}else{
location.reload();
}
}
});
}
});
$dom.disableSelection();
});
大致思路是,开始拖动时用old变量保存当前的id序列,news变量保存拖动后的id序列,然后将这个两个数组扔给服务器。留意下发送ajax时指定了“traditional:true”,为的是便于服务器绑定Integer数组。
前端代码差不多就这样了,界面应该能拖动调整顺序了,接着看服务器如何处理了:
/**
* 设置排序顺序
*/
@Override
public void editSaveSort(Long[] old, Long[] news) throws Exception {
if (old != null && old.length > 0) {
Map<Long, Integer> map = new HashMap<Long, Integer>();
for (int i = 0; i < news.length; i++) {
Long nid = news[i];
Long oid = old[i];
if (oid.intValue() == nid.intValue()) {
continue;
}
Helpdoc h1 = this.get(nid);
map.put(nid, h1.getSort());
Integer sort = map.get(oid);
if (sort == null) {
Helpdoc h2 = this.get(oid);
sort = h2.getSort();
map.put(oid, sort);
}
h1.setSort(sort);
this.update(h1);
}
}
}
其中,old和news分别对应前端传过来的id序列。我的做法是,遍历新的数组,如果同一索引下两个数组的id值不一样,那就将nid对应的sort值设置为oid对应的sort值。map是缓存,保存每个id修改之前的sort值,特别重要。