原文出處:
http://elliotttravel.blogspot.tw/2015/01/jquery-ui-sortable.html
jQuery UI有個很好用的功能,可以使用拖曳的方式,直接調整畫面的順序,請見jQuery UI官網 jqueryui.com
但拖曳完後,要怎麼把排列順序存入後端呢?
資料庫設計了CategoryId、CategoryName、CategoryOrder三個欄位(CategoryOrder記錄順序)
首先先處理html的部份
1. 先加入jvavscript (因為套bootstrap畫面較好看,所以順便加入)
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery-ui-1.11.2.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
2. 加入css (可省略,只是為了加入bootstrap畫面較好看)
<link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
3. 設計表格,Sortable 也可支援<ul></ul>不一定要使用table
4.套入jQuery UI Sortable效果,在update裡使用$(this).sortable('toArray').toString();將表格裡的<tr id="@Html.DisplayFor(modelItem => item.CategoryOrder)">串成字串,但此方法只能將id轉成字串,較好的方法應該是取td裡的CategoryOrder欄位,但sortable好像沒辦法直接取到,可能要用jquery想辦法去取…就沒有做測試了
最後將組好的字串傳到後端處理,存進資料庫就大功告成囉~~
另外,因為沒有使用Angular或Knockout來做Data binding,而且傳到後端的是取tr的id…所以每次必需Reload畫面,讓id更新才行,較好的方法應該是使用Data binding,讓畫面上的CategoryOrder會即時更改,並取出傳至後端,就不需要每次重load了。
更新jQuery UI Sortable取得oldIndex和newIndex的方法,只需要傳兩個值到後端,就能夠偵對order進行排序,無需傳入一整個list囉。
1. start,當拖曳動作開始,就會先執行這一段,這使用ui.item.index(),就可以取得目前使用者拖曳的item的index,在用ui.item.data('start_pos', start_pos),把index填進此item的'start_pos'(這個名字可以自訂),tag中,產生出來的html會變成 <tr start_pos = "index"></tr>
2. 在update時,就可以使用ui.item.data('start_pos'),將剛才存下來的index取出來,在使用ui.item.context.rowIndex取得最新的index,將這兩個index傳到後端就大空告成了!!
3. 順便附上後端的c# code供大家參考
比上次的方法容易且合理多了,如果grid有設定分頁的話,別忘了把page和pagesize也傳到後端進行判斷囉!!
但拖曳完後,要怎麼把排列順序存入後端呢?
資料庫設計了CategoryId、CategoryName、CategoryOrder三個欄位(CategoryOrder記錄順序)
首先先處理html的部份
1. 先加入jvavscript (因為套bootstrap畫面較好看,所以順便加入)
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery-ui-1.11.2.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
2. 加入css (可省略,只是為了加入bootstrap畫面較好看)
<link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
3. 設計表格,Sortable 也可支援<ul></ul>不一定要使用table
<table id="mytable" class="table"> <tr> <th> @Html.DisplayNameFor(model => model.CategoryName) </th> <th> @Html.DisplayNameFor(model => model.CategoryOrder) </th> <th></th> </tr> <tbody id="myfruit"> @foreach (var item in Model.OrderBy(r => r.CategoryOrder)) { <tr id="@Html.DisplayFor(modelItem => item.CategoryOrder)"> <td> @Html.DisplayFor(modelItem => item.CategoryName) </td> <td> @Html.DisplayFor(modelItem => item.CategoryOrder) </td> <td> @Html.ActionLink("Edit", "Edit", new { id = item.CategoryId }) | @Html.ActionLink("Details", "Details", new { id = item.CategoryId }) | @Html.ActionLink("Delete", "Delete", new { id = item.CategoryId }) </td> </tr> } </tbody> </table>
4.套入jQuery UI Sortable效果,在update裡使用$(this).sortable('toArray').toString();將表格裡的<tr id="@Html.DisplayFor(modelItem => item.CategoryOrder)">串成字串,但此方法只能將id轉成字串,較好的方法應該是取td裡的CategoryOrder欄位,但sortable好像沒辦法直接取到,可能要用jquery想辦法去取…就沒有做測試了
最後將組好的字串傳到後端處理,存進資料庫就大功告成囉~~
另外,因為沒有使用Angular或Knockout來做Data binding,而且傳到後端的是取tr的id…所以每次必需Reload畫面,讓id更新才行,較好的方法應該是使用Data binding,讓畫面上的CategoryOrder會即時更改,並取出傳至後端,就不需要每次重load了。
$(function () { $('#mytable tbody').sortable({ opacity: 0.6, cursor: 'move', axis: 'y', update: function (event, ui) { var productOrder = $(this).sortable('toArray').toString(); $.ajax({ type: 'post', url: '/Home/DragItem', data: { orders: productOrder }, success: function (result) { window.location.href = result.redirectToUrl; } }); } }); });-------------------------2015.01.17更新------------------------------------------------
更新jQuery UI Sortable取得oldIndex和newIndex的方法,只需要傳兩個值到後端,就能夠偵對order進行排序,無需傳入一整個list囉。
$('#grid tbody').sortable({ opacity: 0.6, cursor: 'move', axis: 'y', start: function (event, ui) { var start_pos = ui.item.index(); ui.item.data('start_pos', start_pos); }, update: function (event, ui) { //var productOrder = $(this).sortable('toArray').toString(); var oldIndex = ui.item.data('start_pos'); var newIndex = ui.item.context.rowIndex; $.ajax({ type: 'post', url: '/PeopleGroups/DropOrderItem', data: { oldIndex: oldIndex + 1, newIndex: newIndex + 1, page: currPage, pageSize: pageSize } }); } });
1. start,當拖曳動作開始,就會先執行這一段,這使用ui.item.index(),就可以取得目前使用者拖曳的item的index,在用ui.item.data('start_pos', start_pos),把index填進此item的'start_pos'(這個名字可以自訂),tag中,產生出來的html會變成 <tr start_pos = "index"></tr>
2. 在update時,就可以使用ui.item.data('start_pos'),將剛才存下來的index取出來,在使用ui.item.context.rowIndex取得最新的index,將這兩個index傳到後端就大空告成了!!
3. 順便附上後端的c# code供大家參考
if (oldIndex < newIndex) { var currGroup = ESHCloudsContext.PeopleGroups.SingleOrDefault(r => r.GroupOrder == oldIndex); if (currGroup == null) return false; var peopleGroupList = ESHCloudsContext.PeopleGroups .Where(r => r.GroupOrder <= newIndex && r.GroupOrder > oldIndex && r.GroupID != currGroup.GroupID ).ToList(); foreach (var peopleGroup in peopleGroupList) peopleGroup.GroupOrder--; currGroup.GroupOrder = newIndex; ESHCloudsContext.SaveChanges(); } else { var currGroup = ESHCloudsContext.PeopleGroups.SingleOrDefault(r => r.GroupOrder == oldIndex); if (currGroup == null) return false; var peopleGroupList = ESHCloudsContext.PeopleGroups .Where(r => r.GroupOrder < oldIndex && r.GroupOrder >= newIndex && r.GroupID != currGroup.GroupID ).ToList(); foreach (var peopleGroup in peopleGroupList) peopleGroup.GroupOrder++; currGroup.GroupOrder = newIndex; ESHCloudsContext.SaveChanges(); }
比上次的方法容易且合理多了,如果grid有設定分頁的話,別忘了把page和pagesize也傳到後端進行判斷囉!!
沒有留言:
張貼留言