|
1 /*! ColReorder 1.1.0 |
|
2 * ©2010-2014 SpryMedia Ltd - datatables.net/license |
|
3 */ |
|
4 |
|
5 /** |
|
6 * @summary ColReorder |
|
7 * @description Provide the ability to reorder columns in a DataTable |
|
8 * @version 1.1.0 |
|
9 * @file dataTables.colReorder.js |
|
10 * @author SpryMedia Ltd (www.sprymedia.co.uk) |
|
11 * @contact www.sprymedia.co.uk/contact |
|
12 * @copyright Copyright 2010-2014 SpryMedia Ltd. |
|
13 * |
|
14 * This source file is free software, available under the following license: |
|
15 * MIT license - http://datatables.net/license/mit |
|
16 * |
|
17 * This source file is distributed in the hope that it will be useful, but |
|
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. |
|
20 * |
|
21 * For details please refer to: http://www.datatables.net |
|
22 */ |
|
23 |
|
24 (function (window, document, undefined) { |
|
25 |
|
26 |
|
27 /** |
|
28 * Switch the key value pairing of an index array to be value key (i.e. the old value is now the |
|
29 * key). For example consider [ 2, 0, 1 ] this would be returned as [ 1, 2, 0 ]. |
|
30 * @method fnInvertKeyValues |
|
31 * @param array aIn Array to switch around |
|
32 * @returns array |
|
33 */ |
|
34 function fnInvertKeyValues(aIn) { |
|
35 var aRet = []; |
|
36 for (var i = 0, iLen = aIn.length; i < iLen; i++) { |
|
37 aRet[ aIn[i] ] = i; |
|
38 } |
|
39 return aRet; |
|
40 } |
|
41 |
|
42 |
|
43 /** |
|
44 * Modify an array by switching the position of two elements |
|
45 * @method fnArraySwitch |
|
46 * @param array aArray Array to consider, will be modified by reference (i.e. no return) |
|
47 * @param int iFrom From point |
|
48 * @param int iTo Insert point |
|
49 * @returns void |
|
50 */ |
|
51 function fnArraySwitch(aArray, iFrom, iTo) { |
|
52 var mStore = aArray.splice(iFrom, 1)[0]; |
|
53 aArray.splice(iTo, 0, mStore); |
|
54 } |
|
55 |
|
56 |
|
57 /** |
|
58 * Switch the positions of nodes in a parent node (note this is specifically designed for |
|
59 * table rows). Note this function considers all element nodes under the parent! |
|
60 * @method fnDomSwitch |
|
61 * @param string sTag Tag to consider |
|
62 * @param int iFrom Element to move |
|
63 * @param int Point to element the element to (before this point), can be null for append |
|
64 * @returns void |
|
65 */ |
|
66 function fnDomSwitch(nParent, iFrom, iTo) { |
|
67 var anTags = []; |
|
68 for (var i = 0, iLen = nParent.childNodes.length; i < iLen; i++) { |
|
69 if (nParent.childNodes[i].nodeType == 1) { |
|
70 anTags.push(nParent.childNodes[i]); |
|
71 } |
|
72 } |
|
73 var nStore = anTags[ iFrom ]; |
|
74 |
|
75 if (iTo !== null) { |
|
76 nParent.insertBefore(nStore, anTags[iTo]); |
|
77 } |
|
78 else { |
|
79 nParent.appendChild(nStore); |
|
80 } |
|
81 } |
|
82 |
|
83 |
|
84 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
85 * DataTables plug-in API functions |
|
86 * |
|
87 * This are required by ColReorder in order to perform the tasks required, and also keep this |
|
88 * code portable, to be used for other column reordering projects with DataTables, if needed. |
|
89 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
90 |
|
91 |
|
92 /** |
|
93 * Plug-in for DataTables which will reorder the internal column structure by taking the column |
|
94 * from one position (iFrom) and insert it into a given point (iTo). |
|
95 * @method $.fn.dataTableExt.oApi.fnColReorder |
|
96 * @param object oSettings DataTables settings object - automatically added by DataTables! |
|
97 * @param int iFrom Take the column to be repositioned from this point |
|
98 * @param int iTo and insert it into this point |
|
99 * @returns void |
|
100 */ |
|
101 $.fn.dataTableExt.oApi.fnColReorder = function (oSettings, iFrom, iTo) { |
|
102 var v110 = $.fn.dataTable.Api ? true : false; |
|
103 var i, iLen, j, jLen, iCols = oSettings.aoColumns.length, nTrs, oCol; |
|
104 |
|
105 /* Sanity check in the input */ |
|
106 if (iFrom == iTo) { |
|
107 /* Pointless reorder */ |
|
108 return; |
|
109 } |
|
110 |
|
111 if (iFrom < 0 || iFrom >= iCols) { |
|
112 this.oApi._fnLog(oSettings, 1, "ColReorder 'from' index is out of bounds: " + iFrom); |
|
113 return; |
|
114 } |
|
115 |
|
116 if (iTo < 0 || iTo >= iCols) { |
|
117 this.oApi._fnLog(oSettings, 1, "ColReorder 'to' index is out of bounds: " + iTo); |
|
118 return; |
|
119 } |
|
120 |
|
121 /* |
|
122 * Calculate the new column array index, so we have a mapping between the old and new |
|
123 */ |
|
124 var aiMapping = []; |
|
125 for (i = 0, iLen = iCols; i < iLen; i++) { |
|
126 aiMapping[i] = i; |
|
127 } |
|
128 fnArraySwitch(aiMapping, iFrom, iTo); |
|
129 var aiInvertMapping = fnInvertKeyValues(aiMapping); |
|
130 |
|
131 |
|
132 /* |
|
133 * Convert all internal indexing to the new column order indexes |
|
134 */ |
|
135 /* Sorting */ |
|
136 for (i = 0, iLen = oSettings.aaSorting.length; i < iLen; i++) { |
|
137 oSettings.aaSorting[i][0] = aiInvertMapping[ oSettings.aaSorting[i][0] ]; |
|
138 } |
|
139 |
|
140 /* Fixed sorting */ |
|
141 if (oSettings.aaSortingFixed !== null) { |
|
142 for (i = 0, iLen = oSettings.aaSortingFixed.length; i < iLen; i++) { |
|
143 oSettings.aaSortingFixed[i][0] = aiInvertMapping[ oSettings.aaSortingFixed[i][0] ]; |
|
144 } |
|
145 } |
|
146 |
|
147 /* Data column sorting (the column which the sort for a given column should take place on) */ |
|
148 for (i = 0, iLen = iCols; i < iLen; i++) { |
|
149 oCol = oSettings.aoColumns[i]; |
|
150 for (j = 0, jLen = oCol.aDataSort.length; j < jLen; j++) { |
|
151 oCol.aDataSort[j] = aiInvertMapping[ oCol.aDataSort[j] ]; |
|
152 } |
|
153 |
|
154 // Update the column indexes |
|
155 if (v110) { |
|
156 oCol.idx = aiInvertMapping[ oCol.idx ]; |
|
157 } |
|
158 } |
|
159 |
|
160 if (v110) { |
|
161 // Update 1.10 optimised sort class removal variable |
|
162 $.each(oSettings.aLastSort, function (i, val) { |
|
163 oSettings.aLastSort[i].src = aiInvertMapping[ val.src ]; |
|
164 }); |
|
165 } |
|
166 |
|
167 /* Update the Get and Set functions for each column */ |
|
168 for (i = 0, iLen = iCols; i < iLen; i++) { |
|
169 oCol = oSettings.aoColumns[i]; |
|
170 if (typeof oCol.mData == 'number') { |
|
171 oCol.mData = aiInvertMapping[ oCol.mData ]; |
|
172 |
|
173 // regenerate the get / set functions |
|
174 oSettings.oApi._fnColumnOptions(oSettings, i, {}); |
|
175 } |
|
176 } |
|
177 |
|
178 |
|
179 /* |
|
180 * Move the DOM elements |
|
181 */ |
|
182 if (oSettings.aoColumns[iFrom].bVisible) { |
|
183 /* Calculate the current visible index and the point to insert the node before. The insert |
|
184 * before needs to take into account that there might not be an element to insert before, |
|
185 * in which case it will be null, and an appendChild should be used |
|
186 */ |
|
187 var iVisibleIndex = this.oApi._fnColumnIndexToVisible(oSettings, iFrom); |
|
188 var iInsertBeforeIndex = null; |
|
189 |
|
190 i = iTo < iFrom ? iTo : iTo + 1; |
|
191 while (iInsertBeforeIndex === null && i < iCols) { |
|
192 iInsertBeforeIndex = this.oApi._fnColumnIndexToVisible(oSettings, i); |
|
193 i++; |
|
194 } |
|
195 |
|
196 /* Header */ |
|
197 nTrs = oSettings.nTHead.getElementsByTagName('tr'); |
|
198 for (i = 0, iLen = nTrs.length; i < iLen; i++) { |
|
199 fnDomSwitch(nTrs[i], iVisibleIndex, iInsertBeforeIndex); |
|
200 } |
|
201 |
|
202 /* Footer */ |
|
203 if (oSettings.nTFoot !== null) { |
|
204 nTrs = oSettings.nTFoot.getElementsByTagName('tr'); |
|
205 for (i = 0, iLen = nTrs.length; i < iLen; i++) { |
|
206 fnDomSwitch(nTrs[i], iVisibleIndex, iInsertBeforeIndex); |
|
207 } |
|
208 } |
|
209 |
|
210 /* Body */ |
|
211 for (i = 0, iLen = oSettings.aoData.length; i < iLen; i++) { |
|
212 if (oSettings.aoData[i].nTr !== null) { |
|
213 fnDomSwitch(oSettings.aoData[i].nTr, iVisibleIndex, iInsertBeforeIndex); |
|
214 } |
|
215 } |
|
216 } |
|
217 |
|
218 /* |
|
219 * Move the internal array elements |
|
220 */ |
|
221 /* Columns */ |
|
222 fnArraySwitch(oSettings.aoColumns, iFrom, iTo); |
|
223 |
|
224 /* Search columns */ |
|
225 fnArraySwitch(oSettings.aoPreSearchCols, iFrom, iTo); |
|
226 |
|
227 /* Array array - internal data anodes cache */ |
|
228 for (i = 0, iLen = oSettings.aoData.length; i < iLen; i++) { |
|
229 if (v110) { |
|
230 // DataTables 1.10+ |
|
231 fnArraySwitch(oSettings.aoData[i].anCells, iFrom, iTo); |
|
232 } |
|
233 else { |
|
234 // DataTables 1.9- |
|
235 if ($.isArray(oSettings.aoData[i]._aData)) { |
|
236 fnArraySwitch(oSettings.aoData[i]._aData, iFrom, iTo); |
|
237 } |
|
238 fnArraySwitch(oSettings.aoData[i]._anHidden, iFrom, iTo); |
|
239 } |
|
240 } |
|
241 |
|
242 /* Reposition the header elements in the header layout array */ |
|
243 for (i = 0, iLen = oSettings.aoHeader.length; i < iLen; i++) { |
|
244 fnArraySwitch(oSettings.aoHeader[i], iFrom, iTo); |
|
245 } |
|
246 |
|
247 if (oSettings.aoFooter !== null) { |
|
248 for (i = 0, iLen = oSettings.aoFooter.length; i < iLen; i++) { |
|
249 fnArraySwitch(oSettings.aoFooter[i], iFrom, iTo); |
|
250 } |
|
251 } |
|
252 |
|
253 // In 1.10 we need to invalidate row cached data for sorting, filtering etc |
|
254 if (v110) { |
|
255 var api = new $.fn.dataTable.Api(oSettings); |
|
256 api.rows().invalidate(); |
|
257 } |
|
258 |
|
259 /* |
|
260 * Update DataTables' event handlers |
|
261 */ |
|
262 |
|
263 /* Sort listener */ |
|
264 for (i = 0, iLen = iCols; i < iLen; i++) { |
|
265 $(oSettings.aoColumns[i].nTh).off('click.DT'); |
|
266 this.oApi._fnSortAttachListener(oSettings, oSettings.aoColumns[i].nTh, i); |
|
267 } |
|
268 |
|
269 |
|
270 /* Fire an event so other plug-ins can update */ |
|
271 $(oSettings.oInstance).trigger('column-reorder', [ oSettings, { |
|
272 "iFrom": iFrom, |
|
273 "iTo": iTo, |
|
274 "aiInvertMapping": aiInvertMapping |
|
275 } ]); |
|
276 }; |
|
277 |
|
278 |
|
279 var factory = function ($, DataTable) { |
|
280 "use strict"; |
|
281 |
|
282 /** |
|
283 * ColReorder provides column visibility control for DataTables |
|
284 * @class ColReorder |
|
285 * @constructor |
|
286 * @param {object} dt DataTables settings object |
|
287 * @param {object} opts ColReorder options |
|
288 */ |
|
289 var ColReorder = function (dt, opts) { |
|
290 var oDTSettings; |
|
291 |
|
292 if ($.fn.dataTable.Api) { |
|
293 oDTSettings = new $.fn.dataTable.Api(dt).settings()[0]; |
|
294 } |
|
295 // 1.9 compatibility |
|
296 else if (dt.fnSettings) { |
|
297 // DataTables object, convert to the settings object |
|
298 oDTSettings = dt.fnSettings(); |
|
299 } |
|
300 else if (typeof dt === 'string') { |
|
301 // jQuery selector |
|
302 if ($.fn.dataTable.fnIsDataTable($(dt)[0])) { |
|
303 oDTSettings = $(dt).eq(0).dataTable().fnSettings(); |
|
304 } |
|
305 } |
|
306 else if (dt.nodeName && dt.nodeName.toLowerCase() === 'table') { |
|
307 // Table node |
|
308 if ($.fn.dataTable.fnIsDataTable(dt.nodeName)) { |
|
309 oDTSettings = $(dt.nodeName).dataTable().fnSettings(); |
|
310 } |
|
311 } |
|
312 else if (dt instanceof jQuery) { |
|
313 // jQuery object |
|
314 if ($.fn.dataTable.fnIsDataTable(dt[0])) { |
|
315 oDTSettings = dt.eq(0).dataTable().fnSettings(); |
|
316 } |
|
317 } |
|
318 else { |
|
319 // DataTables settings object |
|
320 oDTSettings = dt; |
|
321 } |
|
322 |
|
323 // Convert from camelCase to Hungarian, just as DataTables does |
|
324 if ($.fn.dataTable.camelToHungarian) { |
|
325 $.fn.dataTable.camelToHungarian(ColReorder.defaults, opts || {}); |
|
326 } |
|
327 |
|
328 |
|
329 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
330 * Public class variables |
|
331 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
332 |
|
333 /** |
|
334 * @namespace Settings object which contains customisable information for ColReorder instance |
|
335 */ |
|
336 this.s = { |
|
337 /** |
|
338 * DataTables settings object |
|
339 * @property dt |
|
340 * @type Object |
|
341 * @default null |
|
342 */ |
|
343 "dt": null, |
|
344 |
|
345 /** |
|
346 * Initialisation object used for this instance |
|
347 * @property init |
|
348 * @type object |
|
349 * @default {} |
|
350 */ |
|
351 "init": $.extend(true, {}, ColReorder.defaults, opts), |
|
352 |
|
353 /** |
|
354 * Number of columns to fix (not allow to be reordered) |
|
355 * @property fixed |
|
356 * @type int |
|
357 * @default 0 |
|
358 */ |
|
359 "fixed": 0, |
|
360 |
|
361 /** |
|
362 * Number of columns to fix counting from right (not allow to be reordered) |
|
363 * @property fixedRight |
|
364 * @type int |
|
365 * @default 0 |
|
366 */ |
|
367 "fixedRight": 0, |
|
368 |
|
369 /** |
|
370 * Callback function for once the reorder has been done |
|
371 * @property dropcallback |
|
372 * @type function |
|
373 * @default null |
|
374 */ |
|
375 "dropCallback": null, |
|
376 |
|
377 /** |
|
378 * @namespace Information used for the mouse drag |
|
379 */ |
|
380 "mouse": { |
|
381 "startX": -1, |
|
382 "startY": -1, |
|
383 "offsetX": -1, |
|
384 "offsetY": -1, |
|
385 "target": -1, |
|
386 "targetIndex": -1, |
|
387 "fromIndex": -1 |
|
388 }, |
|
389 |
|
390 /** |
|
391 * Information which is used for positioning the insert cusor and knowing where to do the |
|
392 * insert. Array of objects with the properties: |
|
393 * x: x-axis position |
|
394 * to: insert point |
|
395 * @property aoTargets |
|
396 * @type array |
|
397 * @default [] |
|
398 */ |
|
399 "aoTargets": [] |
|
400 }; |
|
401 |
|
402 |
|
403 /** |
|
404 * @namespace Common and useful DOM elements for the class instance |
|
405 */ |
|
406 this.dom = { |
|
407 /** |
|
408 * Dragging element (the one the mouse is moving) |
|
409 * @property drag |
|
410 * @type element |
|
411 * @default null |
|
412 */ |
|
413 "drag": null, |
|
414 |
|
415 /** |
|
416 * The insert cursor |
|
417 * @property pointer |
|
418 * @type element |
|
419 * @default null |
|
420 */ |
|
421 "pointer": null |
|
422 }; |
|
423 |
|
424 |
|
425 /* Constructor logic */ |
|
426 this.s.dt = oDTSettings.oInstance.fnSettings(); |
|
427 this.s.dt._colReorder = this; |
|
428 this._fnConstruct(); |
|
429 |
|
430 /* Add destroy callback */ |
|
431 oDTSettings.oApi._fnCallbackReg(oDTSettings, 'aoDestroyCallback', $.proxy(this._fnDestroy, this), 'ColReorder'); |
|
432 |
|
433 return this; |
|
434 }; |
|
435 |
|
436 |
|
437 ColReorder.prototype = { |
|
438 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
439 * Public methods |
|
440 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
441 |
|
442 /** |
|
443 * Reset the column ordering to the original ordering that was detected on |
|
444 * start up. |
|
445 * @return {this} Returns `this` for chaining. |
|
446 * |
|
447 * @example |
|
448 * // DataTables initialisation with ColReorder |
|
449 * var table = $('#example').dataTable( { |
|
450 * "sDom": 'Rlfrtip' |
|
451 * } ); |
|
452 * |
|
453 * // Add click event to a button to reset the ordering |
|
454 * $('#resetOrdering').click( function (e) { |
|
455 * e.preventDefault(); |
|
456 * $.fn.dataTable.ColReorder( table ).fnReset(); |
|
457 * } ); |
|
458 */ |
|
459 "fnReset": function () { |
|
460 var a = []; |
|
461 for (var i = 0, iLen = this.s.dt.aoColumns.length; i < iLen; i++) { |
|
462 a.push(this.s.dt.aoColumns[i]._ColReorder_iOrigCol); |
|
463 } |
|
464 |
|
465 this._fnOrderColumns(a); |
|
466 |
|
467 return this; |
|
468 }, |
|
469 |
|
470 /** |
|
471 * `Deprecated` - Get the current order of the columns, as an array. |
|
472 * @return {array} Array of column identifiers |
|
473 * @deprecated `fnOrder` should be used in preference to this method. |
|
474 * `fnOrder` acts as a getter/setter. |
|
475 */ |
|
476 "fnGetCurrentOrder": function () { |
|
477 return this.fnOrder(); |
|
478 }, |
|
479 |
|
480 /** |
|
481 * Get the current order of the columns, as an array. Note that the values |
|
482 * given in the array are unique identifiers for each column. Currently |
|
483 * these are the original ordering of the columns that was detected on |
|
484 * start up, but this could potentially change in future. |
|
485 * @return {array} Array of column identifiers |
|
486 * |
|
487 * @example |
|
488 * // Get column ordering for the table |
|
489 * var order = $.fn.dataTable.ColReorder( dataTable ).fnOrder(); |
|
490 *//** |
|
491 * Set the order of the columns, from the positions identified in the |
|
492 * ordering array given. Note that ColReorder takes a brute force approach |
|
493 * to reordering, so it is possible multiple reordering events will occur |
|
494 * before the final order is settled upon. |
|
495 * @param {array} [set] Array of column identifiers in the new order. Note |
|
496 * that every column must be included, uniquely, in this array. |
|
497 * @return {this} Returns `this` for chaining. |
|
498 * |
|
499 * @example |
|
500 * // Swap the first and second columns |
|
501 * $.fn.dataTable.ColReorder( dataTable ).fnOrder( [1, 0, 2, 3, 4] ); |
|
502 * |
|
503 * @example |
|
504 * // Move the first column to the end for the table `#example` |
|
505 * var curr = $.fn.dataTable.ColReorder( '#example' ).fnOrder(); |
|
506 * var first = curr.shift(); |
|
507 * curr.push( first ); |
|
508 * $.fn.dataTable.ColReorder( '#example' ).fnOrder( curr ); |
|
509 * |
|
510 * @example |
|
511 * // Reverse the table's order |
|
512 * $.fn.dataTable.ColReorder( '#example' ).fnOrder( |
|
513 * $.fn.dataTable.ColReorder( '#example' ).fnOrder().reverse() |
|
514 * ); |
|
515 */ |
|
516 "fnOrder": function (set) { |
|
517 if (set === undefined) { |
|
518 var a = []; |
|
519 for (var i = 0, iLen = this.s.dt.aoColumns.length; i < iLen; i++) { |
|
520 a.push(this.s.dt.aoColumns[i]._ColReorder_iOrigCol); |
|
521 } |
|
522 return a; |
|
523 } |
|
524 |
|
525 this._fnOrderColumns(fnInvertKeyValues(set)); |
|
526 |
|
527 return this; |
|
528 }, |
|
529 |
|
530 |
|
531 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
532 * Private methods (they are of course public in JS, but recommended as private) |
|
533 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
534 |
|
535 /** |
|
536 * Constructor logic |
|
537 * @method _fnConstruct |
|
538 * @returns void |
|
539 * @private |
|
540 */ |
|
541 "_fnConstruct": function () { |
|
542 var that = this; |
|
543 var iLen = this.s.dt.aoColumns.length; |
|
544 var i; |
|
545 |
|
546 /* Columns discounted from reordering - counting left to right */ |
|
547 if (this.s.init.iFixedColumns) { |
|
548 this.s.fixed = this.s.init.iFixedColumns; |
|
549 } |
|
550 |
|
551 /* Columns discounted from reordering - counting right to left */ |
|
552 this.s.fixedRight = this.s.init.iFixedColumnsRight ? |
|
553 this.s.init.iFixedColumnsRight : |
|
554 0; |
|
555 |
|
556 /* Drop callback initialisation option */ |
|
557 if (this.s.init.fnReorderCallback) { |
|
558 this.s.dropCallback = this.s.init.fnReorderCallback; |
|
559 } |
|
560 |
|
561 /* Add event handlers for the drag and drop, and also mark the original column order */ |
|
562 for (i = 0; i < iLen; i++) { |
|
563 if (i > this.s.fixed - 1 && i < iLen - this.s.fixedRight) { |
|
564 this._fnMouseListener(i, this.s.dt.aoColumns[i].nTh); |
|
565 } |
|
566 |
|
567 /* Mark the original column order for later reference */ |
|
568 this.s.dt.aoColumns[i]._ColReorder_iOrigCol = i; |
|
569 } |
|
570 |
|
571 /* State saving */ |
|
572 this.s.dt.oApi._fnCallbackReg(this.s.dt, 'aoStateSaveParams', function (oS, oData) { |
|
573 that._fnStateSave.call(that, oData); |
|
574 }, "ColReorder_State"); |
|
575 |
|
576 /* An initial column order has been specified */ |
|
577 var aiOrder = null; |
|
578 if (this.s.init.aiOrder) { |
|
579 aiOrder = this.s.init.aiOrder.slice(); |
|
580 } |
|
581 |
|
582 /* State loading, overrides the column order given */ |
|
583 if (this.s.dt.oLoadedState && typeof this.s.dt.oLoadedState.ColReorder != 'undefined' && |
|
584 this.s.dt.oLoadedState.ColReorder.length == this.s.dt.aoColumns.length) { |
|
585 aiOrder = this.s.dt.oLoadedState.ColReorder; |
|
586 } |
|
587 |
|
588 /* If we have an order to apply - do so */ |
|
589 if (aiOrder) { |
|
590 /* We might be called during or after the DataTables initialisation. If before, then we need |
|
591 * to wait until the draw is done, if after, then do what we need to do right away |
|
592 */ |
|
593 if (!that.s.dt._bInitComplete) { |
|
594 var bDone = false; |
|
595 this.s.dt.aoDrawCallback.push({ |
|
596 "fn": function () { |
|
597 if (!that.s.dt._bInitComplete && !bDone) { |
|
598 bDone = true; |
|
599 var resort = fnInvertKeyValues(aiOrder); |
|
600 that._fnOrderColumns.call(that, resort); |
|
601 } |
|
602 }, |
|
603 "sName": "ColReorder_Pre" |
|
604 }); |
|
605 } |
|
606 else { |
|
607 var resort = fnInvertKeyValues(aiOrder); |
|
608 that._fnOrderColumns.call(that, resort); |
|
609 } |
|
610 } |
|
611 else { |
|
612 this._fnSetColumnIndexes(); |
|
613 } |
|
614 }, |
|
615 |
|
616 |
|
617 /** |
|
618 * Set the column order from an array |
|
619 * @method _fnOrderColumns |
|
620 * @param array a An array of integers which dictate the column order that should be applied |
|
621 * @returns void |
|
622 * @private |
|
623 */ |
|
624 "_fnOrderColumns": function (a) { |
|
625 if (a.length != this.s.dt.aoColumns.length) { |
|
626 this.s.dt.oInstance.oApi._fnLog(this.s.dt, 1, "ColReorder - array reorder does not " + |
|
627 "match known number of columns. Skipping."); |
|
628 return; |
|
629 } |
|
630 |
|
631 for (var i = 0, iLen = a.length; i < iLen; i++) { |
|
632 var currIndex = $.inArray(i, a); |
|
633 if (i != currIndex) { |
|
634 /* Reorder our switching array */ |
|
635 fnArraySwitch(a, currIndex, i); |
|
636 |
|
637 /* Do the column reorder in the table */ |
|
638 this.s.dt.oInstance.fnColReorder(currIndex, i); |
|
639 } |
|
640 } |
|
641 |
|
642 /* When scrolling we need to recalculate the column sizes to allow for the shift */ |
|
643 if (this.s.dt.oScroll.sX !== "" || this.s.dt.oScroll.sY !== "") { |
|
644 this.s.dt.oInstance.fnAdjustColumnSizing(); |
|
645 } |
|
646 |
|
647 /* Save the state */ |
|
648 this.s.dt.oInstance.oApi._fnSaveState(this.s.dt); |
|
649 |
|
650 this._fnSetColumnIndexes(); |
|
651 }, |
|
652 |
|
653 |
|
654 /** |
|
655 * Because we change the indexes of columns in the table, relative to their starting point |
|
656 * we need to reorder the state columns to what they are at the starting point so we can |
|
657 * then rearrange them again on state load! |
|
658 * @method _fnStateSave |
|
659 * @param object oState DataTables state |
|
660 * @returns string JSON encoded cookie string for DataTables |
|
661 * @private |
|
662 */ |
|
663 "_fnStateSave": function (oState) { |
|
664 var i, iLen, aCopy, iOrigColumn; |
|
665 var oSettings = this.s.dt; |
|
666 |
|
667 /* Sorting */ |
|
668 for (i = 0; i < oState.aaSorting.length; i++) { |
|
669 oState.aaSorting[i][0] = oSettings.aoColumns[ oState.aaSorting[i][0] ]._ColReorder_iOrigCol; |
|
670 } |
|
671 |
|
672 var aSearchCopy = $.extend(true, [], oState.aoSearchCols); |
|
673 oState.ColReorder = []; |
|
674 |
|
675 for (i = 0, iLen = oSettings.aoColumns.length; i < iLen; i++) { |
|
676 iOrigColumn = oSettings.aoColumns[i]._ColReorder_iOrigCol; |
|
677 |
|
678 /* Column filter */ |
|
679 oState.aoSearchCols[ iOrigColumn ] = aSearchCopy[i]; |
|
680 |
|
681 /* Visibility */ |
|
682 oState.abVisCols[ iOrigColumn ] = oSettings.aoColumns[i].bVisible; |
|
683 |
|
684 /* Column reordering */ |
|
685 oState.ColReorder.push(iOrigColumn); |
|
686 } |
|
687 }, |
|
688 |
|
689 |
|
690 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
691 * Mouse drop and drag |
|
692 */ |
|
693 |
|
694 /** |
|
695 * Add a mouse down listener to a particluar TH element |
|
696 * @method _fnMouseListener |
|
697 * @param int i Column index |
|
698 * @param element nTh TH element clicked on |
|
699 * @returns void |
|
700 * @private |
|
701 */ |
|
702 "_fnMouseListener": function (i, nTh) { |
|
703 var that = this; |
|
704 $(nTh).on('mousedown.ColReorder', function (e) { |
|
705 e.preventDefault(); |
|
706 that._fnMouseDown.call(that, e, nTh); |
|
707 }); |
|
708 }, |
|
709 |
|
710 |
|
711 /** |
|
712 * Mouse down on a TH element in the table header |
|
713 * @method _fnMouseDown |
|
714 * @param event e Mouse event |
|
715 * @param element nTh TH element to be dragged |
|
716 * @returns void |
|
717 * @private |
|
718 */ |
|
719 "_fnMouseDown": function (e, nTh) { |
|
720 var that = this; |
|
721 |
|
722 /* Store information about the mouse position */ |
|
723 var target = $(e.target).closest('th, td'); |
|
724 var offset = target.offset(); |
|
725 var idx = parseInt($(nTh).attr('data-column-index'), 10); |
|
726 |
|
727 if (idx === undefined) { |
|
728 return; |
|
729 } |
|
730 |
|
731 this.s.mouse.startX = e.pageX; |
|
732 this.s.mouse.startY = e.pageY; |
|
733 this.s.mouse.offsetX = e.pageX - offset.left; |
|
734 this.s.mouse.offsetY = e.pageY - offset.top; |
|
735 this.s.mouse.target = this.s.dt.aoColumns[ idx ].nTh;//target[0]; |
|
736 this.s.mouse.targetIndex = idx; |
|
737 this.s.mouse.fromIndex = idx; |
|
738 |
|
739 this._fnRegions(); |
|
740 |
|
741 /* Add event handlers to the document */ |
|
742 $(document) |
|
743 .on('mousemove.ColReorder', function (e) { |
|
744 that._fnMouseMove.call(that, e); |
|
745 }) |
|
746 .on('mouseup.ColReorder', function (e) { |
|
747 that._fnMouseUp.call(that, e); |
|
748 }); |
|
749 }, |
|
750 |
|
751 |
|
752 /** |
|
753 * Deal with a mouse move event while dragging a node |
|
754 * @method _fnMouseMove |
|
755 * @param event e Mouse event |
|
756 * @returns void |
|
757 * @private |
|
758 */ |
|
759 "_fnMouseMove": function (e) { |
|
760 var that = this; |
|
761 |
|
762 if (this.dom.drag === null) { |
|
763 /* Only create the drag element if the mouse has moved a specific distance from the start |
|
764 * point - this allows the user to make small mouse movements when sorting and not have a |
|
765 * possibly confusing drag element showing up |
|
766 */ |
|
767 if (Math.pow( |
|
768 Math.pow(e.pageX - this.s.mouse.startX, 2) + |
|
769 Math.pow(e.pageY - this.s.mouse.startY, 2), 0.5) < 5) { |
|
770 return; |
|
771 } |
|
772 this._fnCreateDragNode(); |
|
773 } |
|
774 |
|
775 /* Position the element - we respect where in the element the click occured */ |
|
776 this.dom.drag.css({ |
|
777 left: e.pageX - this.s.mouse.offsetX, |
|
778 top: e.pageY - this.s.mouse.offsetY |
|
779 }); |
|
780 |
|
781 /* Based on the current mouse position, calculate where the insert should go */ |
|
782 var bSet = false; |
|
783 var lastToIndex = this.s.mouse.toIndex; |
|
784 |
|
785 for (var i = 1, iLen = this.s.aoTargets.length; i < iLen; i++) { |
|
786 if (e.pageX < this.s.aoTargets[i - 1].x + ((this.s.aoTargets[i].x - this.s.aoTargets[i - 1].x) / 2)) { |
|
787 this.dom.pointer.css('left', this.s.aoTargets[i - 1].x); |
|
788 this.s.mouse.toIndex = this.s.aoTargets[i - 1].to; |
|
789 bSet = true; |
|
790 break; |
|
791 } |
|
792 } |
|
793 |
|
794 // The insert element wasn't positioned in the array (less than |
|
795 // operator), so we put it at the end |
|
796 if (!bSet) { |
|
797 this.dom.pointer.css('left', this.s.aoTargets[this.s.aoTargets.length - 1].x); |
|
798 this.s.mouse.toIndex = this.s.aoTargets[this.s.aoTargets.length - 1].to; |
|
799 } |
|
800 |
|
801 // Perform reordering if realtime updating is on and the column has moved |
|
802 if (this.s.init.bRealtime && lastToIndex !== this.s.mouse.toIndex) { |
|
803 this.s.dt.oInstance.fnColReorder(this.s.mouse.fromIndex, this.s.mouse.toIndex); |
|
804 this.s.mouse.fromIndex = this.s.mouse.toIndex; |
|
805 this._fnRegions(); |
|
806 } |
|
807 }, |
|
808 |
|
809 |
|
810 /** |
|
811 * Finish off the mouse drag and insert the column where needed |
|
812 * @method _fnMouseUp |
|
813 * @param event e Mouse event |
|
814 * @returns void |
|
815 * @private |
|
816 */ |
|
817 "_fnMouseUp": function (e) { |
|
818 var that = this; |
|
819 |
|
820 $(document).off('mousemove.ColReorder mouseup.ColReorder'); |
|
821 |
|
822 if (this.dom.drag !== null) { |
|
823 /* Remove the guide elements */ |
|
824 this.dom.drag.remove(); |
|
825 this.dom.pointer.remove(); |
|
826 this.dom.drag = null; |
|
827 this.dom.pointer = null; |
|
828 |
|
829 /* Actually do the reorder */ |
|
830 this.s.dt.oInstance.fnColReorder(this.s.mouse.fromIndex, this.s.mouse.toIndex); |
|
831 this._fnSetColumnIndexes(); |
|
832 |
|
833 /* When scrolling we need to recalculate the column sizes to allow for the shift */ |
|
834 if (this.s.dt.oScroll.sX !== "" || this.s.dt.oScroll.sY !== "") { |
|
835 this.s.dt.oInstance.fnAdjustColumnSizing(); |
|
836 } |
|
837 |
|
838 if (this.s.dropCallback !== null) { |
|
839 this.s.dropCallback.call(this); |
|
840 } |
|
841 |
|
842 /* Save the state */ |
|
843 this.s.dt.oInstance.oApi._fnSaveState(this.s.dt); |
|
844 } |
|
845 }, |
|
846 |
|
847 |
|
848 /** |
|
849 * Calculate a cached array with the points of the column inserts, and the |
|
850 * 'to' points |
|
851 * @method _fnRegions |
|
852 * @returns void |
|
853 * @private |
|
854 */ |
|
855 "_fnRegions": function () { |
|
856 var aoColumns = this.s.dt.aoColumns; |
|
857 |
|
858 this.s.aoTargets.splice(0, this.s.aoTargets.length); |
|
859 |
|
860 this.s.aoTargets.push({ |
|
861 "x": $(this.s.dt.nTable).offset().left, |
|
862 "to": 0 |
|
863 }); |
|
864 |
|
865 var iToPoint = 0; |
|
866 for (var i = 0, iLen = aoColumns.length; i < iLen; i++) { |
|
867 /* For the column / header in question, we want it's position to remain the same if the |
|
868 * position is just to it's immediate left or right, so we only incremement the counter for |
|
869 * other columns |
|
870 */ |
|
871 if (i != this.s.mouse.fromIndex) { |
|
872 iToPoint++; |
|
873 } |
|
874 |
|
875 if (aoColumns[i].bVisible) { |
|
876 this.s.aoTargets.push({ |
|
877 "x": $(aoColumns[i].nTh).offset().left + $(aoColumns[i].nTh).outerWidth(), |
|
878 "to": iToPoint |
|
879 }); |
|
880 } |
|
881 } |
|
882 |
|
883 /* Disallow columns for being reordered by drag and drop, counting right to left */ |
|
884 if (this.s.fixedRight !== 0) { |
|
885 this.s.aoTargets.splice(this.s.aoTargets.length - this.s.fixedRight); |
|
886 } |
|
887 |
|
888 /* Disallow columns for being reordered by drag and drop, counting left to right */ |
|
889 if (this.s.fixed !== 0) { |
|
890 this.s.aoTargets.splice(0, this.s.fixed); |
|
891 } |
|
892 }, |
|
893 |
|
894 |
|
895 /** |
|
896 * Copy the TH element that is being drags so the user has the idea that they are actually |
|
897 * moving it around the page. |
|
898 * @method _fnCreateDragNode |
|
899 * @returns void |
|
900 * @private |
|
901 */ |
|
902 "_fnCreateDragNode": function () { |
|
903 var scrolling = this.s.dt.oScroll.sX !== "" || this.s.dt.oScroll.sY !== ""; |
|
904 |
|
905 var origCell = this.s.dt.aoColumns[ this.s.mouse.targetIndex ].nTh; |
|
906 var origTr = origCell.parentNode; |
|
907 var origThead = origTr.parentNode; |
|
908 var origTable = origThead.parentNode; |
|
909 var cloneCell = $(origCell).clone(); |
|
910 |
|
911 // This is a slightly odd combination of jQuery and DOM, but it is the |
|
912 // fastest and least resource intensive way I could think of cloning |
|
913 // the table with just a single header cell in it. |
|
914 this.dom.drag = $(origTable.cloneNode(false)) |
|
915 .addClass('DTCR_clonedTable') |
|
916 .append( |
|
917 origThead.cloneNode(false).appendChild( |
|
918 origTr.cloneNode(false).appendChild( |
|
919 cloneCell[0] |
|
920 ) |
|
921 ) |
|
922 ) |
|
923 .css({ |
|
924 position: 'absolute', |
|
925 top: 0, |
|
926 left: 0, |
|
927 width: $(origCell).outerWidth(), |
|
928 height: $(origCell).outerHeight() |
|
929 }) |
|
930 .appendTo('body'); |
|
931 |
|
932 this.dom.pointer = $('<div></div>') |
|
933 .addClass('DTCR_pointer') |
|
934 .css({ |
|
935 position: 'absolute', |
|
936 top: scrolling ? |
|
937 $('div.dataTables_scroll', this.s.dt.nTableWrapper).offset().top : |
|
938 $(this.s.dt.nTable).offset().top, |
|
939 height: scrolling ? |
|
940 $('div.dataTables_scroll', this.s.dt.nTableWrapper).height() : |
|
941 $(this.s.dt.nTable).height() |
|
942 }) |
|
943 .appendTo('body'); |
|
944 }, |
|
945 |
|
946 /** |
|
947 * Clean up ColReorder memory references and event handlers |
|
948 * @method _fnDestroy |
|
949 * @returns void |
|
950 * @private |
|
951 */ |
|
952 "_fnDestroy": function () { |
|
953 var i, iLen; |
|
954 |
|
955 for (i = 0, iLen = this.s.dt.aoDrawCallback.length; i < iLen; i++) { |
|
956 if (this.s.dt.aoDrawCallback[i].sName === 'ColReorder_Pre') { |
|
957 this.s.dt.aoDrawCallback.splice(i, 1); |
|
958 break; |
|
959 } |
|
960 } |
|
961 |
|
962 $(this.s.dt.nTHead).find('*').off('.ColReorder'); |
|
963 |
|
964 $.each(this.s.dt.aoColumns, function (i, column) { |
|
965 $(column.nTh).removeAttr('data-column-index'); |
|
966 }); |
|
967 |
|
968 this.s.dt._colReorder = null; |
|
969 this.s = null; |
|
970 }, |
|
971 |
|
972 |
|
973 /** |
|
974 * Add a data attribute to the column headers, so we know the index of |
|
975 * the row to be reordered. This allows fast detection of the index, and |
|
976 * for this plug-in to work with FixedHeader which clones the nodes. |
|
977 * @private |
|
978 */ |
|
979 "_fnSetColumnIndexes": function () { |
|
980 $.each(this.s.dt.aoColumns, function (i, column) { |
|
981 $(column.nTh).attr('data-column-index', i); |
|
982 }); |
|
983 } |
|
984 }; |
|
985 |
|
986 |
|
987 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
988 * Static parameters |
|
989 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
990 |
|
991 |
|
992 /** |
|
993 * ColReorder default settings for initialisation |
|
994 * @namespace |
|
995 * @static |
|
996 */ |
|
997 ColReorder.defaults = { |
|
998 /** |
|
999 * Predefined ordering for the columns that will be applied automatically |
|
1000 * on initialisation. If not specified then the order that the columns are |
|
1001 * found to be in the HTML is the order used. |
|
1002 * @type array |
|
1003 * @default null |
|
1004 * @static |
|
1005 * @example |
|
1006 * // Using the `oColReorder` option in the DataTables options object |
|
1007 * $('#example').dataTable( { |
|
1008 * "sDom": 'Rlfrtip', |
|
1009 * "oColReorder": { |
|
1010 * "aiOrder": [ 4, 3, 2, 1, 0 ] |
|
1011 * } |
|
1012 * } ); |
|
1013 * |
|
1014 * @example |
|
1015 * // Using `new` constructor |
|
1016 * $('#example').dataTable() |
|
1017 * |
|
1018 * new $.fn.dataTable.ColReorder( '#example', { |
|
1019 * "aiOrder": [ 4, 3, 2, 1, 0 ] |
|
1020 * } ); |
|
1021 */ |
|
1022 aiOrder: null, |
|
1023 |
|
1024 /** |
|
1025 * Redraw the table's column ordering as the end user draws the column |
|
1026 * (`true`) or wait until the mouse is released (`false` - default). Note |
|
1027 * that this will perform a redraw on each reordering, which involves an |
|
1028 * Ajax request each time if you are using server-side processing in |
|
1029 * DataTables. |
|
1030 * @type boolean |
|
1031 * @default false |
|
1032 * @static |
|
1033 * @example |
|
1034 * // Using the `oColReorder` option in the DataTables options object |
|
1035 * $('#example').dataTable( { |
|
1036 * "sDom": 'Rlfrtip', |
|
1037 * "oColReorder": { |
|
1038 * "bRealtime": true |
|
1039 * } |
|
1040 * } ); |
|
1041 * |
|
1042 * @example |
|
1043 * // Using `new` constructor |
|
1044 * $('#example').dataTable() |
|
1045 * |
|
1046 * new $.fn.dataTable.ColReorder( '#example', { |
|
1047 * "bRealtime": true |
|
1048 * } ); |
|
1049 */ |
|
1050 bRealtime: false, |
|
1051 |
|
1052 /** |
|
1053 * Indicate how many columns should be fixed in position (counting from the |
|
1054 * left). This will typically be 1 if used, but can be as high as you like. |
|
1055 * @type int |
|
1056 * @default 0 |
|
1057 * @static |
|
1058 * @example |
|
1059 * // Using the `oColReorder` option in the DataTables options object |
|
1060 * $('#example').dataTable( { |
|
1061 * "sDom": 'Rlfrtip', |
|
1062 * "oColReorder": { |
|
1063 * "iFixedColumns": 1 |
|
1064 * } |
|
1065 * } ); |
|
1066 * |
|
1067 * @example |
|
1068 * // Using `new` constructor |
|
1069 * $('#example').dataTable() |
|
1070 * |
|
1071 * new $.fn.dataTable.ColReorder( '#example', { |
|
1072 * "iFixedColumns": 1 |
|
1073 * } ); |
|
1074 */ |
|
1075 iFixedColumns: 0, |
|
1076 |
|
1077 /** |
|
1078 * As `iFixedColumnsRight` but counting from the right. |
|
1079 * @type int |
|
1080 * @default 0 |
|
1081 * @static |
|
1082 * @example |
|
1083 * // Using the `oColReorder` option in the DataTables options object |
|
1084 * $('#example').dataTable( { |
|
1085 * "sDom": 'Rlfrtip', |
|
1086 * "oColReorder": { |
|
1087 * "iFixedColumnsRight": 1 |
|
1088 * } |
|
1089 * } ); |
|
1090 * |
|
1091 * @example |
|
1092 * // Using `new` constructor |
|
1093 * $('#example').dataTable() |
|
1094 * |
|
1095 * new $.fn.dataTable.ColReorder( '#example', { |
|
1096 * "iFixedColumnsRight": 1 |
|
1097 * } ); |
|
1098 */ |
|
1099 iFixedColumnsRight: 0, |
|
1100 |
|
1101 /** |
|
1102 * Callback function that is fired when columns are reordered |
|
1103 * @type function():void |
|
1104 * @default null |
|
1105 * @static |
|
1106 * @example |
|
1107 * // Using the `oColReorder` option in the DataTables options object |
|
1108 * $('#example').dataTable( { |
|
1109 * "sDom": 'Rlfrtip', |
|
1110 * "oColReorder": { |
|
1111 * "fnReorderCallback": function () { |
|
1112 * alert( 'Columns reordered' ); |
|
1113 * } |
|
1114 * } |
|
1115 * } ); |
|
1116 * |
|
1117 * @example |
|
1118 * // Using `new` constructor |
|
1119 * $('#example').dataTable() |
|
1120 * |
|
1121 * new $.fn.dataTable.ColReorder( '#example', { |
|
1122 * "fnReorderCallback": function () { |
|
1123 * alert( 'Columns reordered' ); |
|
1124 * } |
|
1125 * } ); |
|
1126 */ |
|
1127 fnReorderCallback: null |
|
1128 }; |
|
1129 |
|
1130 |
|
1131 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
1132 * Constants |
|
1133 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
1134 |
|
1135 /** |
|
1136 * ColReorder version |
|
1137 * @constant version |
|
1138 * @type String |
|
1139 * @default As code |
|
1140 */ |
|
1141 ColReorder.version = "1.1.0"; |
|
1142 |
|
1143 |
|
1144 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
1145 * DataTables interfaces |
|
1146 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
1147 |
|
1148 // Expose |
|
1149 $.fn.dataTable.ColReorder = ColReorder; |
|
1150 $.fn.DataTable.ColReorder = ColReorder; |
|
1151 |
|
1152 |
|
1153 // Register a new feature with DataTables |
|
1154 if (typeof $.fn.dataTable == "function" && |
|
1155 typeof $.fn.dataTableExt.fnVersionCheck == "function" && |
|
1156 $.fn.dataTableExt.fnVersionCheck('1.9.3')) { |
|
1157 $.fn.dataTableExt.aoFeatures.push({ |
|
1158 "fnInit": function (settings) { |
|
1159 var table = settings.oInstance; |
|
1160 |
|
1161 if (!settings._colReorder) { |
|
1162 var dtInit = settings.oInit; |
|
1163 var opts = dtInit.colReorder || dtInit.oColReorder || {}; |
|
1164 |
|
1165 new ColReorder(settings, opts); |
|
1166 } |
|
1167 else { |
|
1168 table.oApi._fnLog(settings, 1, "ColReorder attempted to initialise twice. Ignoring second"); |
|
1169 } |
|
1170 |
|
1171 return null; |
|
1172 /* No node for DataTables to insert */ |
|
1173 }, |
|
1174 "cFeature": "R", |
|
1175 "sFeature": "ColReorder" |
|
1176 }); |
|
1177 } |
|
1178 else { |
|
1179 alert("Warning: ColReorder requires DataTables 1.9.3 or greater - www.datatables.net/download"); |
|
1180 } |
|
1181 |
|
1182 |
|
1183 // API augmentation |
|
1184 if ($.fn.dataTable.Api) { |
|
1185 $.fn.dataTable.Api.register('colReorder.reset()', function () { |
|
1186 return this.iterator('table', function (ctx) { |
|
1187 ctx._colReorder.fnReset(); |
|
1188 }); |
|
1189 }); |
|
1190 |
|
1191 $.fn.dataTable.Api.register('colReorder.order()', function (set) { |
|
1192 if (set) { |
|
1193 return this.iterator('table', function (ctx) { |
|
1194 ctx._colReorder.fnOrder(set); |
|
1195 }); |
|
1196 } |
|
1197 |
|
1198 return this.context.length ? |
|
1199 this.context[0]._colReorder.fnOrder() : |
|
1200 null; |
|
1201 }); |
|
1202 } |
|
1203 |
|
1204 return ColReorder; |
|
1205 }; // /factory |
|
1206 |
|
1207 |
|
1208 // Otherwise simply initialise as normal, stopping multiple evaluation |
|
1209 factory(jQuery, jQuery.fn.dataTable); |
|
1210 |
|
1211 |
|
1212 })(window, document); |