在上篇随笔《基于Metronic的Bootstrap开发框架经验总结(12)--页面连接收藏夹功能的实现》上,我介绍了连接收藏夹功能的实现,以及对收藏记录的排序处理。该篇随笔主要使用功能按钮的方式移动收藏记录,功能虽然实现的还算不错,不过文章出来后,有读者同行指出能够利用直接拖动的方式实现排序更方便,所以对其中列表记录的排序进行了研究,从而介绍了如何利用Sortable开源JS组件实现拖动排序的处理,本篇随笔介绍了该组件在链接收藏夹排序中的应用。git
上篇随笔介绍的收藏夹处理,主要就是为了方便用户快速进入经常使用功能的一个模块,随着收藏夹记录的增多,咱们有必要对它们进行合理的排序,以方便咱们的使用。
原来的收藏夹记录排序界面以下所示。github
这个界面里面包含了对记录的移动处理,包括向上或者向下。
实现的逻辑代码主要就是对当前记录的先后记录的排序进行调整的处理,从而实现位置的调整,代码以下所示。json
/// <summary> /// 更新向上或者向下的顺序 /// </summary> /// <param name="id">记录的ID</param> /// <param name="moveUp">往上,仍是往下移动,往上则为true</param> /// <returns></returns> public bool UpDown(string id, bool moveUp) { //设置排序的规则 bool IsDescending = true; bool result = false; WebFavoriteInfo info = FindByID(id); if (info != null) { //构建查询的条件 string condition = ""; if (IsDescending) { condition = string.Format("Seq {0} {1}", moveUp ? ">" : "<", info.Seq); } else { condition = string.Format("Seq {0} {1}", moveUp ? "<" : ">", info.Seq); } var list = baseDal.Find(condition); decimal newSeq = 0M; switch (list.Count) { case 0: newSeq = info.Seq;//已在顶部或者底部,顺序默认不变 break; case 1: //上面或者下面有一个记录 if (IsDescending) { newSeq = moveUp ? (list[0].Seq + 1M) : (list[0].Seq - 1M); } else { newSeq = !moveUp ? (list[0].Seq + 1M) : (list[0].Seq - 1M); } break; case 2: //中间区域,取平均值 newSeq = (list[0].Seq + list[1].Seq) / 2M; break; default: //多于两个的状况 if (moveUp) { newSeq = (list[list.Count - 2].Seq + list[list.Count - 1].Seq) / 2M; } else { newSeq = (list[0].Seq + list[1].Seq) / 2M; } break; } //统一修改顺序 info.Seq = newSeq; result = Update(info, info.ID); } return result; }
以上的代码,经过判断当前移动记录的位置,而后获取排序在其上面或者下面的记录,若是记录数量为0 ,那么就是顶端或者底端的了,若是是1条记录,那么就是在该记录上增长或者减除某个数值就做为新排序位置的值便可。若是是大于或等于2条记录记录,则取其最近的两个记录,取他们的平均值便可。框架
上面的处理可以知足基本的要求,并且调整位置也是正确的。可是咱们若是可以拖动列表项进行排序的话,那样就更加方便、更加友好的了。
基于拖动的排序,我寻找到了一个比较好的JS处理组件(Sortable)这个在github上排名比较高,估计用的人也不少。
这个控件的使用相对比较简单,代码以下所示。post
<ul id="items"> <li>item 1</li> <li>item 2</li> <li>item 3</li> </ul> var el = document.getElementById('items'); var sortable = new Sortable(el);
咱们先来看看我最终使用Sortable整合好的界面效果。url
这样咱们就能够经过移动记录的方式进行调整位置。
列表的展现,咱们仍是使用分页的方式,为了提升检索效率。spa
<div class="portlet-body flip-scroll"> <div class="portlet-body"> <div> <span>每页显示</span> <select id="rows" onchange="ChangeRows()"> <option>10</option> <option selected>50</option> <option>100</option> <option>1000</option> </select> <span>条记录</span> <span>共有记录:</span><span id='totalCount' class="label label-success">0</span>条,总页数:<span id='totalPageCount' class="label label-success">0</span>页。 </div> <hr /> <div id="grid_body" class='list-group'></div> <div class="paging-toolbar"> <ul id='grid_paging'></ul> </div> </div> </div>
在这里面咱们经过在grid_body里面构建一系列的列表记录便可。code
<div class="list-group-item"> <span class="glyphicon glyphicon-move" aria-hidden="true"></span> <a class="btn btn-sm blue" id="e1f462c6-c749-4258-836f-e13ee8c8acd7" href="http://localhost:2251/User/Index?tid=2744DBF5-A648-47C1-9E9A-D8B405884389">系统用户信息</a> <i class="js-remove">✖</i> </div>
在记录的更新后,该Sortable组件有一个OnUpdate的事件能够处理,以下所示。orm
var grid_body = document.getElementById('grid_body'); new Sortable(grid_body, { handle: '.glyphicon-move', filter: ".js-remove", animation: 150, onUpdate: function (/**Event*/evt) { var list = [];//构造集合对象 $('.list-group div a').each(function (i, item) { list.push({ 'Text': item.text, 'Value': item.href }); }); var url = "/WebFavorite/EditFavorite"; var postData = { list: list }; $.post(url, postData, function (json) { var data = $.parseJSON(json); if (data.Success) { //showTips("操做成功"); Refresh();//刷新页面数据 } else { showTips(data.ErrorMessage); } }); }, });
这样咱们把业务处理交给EditFavorite方法了,这里面主要对列表记录进行统一更新便可,处理逻辑就是先删除之前的记录,而后添加列表的集合记录,而且设置它们的排序记录为合适的顺序便可。对象
/// <summary> /// 编辑记录列表 /// </summary> /// <param name="list">记录列表</param> /// <returns></returns> [HttpPost] public ActionResult EditFavorite(List<CListItem> list) { CommonResult result = new CommonResult(); var userid = CurrentUser.ID; DbTransaction trans = BLLFactory<WebFavorite>.Instance.CreateTransaction(); if (trans != null) { try { //先删除就记录 var condition = string.Format("Creator='{0}'", userid); BLLFactory<WebFavorite>.Instance.DeleteByCondition(condition, trans); //逐条添加记录 int i = list.Count; foreach (CListItem item in list) { WebFavoriteInfo info = new WebFavoriteInfo(); info.Title = item.Text; info.Url = item.Value; info.Seq = i--; info.Creator = CurrentUser.ID.ToString(); BLLFactory<WebFavorite>.Instance.Insert(info, trans); } trans.Commit(); result.Success = true; } catch(Exception ex) { result.ErrorMessage = ex.Message; trans.Rollback(); LogHelper.Error(ex); } } return ToJsonContent(result); }
以上就是对收藏夹列表进行拖动排序的改进处理,但愿在实际的项目中可以合理利用这个Sortable的JS组件,可以提升咱们用户的体检效果。