1 /* |
|
2 * File: jquery.dataTables.rowReordering.js |
|
3 * Version: 1.2.1. |
|
4 * Author: Jovan Popovic |
|
5 * |
|
6 * Copyright 2013 Jovan Popovic, all rights reserved. |
|
7 * |
|
8 * This source file is free software, under either the GPL v2 license or a |
|
9 * BSD style license, as supplied with this software. |
|
10 * |
|
11 * This source file is distributed in the hope that it will be useful, but |
|
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|
13 * or FITNESS FOR A PARTICULAR PURPOSE. |
|
14 * |
|
15 * Parameters: |
|
16 * @iIndexColumn int Position of the indexing column |
|
17 * @sURL String Server side page tat will be notified that order is changed |
|
18 * @iGroupingLevel int Defines that grouping is used |
|
19 */ |
|
20 (function ($) { |
|
21 |
|
22 "use strict"; |
|
23 $.fn.rowReordering = function (options) { |
|
24 |
|
25 function _fnStartProcessingMode(oTable) { |
|
26 ///<summary> |
|
27 ///Function that starts "Processing" mode i.e. shows "Processing..." dialog while some action is executing(Default function) |
|
28 ///</summary> |
|
29 |
|
30 if (oTable.fnSettings().oFeatures.bProcessing) { |
|
31 $(".dataTables_processing").css('visibility', 'visible'); |
|
32 } |
|
33 } |
|
34 |
|
35 function _fnEndProcessingMode(oTable) { |
|
36 ///<summary> |
|
37 ///Function that ends the "Processing" mode and returns the table in the normal state(Default function) |
|
38 ///</summary> |
|
39 |
|
40 if (oTable.fnSettings().oFeatures.bProcessing) { |
|
41 $(".dataTables_processing").css('visibility', 'hidden'); |
|
42 } |
|
43 } |
|
44 |
|
45 ///Not used |
|
46 function fnGetStartPosition(oTable, sSelector) { |
|
47 var iStart = 1000000; |
|
48 $(sSelector, oTable).each(function () { |
|
49 var iPosition = parseInt(oTable.fnGetData(this, properties.iIndexColumn)); |
|
50 if (iPosition < iStart) |
|
51 iStart = iPosition; |
|
52 }); |
|
53 return iStart; |
|
54 } |
|
55 |
|
56 function fnCancelSorting(oTable, tbody, properties, iLogLevel, sMessage) { |
|
57 tbody.sortable('cancel'); |
|
58 if (iLogLevel <= properties.iLogLevel) { |
|
59 if (sMessage != undefined) { |
|
60 properties.fnAlert(sMessage, ""); |
|
61 } else { |
|
62 properties.fnAlert("Row cannot be moved", ""); |
|
63 } |
|
64 } |
|
65 properties.fnEndProcessingMode(oTable); |
|
66 } |
|
67 |
|
68 function fnGetState(oTable, sSelector, id) { |
|
69 |
|
70 var tr = $("#" + id, oTable); |
|
71 var iCurrentPosition = oTable.fnGetData(tr[0], properties.iIndexColumn); |
|
72 var iNewPosition = -1; // fnGetStartPosition(sSelector); |
|
73 var sDirection; |
|
74 var trPrevious = tr.prev(sSelector); |
|
75 if (trPrevious.length > 0) { |
|
76 iNewPosition = parseInt(oTable.fnGetData(trPrevious[0], properties.iIndexColumn)); |
|
77 if (iNewPosition < iCurrentPosition) { |
|
78 iNewPosition = iNewPosition + 1; |
|
79 } |
|
80 } else { |
|
81 var trNext = tr.next(sSelector); |
|
82 if (trNext.length > 0) { |
|
83 iNewPosition = parseInt(oTable.fnGetData(trNext[0], properties.iIndexColumn)); |
|
84 if (iNewPosition > iCurrentPosition)//moved back |
|
85 iNewPosition = iNewPosition - 1; |
|
86 } |
|
87 } |
|
88 if (iNewPosition < iCurrentPosition) |
|
89 sDirection = "back"; |
|
90 else |
|
91 sDirection = "forward"; |
|
92 |
|
93 return { sDirection: sDirection, iCurrentPosition: iCurrentPosition, iNewPosition: iNewPosition }; |
|
94 |
|
95 } |
|
96 |
|
97 function fnMoveRows(oTable, sSelector, iCurrentPosition, iNewPosition, sDirection, id, sGroup) { |
|
98 var iStart = iCurrentPosition; |
|
99 var iEnd = iNewPosition; |
|
100 if (sDirection == "back") { |
|
101 iStart = iNewPosition; |
|
102 iEnd = iCurrentPosition; |
|
103 } |
|
104 |
|
105 $(oTable.fnGetNodes()).each(function () { |
|
106 if (sGroup != "" && $(this).attr("data-group") != sGroup) |
|
107 return; |
|
108 var tr = this; |
|
109 var iRowPosition = parseInt(oTable.fnGetData(tr, properties.iIndexColumn)); |
|
110 if (iStart <= iRowPosition && iRowPosition <= iEnd) { |
|
111 if (tr.id == id) { |
|
112 oTable.fnUpdate(iNewPosition, |
|
113 oTable.fnGetPosition(tr), // get row position in current model |
|
114 properties.iIndexColumn, |
|
115 false); // false = defer redraw until all row updates are done |
|
116 } else { |
|
117 if (sDirection == "back") { |
|
118 oTable.fnUpdate(iRowPosition + 1, |
|
119 oTable.fnGetPosition(tr), // get row position in current model |
|
120 properties.iIndexColumn, |
|
121 false); // false = defer redraw until all row updates are done |
|
122 } else { |
|
123 oTable.fnUpdate(iRowPosition - 1, |
|
124 oTable.fnGetPosition(tr), // get row position in current model |
|
125 properties.iIndexColumn, |
|
126 false); // false = defer redraw until all row updates are done |
|
127 } |
|
128 } |
|
129 } |
|
130 }); |
|
131 |
|
132 var oSettings = oTable.fnSettings(); |
|
133 |
|
134 //Standing Redraw Extension |
|
135 //Author: Jonathan Hoguet |
|
136 //http://datatables.net/plug-ins/api#fnStandingRedraw |
|
137 if (oSettings.oFeatures.bServerSide === false) { |
|
138 var before = oSettings._iDisplayStart; |
|
139 oSettings.oApi._fnReDraw(oSettings); |
|
140 //iDisplayStart has been reset to zero - so lets change it back |
|
141 oSettings._iDisplayStart = before; |
|
142 oSettings.oApi._fnCalculateEnd(oSettings); |
|
143 } |
|
144 //draw the 'current' page |
|
145 oSettings.oApi._fnDraw(oSettings); |
|
146 } |
|
147 |
|
148 function _fnAlert(message, type) { |
|
149 alert(message); |
|
150 } |
|
151 |
|
152 var defaults = { |
|
153 iIndexColumn: 0, |
|
154 iStartPosition: 1, |
|
155 sURL: null, |
|
156 sRequestType: "POST", |
|
157 iGroupingLevel: 0, |
|
158 fnAlert: _fnAlert, |
|
159 fnSuccess: jQuery.noop, |
|
160 iLogLevel: 1, |
|
161 sDataGroupAttribute: "data-group", |
|
162 fnStartProcessingMode: _fnStartProcessingMode, |
|
163 fnEndProcessingMode: _fnEndProcessingMode, |
|
164 fnUpdateAjaxRequest: jQuery.noop |
|
165 }; |
|
166 |
|
167 var properties = $.extend(defaults, options); |
|
168 |
|
169 var iFrom, iTo; |
|
170 |
|
171 // Return a helper with preserved width of cells (see Issue 9) |
|
172 var tableFixHelper = function (e, tr) { |
|
173 var $originals = tr.children(); |
|
174 var $helper = tr.clone(); |
|
175 $helper.children().each(function (index) { |
|
176 // Set helper cell sizes to match the original sizes |
|
177 $(this).width($originals.eq(index).width()) |
|
178 }); |
|
179 return $helper; |
|
180 }; |
|
181 |
|
182 return this.each(function () { |
|
183 |
|
184 var oTable = $(this).dataTable(); |
|
185 |
|
186 var aaSortingFixed = (oTable.fnSettings().aaSortingFixed == null ? new Array() : oTable.fnSettings().aaSortingFixed); |
|
187 aaSortingFixed.push([properties.iIndexColumn, "asc"]); |
|
188 |
|
189 oTable.fnSettings().aaSortingFixed = aaSortingFixed; |
|
190 |
|
191 |
|
192 for (var i = 0; i < oTable.fnSettings().aoColumns.length; i++) { |
|
193 oTable.fnSettings().aoColumns[i].bSortable = false; |
|
194 /*for(var j=0; j<aaSortingFixed.length; j++) |
|
195 { |
|
196 if( i == aaSortingFixed[j][0] ) |
|
197 oTable.fnSettings().aoColumns[i].bSortable = false; |
|
198 }*/ |
|
199 } |
|
200 oTable.fnDraw(); |
|
201 |
|
202 $("tbody", oTable).disableSelection().sortable({ |
|
203 cursor: "move", |
|
204 helper: tableFixHelper, |
|
205 update: function (event, ui) { |
|
206 var $dataTable = oTable; |
|
207 var tbody = $(this); |
|
208 var sSelector = "tbody tr"; |
|
209 var sGroup = ""; |
|
210 if (properties.bGroupingUsed) { |
|
211 sGroup = $(ui.item).attr(properties.sDataGroupAttribute); |
|
212 if (sGroup == null || sGroup == undefined) { |
|
213 fnCancelSorting($dataTable, tbody, properties, 3, "Grouping row cannot be moved"); |
|
214 return; |
|
215 } |
|
216 sSelector = "tbody tr[" + properties.sDataGroupAttribute + " ='" + sGroup + "']"; |
|
217 } |
|
218 |
|
219 var oState = fnGetState($dataTable, sSelector, ui.item.context.id); |
|
220 if (oState.iNewPosition == -1) { |
|
221 fnCancelSorting($dataTable, tbody, properties, 2); |
|
222 return; |
|
223 } |
|
224 |
|
225 if (properties.sURL != null) { |
|
226 properties.fnStartProcessingMode($dataTable); |
|
227 var oAjaxRequest = { |
|
228 url: properties.sURL, |
|
229 type: properties.sRequestType, |
|
230 data: { id: ui.item.context.id, |
|
231 fromPosition: oState.iCurrentPosition, |
|
232 toPosition: oState.iNewPosition, |
|
233 direction: oState.sDirection, |
|
234 group: sGroup |
|
235 }, |
|
236 success: function (data) { |
|
237 properties.fnSuccess(data); |
|
238 fnMoveRows($dataTable, sSelector, oState.iCurrentPosition, oState.iNewPosition, oState.sDirection, ui.item.context.id, sGroup); |
|
239 properties.fnEndProcessingMode($dataTable); |
|
240 }, |
|
241 error: function (jqXHR) { |
|
242 fnCancelSorting($dataTable, tbody, properties, 1, jqXHR.statusText); |
|
243 } |
|
244 }; |
|
245 properties.fnUpdateAjaxRequest(oAjaxRequest, properties, $dataTable); |
|
246 $.ajax(oAjaxRequest); |
|
247 } else { |
|
248 fnMoveRows($dataTable, sSelector, oState.iCurrentPosition, oState.iNewPosition, oState.sDirection, ui.item.context.id, sGroup); |
|
249 } |
|
250 |
|
251 } |
|
252 }); |
|
253 |
|
254 }); |
|
255 |
|
256 }; |
|
257 })(jQuery); |
|