在上篇隨筆《基於Metronic的Bootstrap開發框架經驗總結(12)--頁面鏈接收藏夾功能的實現》上,我介紹了鏈接收藏夾功能的實現,以及對收藏記錄的排序處理。該篇隨筆主要使用功能按鈕的方式移動收藏記錄,功能雖然實現的還算不錯,不過文章出來後,有讀者同行指出可以利用直接拖動的方式實現排序更方便... ...
在上篇隨筆《基於Metronic的Bootstrap開發框架經驗總結(12)--頁面鏈接收藏夾功能的實現》上,我介紹了鏈接收藏夾功能的實現,以及對收藏記錄的排序處理。該篇隨筆主要使用功能按鈕的方式移動收藏記錄,功能雖然實現的還算不錯,不過文章出來後,有讀者同行指出可以利用直接拖動的方式實現排序更方便,因此對其中列表記錄的排序進行了研究,從而介紹瞭如何利用Sortable開源JS組件實現拖動排序的處理,本篇隨筆介紹了該組件在連接收藏夾排序中的應用。
1、收藏記錄的排序處理回顧
上篇隨筆介紹的收藏夾處理,主要就是為了方便用戶快速進入常用功能的一個模塊,隨著收藏夾記錄的增多,我們有必要對它們進行合理的排序,以方便我們的使用。
原來的收藏夾記錄排序界面如下所示。
這個界面裡面包含了對記錄的移動處理,包括向上或者向下。
實現的邏輯代碼主要就是對當前記錄的前後記錄的排序進行調整的處理,從而實現位置的調整,代碼如下所示。
/// <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條記錄記錄,則取其最近的兩個記錄,取他們的平均值即可。
2、收藏夾的拖動排序處理
上面的處理能夠滿足基本的要求,而且調整位置也是正確的。但是我們如果能夠拖動列表項進行排序的話,那樣就更加方便、更加友好的了。
基於拖動的排序,我尋找到了一個比較好的JS處理組件(Sortable)這個在github上排名比較高,估計用的人也很多。
這個控制項的使用相對比較簡單,代碼如下所示。
<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整合好的界面效果。
這樣我們就可以通過移動記錄的方式進行調整位置。
列表的展示,我們還是使用分頁的方式,為了提高檢索效率。
<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裡面構建一系列的列表記錄即可。
<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的事件可以處理,如下所示。
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組件,能夠提高我們用戶的體檢效果。