effective_datatables 4.17.3 → 4.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/dataTables/UPGRADE.md +17 -0
- data/app/assets/javascripts/dataTables/buttons/buttons.bootstrap4.js +73 -19
- data/app/assets/javascripts/dataTables/buttons/buttons.colVis.js +166 -120
- data/app/assets/javascripts/dataTables/buttons/buttons.html5.js +749 -667
- data/app/assets/javascripts/dataTables/buttons/buttons.print.js +96 -64
- data/app/assets/javascripts/dataTables/buttons/dataTables.buttons.js +1568 -909
- data/app/assets/javascripts/dataTables/dataTables.bootstrap4.js +172 -154
- data/app/assets/javascripts/dataTables/jquery.dataTables.js +3119 -2704
- data/app/assets/javascripts/dataTables/responsive/dataTables.responsive.js +707 -531
- data/app/assets/javascripts/dataTables/responsive/responsive.bootstrap4.js +61 -33
- data/app/assets/javascripts/dataTables/rowReorder/dataTables.rowReorder.js +961 -740
- data/app/assets/javascripts/dataTables/rowReorder/rowReorder.bootstrap4.js +50 -30
- data/app/assets/stylesheets/dataTables/buttons/buttons.bootstrap4.scss +178 -151
- data/app/assets/stylesheets/dataTables/dataTables.bootstrap4.scss +300 -81
- data/app/assets/stylesheets/dataTables/responsive/responsive.bootstrap4.scss +54 -71
- data/app/assets/stylesheets/dataTables/rowReorder/rowReorder.bootstrap4.scss +23 -4
- data/app/assets/stylesheets/effective_datatables/_overrides.bootstrap4.scss +81 -39
- data/app/models/effective/datatable.rb +8 -2
- data/lib/effective_datatables/version.rb +1 -1
- metadata +3 -2
@@ -1,15 +1,62 @@
|
|
1
|
-
/*! RowReorder 1.
|
2
|
-
*
|
1
|
+
/*! RowReorder 1.4.1
|
2
|
+
* © SpryMedia Ltd - datatables.net/license
|
3
3
|
*/
|
4
4
|
|
5
|
+
(function( factory ){
|
6
|
+
if ( typeof define === 'function' && define.amd ) {
|
7
|
+
// AMD
|
8
|
+
define( ['jquery', 'datatables.net'], function ( $ ) {
|
9
|
+
return factory( $, window, document );
|
10
|
+
} );
|
11
|
+
}
|
12
|
+
else if ( typeof exports === 'object' ) {
|
13
|
+
// CommonJS
|
14
|
+
var jq = require('jquery');
|
15
|
+
var cjsRequires = function (root, $) {
|
16
|
+
if ( ! $.fn.dataTable ) {
|
17
|
+
require('datatables.net')(root, $);
|
18
|
+
}
|
19
|
+
};
|
20
|
+
|
21
|
+
if (typeof window === 'undefined') {
|
22
|
+
module.exports = function (root, $) {
|
23
|
+
if ( ! root ) {
|
24
|
+
// CommonJS environments without a window global must pass a
|
25
|
+
// root. This will give an error otherwise
|
26
|
+
root = window;
|
27
|
+
}
|
28
|
+
|
29
|
+
if ( ! $ ) {
|
30
|
+
$ = jq( root );
|
31
|
+
}
|
32
|
+
|
33
|
+
cjsRequires( root, $ );
|
34
|
+
return factory( $, root, root.document );
|
35
|
+
};
|
36
|
+
}
|
37
|
+
else {
|
38
|
+
cjsRequires( window, jq );
|
39
|
+
module.exports = factory( jq, window, window.document );
|
40
|
+
}
|
41
|
+
}
|
42
|
+
else {
|
43
|
+
// Browser
|
44
|
+
factory( jQuery, window, document );
|
45
|
+
}
|
46
|
+
}(function( $, window, document, undefined ) {
|
47
|
+
'use strict';
|
48
|
+
var DataTable = $.fn.dataTable;
|
49
|
+
|
50
|
+
|
51
|
+
|
5
52
|
/**
|
6
53
|
* @summary RowReorder
|
7
54
|
* @description Row reordering extension for DataTables
|
8
|
-
* @version 1.
|
55
|
+
* @version 1.4.1
|
9
56
|
* @file dataTables.rowReorder.js
|
10
|
-
* @author SpryMedia Ltd
|
11
|
-
* @contact
|
12
|
-
* @copyright Copyright 2015-
|
57
|
+
* @author SpryMedia Ltd
|
58
|
+
* @contact datatables.net
|
59
|
+
* @copyright Copyright 2015-2023 SpryMedia Ltd.
|
13
60
|
*
|
14
61
|
* This source file is free software, available under the following license:
|
15
62
|
* MIT license - http://datatables.net/license/mit
|
@@ -21,36 +68,6 @@
|
|
21
68
|
* For details please refer to: http://www.datatables.net
|
22
69
|
*/
|
23
70
|
|
24
|
-
(function( factory ){
|
25
|
-
if ( typeof define === 'function' && define.amd ) {
|
26
|
-
// AMD
|
27
|
-
define( ['jquery', 'datatables.net'], function ( $ ) {
|
28
|
-
return factory( $, window, document );
|
29
|
-
} );
|
30
|
-
}
|
31
|
-
else if ( typeof exports === 'object' ) {
|
32
|
-
// CommonJS
|
33
|
-
module.exports = function (root, $) {
|
34
|
-
if ( ! root ) {
|
35
|
-
root = window;
|
36
|
-
}
|
37
|
-
|
38
|
-
if ( ! $ || ! $.fn.dataTable ) {
|
39
|
-
$ = require('datatables.net')(root, $).$;
|
40
|
-
}
|
41
|
-
|
42
|
-
return factory( $, root, root.document );
|
43
|
-
};
|
44
|
-
}
|
45
|
-
else {
|
46
|
-
// Browser
|
47
|
-
factory( jQuery, window, document );
|
48
|
-
}
|
49
|
-
}(function( $, window, document, undefined ) {
|
50
|
-
'use strict';
|
51
|
-
var DataTable = $.fn.dataTable;
|
52
|
-
|
53
|
-
|
54
71
|
/**
|
55
72
|
* RowReorder provides the ability in DataTables to click and drag rows to
|
56
73
|
* reorder them. When a row is dropped the data for the rows effected will be
|
@@ -72,613 +89,813 @@ var DataTable = $.fn.dataTable;
|
|
72
89
|
* @requires jQuery 1.7+
|
73
90
|
* @requires DataTables 1.10.7+
|
74
91
|
*/
|
75
|
-
var RowReorder = function (
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
bodyTop: null,
|
92
|
-
|
93
|
-
/** @type {DataTable.Api} DataTables' API instance */
|
94
|
-
dt: new DataTable.Api( dt ),
|
95
|
-
|
96
|
-
/** @type {function} Data fetch function */
|
97
|
-
getDataFn: DataTable.ext.oApi._fnGetObjectDataFn( this.c.dataSrc ),
|
98
|
-
|
99
|
-
/** @type {array} Pixel positions for row insertion calculation */
|
100
|
-
middles: null,
|
101
|
-
|
102
|
-
/** @type {Object} Cached dimension information for use in the mouse move event handler */
|
103
|
-
scroll: {},
|
104
|
-
|
105
|
-
/** @type {integer} Interval object used for smooth scrolling */
|
106
|
-
scrollInterval: null,
|
107
|
-
|
108
|
-
/** @type {function} Data set function */
|
109
|
-
setDataFn: DataTable.ext.oApi._fnSetObjectDataFn( this.c.dataSrc ),
|
110
|
-
|
111
|
-
/** @type {Object} Mouse down information */
|
112
|
-
start: {
|
113
|
-
top: 0,
|
114
|
-
left: 0,
|
115
|
-
offsetTop: 0,
|
116
|
-
offsetLeft: 0,
|
117
|
-
nodes: []
|
118
|
-
},
|
119
|
-
|
120
|
-
/** @type {integer} Window height cached value */
|
121
|
-
windowHeight: 0,
|
122
|
-
|
123
|
-
/** @type {integer} Document outer height cached value */
|
124
|
-
documentOuterHeight: 0,
|
125
|
-
|
126
|
-
/** @type {integer} DOM clone outer height cached value */
|
127
|
-
domCloneOuterHeight: 0
|
128
|
-
};
|
129
|
-
|
130
|
-
// DOM items
|
131
|
-
this.dom = {
|
132
|
-
/** @type {jQuery} Cloned row being moved around */
|
133
|
-
clone: null,
|
134
|
-
|
135
|
-
/** @type {jQuery} DataTables scrolling container */
|
136
|
-
dtScroll: $('div.dataTables_scrollBody', this.s.dt.table().container())
|
137
|
-
};
|
138
|
-
|
139
|
-
// Check if row reorder has already been initialised on this table
|
140
|
-
var settings = this.s.dt.settings()[0];
|
141
|
-
var exisiting = settings.rowreorder;
|
142
|
-
if ( exisiting ) {
|
143
|
-
return exisiting;
|
144
|
-
}
|
145
|
-
|
146
|
-
settings.rowreorder = this;
|
147
|
-
this._constructor();
|
148
|
-
};
|
92
|
+
var RowReorder = function (dt, opts) {
|
93
|
+
// Sanity check that we are using DataTables 1.10 or newer
|
94
|
+
if (!DataTable.versionCheck || !DataTable.versionCheck('1.10.8')) {
|
95
|
+
throw 'DataTables RowReorder requires DataTables 1.10.8 or newer';
|
96
|
+
}
|
97
|
+
|
98
|
+
// User and defaults configuration object
|
99
|
+
this.c = $.extend(true, {}, DataTable.defaults.rowReorder, RowReorder.defaults, opts);
|
100
|
+
|
101
|
+
// Internal settings
|
102
|
+
this.s = {
|
103
|
+
/** @type {integer} Scroll body top cache */
|
104
|
+
bodyTop: null,
|
105
|
+
|
106
|
+
/** @type {DataTable.Api} DataTables' API instance */
|
107
|
+
dt: new DataTable.Api(dt),
|
149
108
|
|
109
|
+
/** @type {function} Data fetch function */
|
110
|
+
getDataFn: DataTable.ext.oApi._fnGetObjectDataFn(this.c.dataSrc),
|
150
111
|
|
151
|
-
|
152
|
-
|
153
|
-
* Constructor
|
154
|
-
*/
|
155
|
-
|
156
|
-
/**
|
157
|
-
* Initialise the RowReorder instance
|
158
|
-
*
|
159
|
-
* @private
|
160
|
-
*/
|
161
|
-
_constructor: function ()
|
162
|
-
{
|
163
|
-
var that = this;
|
164
|
-
var dt = this.s.dt;
|
165
|
-
var table = $( dt.table().node() );
|
166
|
-
|
167
|
-
// Need to be able to calculate the row positions relative to the table
|
168
|
-
if ( table.css('position') === 'static' ) {
|
169
|
-
table.css( 'position', 'relative' );
|
170
|
-
}
|
171
|
-
|
172
|
-
// listen for mouse down on the target column - we have to implement
|
173
|
-
// this rather than using HTML5 drag and drop as drag and drop doesn't
|
174
|
-
// appear to work on table rows at this time. Also mobile browsers are
|
175
|
-
// not supported.
|
176
|
-
// Use `table().container()` rather than just the table node for IE8 -
|
177
|
-
// otherwise it only works once...
|
178
|
-
$(dt.table().container()).on( 'mousedown.rowReorder touchstart.rowReorder', this.c.selector, function (e) {
|
179
|
-
if ( ! that.c.enable ) {
|
180
|
-
return;
|
181
|
-
}
|
182
|
-
|
183
|
-
// Ignore excluded children of the selector
|
184
|
-
if ( $(e.target).is(that.c.excludedChildren) ) {
|
185
|
-
return true;
|
186
|
-
}
|
187
|
-
|
188
|
-
var tr = $(this).closest('tr');
|
189
|
-
var row = dt.row( tr );
|
190
|
-
|
191
|
-
// Double check that it is a DataTable row
|
192
|
-
if ( row.any() ) {
|
193
|
-
that._emitEvent( 'pre-row-reorder', {
|
194
|
-
node: row.node(),
|
195
|
-
index: row.index()
|
196
|
-
} );
|
197
|
-
|
198
|
-
that._mouseDown( e, tr );
|
199
|
-
return false;
|
200
|
-
}
|
201
|
-
} );
|
202
|
-
|
203
|
-
dt.on( 'destroy.rowReorder', function () {
|
204
|
-
$(dt.table().container()).off( '.rowReorder' );
|
205
|
-
dt.off( '.rowReorder' );
|
206
|
-
} );
|
207
|
-
},
|
208
|
-
|
209
|
-
|
210
|
-
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
211
|
-
* Private methods
|
212
|
-
*/
|
213
|
-
|
214
|
-
/**
|
215
|
-
* Cache the measurements that RowReorder needs in the mouse move handler
|
216
|
-
* to attempt to speed things up, rather than reading from the DOM.
|
217
|
-
*
|
218
|
-
* @private
|
219
|
-
*/
|
220
|
-
_cachePositions: function ()
|
221
|
-
{
|
222
|
-
var dt = this.s.dt;
|
223
|
-
|
224
|
-
// Frustratingly, if we add `position:relative` to the tbody, the
|
225
|
-
// position is still relatively to the parent. So we need to adjust
|
226
|
-
// for that
|
227
|
-
var headerHeight = $( dt.table().node() ).find('thead').outerHeight();
|
228
|
-
|
229
|
-
// Need to pass the nodes through jQuery to get them in document order,
|
230
|
-
// not what DataTables thinks it is, since we have been altering the
|
231
|
-
// order
|
232
|
-
var nodes = $.unique( dt.rows( { page: 'current' } ).nodes().toArray() );
|
233
|
-
var tops = $.map( nodes, function ( node, i ) {
|
234
|
-
return $(node).position().top - headerHeight;
|
235
|
-
} );
|
236
|
-
|
237
|
-
var middles = $.map( tops, function ( top, i ) {
|
238
|
-
return tops.length < i-1 ?
|
239
|
-
(top + tops[i+1]) / 2 :
|
240
|
-
(top + top + $( dt.row( ':last-child' ).node() ).outerHeight() ) / 2;
|
241
|
-
} );
|
242
|
-
|
243
|
-
this.s.middles = middles;
|
244
|
-
this.s.bodyTop = $( dt.table().body() ).offset().top;
|
245
|
-
this.s.windowHeight = $(window).height();
|
246
|
-
this.s.documentOuterHeight = $(document).outerHeight();
|
247
|
-
},
|
248
|
-
|
249
|
-
|
250
|
-
/**
|
251
|
-
* Clone a row so it can be floated around the screen
|
252
|
-
*
|
253
|
-
* @param {jQuery} target Node to be cloned
|
254
|
-
* @private
|
255
|
-
*/
|
256
|
-
_clone: function ( target )
|
257
|
-
{
|
258
|
-
var dt = this.s.dt;
|
259
|
-
var clone = $( dt.table().node().cloneNode(false) )
|
260
|
-
.addClass( 'dt-rowReorder-float' )
|
261
|
-
.append('<tbody/>')
|
262
|
-
.append( target.clone( false ) );
|
263
|
-
|
264
|
-
// Match the table and column widths - read all sizes before setting
|
265
|
-
// to reduce reflows
|
266
|
-
var tableWidth = target.outerWidth();
|
267
|
-
var tableHeight = target.outerHeight();
|
268
|
-
var sizes = target.children().map( function () {
|
269
|
-
return $(this).width();
|
270
|
-
} );
|
271
|
-
|
272
|
-
clone
|
273
|
-
.width( tableWidth )
|
274
|
-
.height( tableHeight )
|
275
|
-
.find('tr').children().each( function (i) {
|
276
|
-
this.style.width = sizes[i]+'px';
|
277
|
-
} );
|
278
|
-
|
279
|
-
// Insert into the document to have it floating around
|
280
|
-
clone.appendTo( 'body' );
|
281
|
-
|
282
|
-
this.dom.clone = clone;
|
283
|
-
this.s.domCloneOuterHeight = clone.outerHeight();
|
284
|
-
},
|
285
|
-
|
286
|
-
|
287
|
-
/**
|
288
|
-
* Update the cloned item's position in the document
|
289
|
-
*
|
290
|
-
* @param {object} e Event giving the mouse's position
|
291
|
-
* @private
|
292
|
-
*/
|
293
|
-
_clonePosition: function ( e )
|
294
|
-
{
|
295
|
-
var start = this.s.start;
|
296
|
-
var topDiff = this._eventToPage( e, 'Y' ) - start.top;
|
297
|
-
var leftDiff = this._eventToPage( e, 'X' ) - start.left;
|
298
|
-
var snap = this.c.snapX;
|
299
|
-
var left;
|
300
|
-
var top = topDiff + start.offsetTop;
|
301
|
-
|
302
|
-
if ( snap === true ) {
|
303
|
-
left = start.offsetLeft;
|
304
|
-
}
|
305
|
-
else if ( typeof snap === 'number' ) {
|
306
|
-
left = start.offsetLeft + snap;
|
307
|
-
}
|
308
|
-
else {
|
309
|
-
left = leftDiff + start.offsetLeft;
|
310
|
-
}
|
311
|
-
|
312
|
-
if(top < 0) {
|
313
|
-
top = 0
|
314
|
-
}
|
315
|
-
else if(top + this.s.domCloneOuterHeight > this.s.documentOuterHeight) {
|
316
|
-
top = this.s.documentOuterHeight - this.s.domCloneOuterHeight;
|
317
|
-
}
|
318
|
-
|
319
|
-
this.dom.clone.css( {
|
320
|
-
top: top,
|
321
|
-
left: left
|
322
|
-
} );
|
323
|
-
},
|
324
|
-
|
325
|
-
|
326
|
-
/**
|
327
|
-
* Emit an event on the DataTable for listeners
|
328
|
-
*
|
329
|
-
* @param {string} name Event name
|
330
|
-
* @param {array} args Event arguments
|
331
|
-
* @private
|
332
|
-
*/
|
333
|
-
_emitEvent: function ( name, args )
|
334
|
-
{
|
335
|
-
this.s.dt.iterator( 'table', function ( ctx, i ) {
|
336
|
-
$(ctx.nTable).triggerHandler( name+'.dt', args );
|
337
|
-
} );
|
338
|
-
},
|
339
|
-
|
340
|
-
|
341
|
-
/**
|
342
|
-
* Get pageX/Y position from an event, regardless of if it is a mouse or
|
343
|
-
* touch event.
|
344
|
-
*
|
345
|
-
* @param {object} e Event
|
346
|
-
* @param {string} pos X or Y (must be a capital)
|
347
|
-
* @private
|
348
|
-
*/
|
349
|
-
_eventToPage: function ( e, pos )
|
350
|
-
{
|
351
|
-
if ( e.type.indexOf( 'touch' ) !== -1 ) {
|
352
|
-
return e.originalEvent.touches[0][ 'page'+pos ];
|
353
|
-
}
|
354
|
-
|
355
|
-
return e[ 'page'+pos ];
|
356
|
-
},
|
357
|
-
|
358
|
-
|
359
|
-
/**
|
360
|
-
* Mouse down event handler. Read initial positions and add event handlers
|
361
|
-
* for the move.
|
362
|
-
*
|
363
|
-
* @param {object} e Mouse event
|
364
|
-
* @param {jQuery} target TR element that is to be moved
|
365
|
-
* @private
|
366
|
-
*/
|
367
|
-
_mouseDown: function ( e, target )
|
368
|
-
{
|
369
|
-
var that = this;
|
370
|
-
var dt = this.s.dt;
|
371
|
-
var start = this.s.start;
|
372
|
-
|
373
|
-
var offset = target.offset();
|
374
|
-
start.top = this._eventToPage( e, 'Y' );
|
375
|
-
start.left = this._eventToPage( e, 'X' );
|
376
|
-
start.offsetTop = offset.top;
|
377
|
-
start.offsetLeft = offset.left;
|
378
|
-
start.nodes = $.unique( dt.rows( { page: 'current' } ).nodes().toArray() );
|
379
|
-
|
380
|
-
this._cachePositions();
|
381
|
-
this._clone( target );
|
382
|
-
this._clonePosition( e );
|
383
|
-
|
384
|
-
this.dom.target = target;
|
385
|
-
target.addClass( 'dt-rowReorder-moving' );
|
386
|
-
|
387
|
-
$( document )
|
388
|
-
.on( 'mouseup.rowReorder touchend.rowReorder', function (e) {
|
389
|
-
that._mouseUp(e);
|
390
|
-
} )
|
391
|
-
.on( 'mousemove.rowReorder touchmove.rowReorder', function (e) {
|
392
|
-
that._mouseMove(e);
|
393
|
-
} );
|
394
|
-
|
395
|
-
// Check if window is x-scrolling - if not, disable it for the duration
|
396
|
-
// of the drag
|
397
|
-
if ( $(window).width() === $(document).width() ) {
|
398
|
-
$(document.body).addClass( 'dt-rowReorder-noOverflow' );
|
399
|
-
}
|
400
|
-
|
401
|
-
// Cache scrolling information so mouse move doesn't need to read.
|
402
|
-
// This assumes that the window and DT scroller will not change size
|
403
|
-
// during an row drag, which I think is a fair assumption
|
404
|
-
var scrollWrapper = this.dom.dtScroll;
|
405
|
-
this.s.scroll = {
|
406
|
-
windowHeight: $(window).height(),
|
407
|
-
windowWidth: $(window).width(),
|
408
|
-
dtTop: scrollWrapper.length ? scrollWrapper.offset().top : null,
|
409
|
-
dtLeft: scrollWrapper.length ? scrollWrapper.offset().left : null,
|
410
|
-
dtHeight: scrollWrapper.length ? scrollWrapper.outerHeight() : null,
|
411
|
-
dtWidth: scrollWrapper.length ? scrollWrapper.outerWidth() : null
|
412
|
-
};
|
413
|
-
},
|
414
|
-
|
415
|
-
|
416
|
-
/**
|
417
|
-
* Mouse move event handler - move the cloned row and shuffle the table's
|
418
|
-
* rows if required.
|
419
|
-
*
|
420
|
-
* @param {object} e Mouse event
|
421
|
-
* @private
|
422
|
-
*/
|
423
|
-
_mouseMove: function ( e )
|
424
|
-
{
|
425
|
-
this._clonePosition( e );
|
426
|
-
|
427
|
-
// Transform the mouse position into a position in the table's body
|
428
|
-
var bodyY = this._eventToPage( e, 'Y' ) - this.s.bodyTop;
|
429
|
-
var middles = this.s.middles;
|
430
|
-
var insertPoint = null;
|
431
|
-
var dt = this.s.dt;
|
432
|
-
var body = dt.table().body();
|
433
|
-
|
434
|
-
// Determine where the row should be inserted based on the mouse
|
435
|
-
// position
|
436
|
-
for ( var i=0, ien=middles.length ; i<ien ; i++ ) {
|
437
|
-
if ( bodyY < middles[i] ) {
|
438
|
-
insertPoint = i;
|
439
|
-
break;
|
440
|
-
}
|
441
|
-
}
|
442
|
-
|
443
|
-
if ( insertPoint === null ) {
|
444
|
-
insertPoint = middles.length;
|
445
|
-
}
|
446
|
-
|
447
|
-
// Perform the DOM shuffle if it has changed from last time
|
448
|
-
if ( this.s.lastInsert === null || this.s.lastInsert !== insertPoint ) {
|
449
|
-
if ( insertPoint === 0 ) {
|
450
|
-
this.dom.target.prependTo( body );
|
451
|
-
}
|
452
|
-
else {
|
453
|
-
var nodes = $.unique( dt.rows( { page: 'current' } ).nodes().toArray() );
|
454
|
-
|
455
|
-
if ( insertPoint > this.s.lastInsert ) {
|
456
|
-
this.dom.target.insertAfter( nodes[ insertPoint-1 ] );
|
457
|
-
}
|
458
|
-
else {
|
459
|
-
this.dom.target.insertBefore( nodes[ insertPoint ] );
|
460
|
-
}
|
461
|
-
}
|
462
|
-
|
463
|
-
this._cachePositions();
|
464
|
-
|
465
|
-
this.s.lastInsert = insertPoint;
|
466
|
-
}
|
467
|
-
|
468
|
-
this._shiftScroll( e );
|
469
|
-
},
|
470
|
-
|
471
|
-
|
472
|
-
/**
|
473
|
-
* Mouse up event handler - release the event handlers and perform the
|
474
|
-
* table updates
|
475
|
-
*
|
476
|
-
* @param {object} e Mouse event
|
477
|
-
* @private
|
478
|
-
*/
|
479
|
-
_mouseUp: function ( e )
|
480
|
-
{
|
481
|
-
var that = this;
|
482
|
-
var dt = this.s.dt;
|
483
|
-
var i, ien;
|
484
|
-
var dataSrc = this.c.dataSrc;
|
485
|
-
|
486
|
-
this.dom.clone.remove();
|
487
|
-
this.dom.clone = null;
|
488
|
-
|
489
|
-
this.dom.target.removeClass( 'dt-rowReorder-moving' );
|
490
|
-
//this.dom.target = null;
|
491
|
-
|
492
|
-
$(document).off( '.rowReorder' );
|
493
|
-
$(document.body).removeClass( 'dt-rowReorder-noOverflow' );
|
494
|
-
|
495
|
-
clearInterval( this.s.scrollInterval );
|
496
|
-
this.s.scrollInterval = null;
|
497
|
-
|
498
|
-
// Calculate the difference
|
499
|
-
var startNodes = this.s.start.nodes;
|
500
|
-
var endNodes = $.unique( dt.rows( { page: 'current' } ).nodes().toArray() );
|
501
|
-
var idDiff = {};
|
502
|
-
var fullDiff = [];
|
503
|
-
var diffNodes = [];
|
504
|
-
var getDataFn = this.s.getDataFn;
|
505
|
-
var setDataFn = this.s.setDataFn;
|
506
|
-
|
507
|
-
for ( i=0, ien=startNodes.length ; i<ien ; i++ ) {
|
508
|
-
if ( startNodes[i] !== endNodes[i] ) {
|
509
|
-
var id = dt.row( endNodes[i] ).id();
|
510
|
-
var endRowData = dt.row( endNodes[i] ).data();
|
511
|
-
var startRowData = dt.row( startNodes[i] ).data();
|
512
|
-
|
513
|
-
if ( id ) {
|
514
|
-
idDiff[ id ] = getDataFn( startRowData );
|
515
|
-
}
|
516
|
-
|
517
|
-
fullDiff.push( {
|
518
|
-
node: endNodes[i],
|
519
|
-
oldData: getDataFn( endRowData ),
|
520
|
-
newData: getDataFn( startRowData ),
|
521
|
-
newPosition: i,
|
522
|
-
oldPosition: $.inArray( endNodes[i], startNodes )
|
523
|
-
} );
|
524
|
-
|
525
|
-
diffNodes.push( endNodes[i] );
|
526
|
-
}
|
527
|
-
}
|
528
|
-
|
529
|
-
// Create event args
|
530
|
-
var eventArgs = [ fullDiff, {
|
531
|
-
dataSrc: dataSrc,
|
532
|
-
nodes: diffNodes,
|
533
|
-
values: idDiff,
|
534
|
-
triggerRow: dt.row( this.dom.target )
|
535
|
-
} ];
|
536
|
-
|
537
|
-
// Emit event
|
538
|
-
this._emitEvent( 'row-reorder', eventArgs );
|
539
|
-
|
540
|
-
var update = function () {
|
541
|
-
if ( that.c.update ) {
|
542
|
-
for ( i=0, ien=fullDiff.length ; i<ien ; i++ ) {
|
543
|
-
var row = dt.row( fullDiff[i].node );
|
544
|
-
var rowData = row.data();
|
545
|
-
|
546
|
-
setDataFn( rowData, fullDiff[i].newData );
|
547
|
-
|
548
|
-
// Invalidate the cell that has the same data source as the dataSrc
|
549
|
-
dt.columns().every( function () {
|
550
|
-
if ( this.dataSrc() === dataSrc ) {
|
551
|
-
dt.cell( fullDiff[i].node, this.index() ).invalidate( 'data' );
|
552
|
-
}
|
553
|
-
} );
|
554
|
-
}
|
555
|
-
|
556
|
-
// Trigger row reordered event
|
557
|
-
that._emitEvent( 'row-reordered', eventArgs );
|
558
|
-
|
559
|
-
dt.draw( false );
|
560
|
-
}
|
561
|
-
};
|
562
|
-
|
563
|
-
// Editor interface
|
564
|
-
if ( this.c.editor ) {
|
565
|
-
// Disable user interaction while Editor is submitting
|
566
|
-
this.c.enable = false;
|
567
|
-
|
568
|
-
this.c.editor
|
569
|
-
.edit(
|
570
|
-
diffNodes,
|
571
|
-
false,
|
572
|
-
$.extend( {submit: 'changed'}, this.c.formOptions )
|
573
|
-
)
|
574
|
-
.multiSet( dataSrc, idDiff )
|
575
|
-
.one( 'preSubmitCancelled.rowReorder', function () {
|
576
|
-
that.c.enable = true;
|
577
|
-
that.c.editor.off( '.rowReorder' );
|
578
|
-
dt.draw( false );
|
579
|
-
} )
|
580
|
-
.one( 'submitUnsuccessful.rowReorder', function () {
|
581
|
-
dt.draw( false );
|
582
|
-
} )
|
583
|
-
.one( 'submitSuccess.rowReorder', function () {
|
584
|
-
update();
|
585
|
-
} )
|
586
|
-
.one( 'submitComplete', function () {
|
587
|
-
that.c.enable = true;
|
588
|
-
that.c.editor.off( '.rowReorder' );
|
589
|
-
} )
|
590
|
-
.submit();
|
591
|
-
}
|
592
|
-
else {
|
593
|
-
update();
|
594
|
-
}
|
595
|
-
},
|
596
|
-
|
597
|
-
|
598
|
-
/**
|
599
|
-
* Move the window and DataTables scrolling during a drag to scroll new
|
600
|
-
* content into view.
|
601
|
-
*
|
602
|
-
* This matches the `_shiftScroll` method used in AutoFill, but only
|
603
|
-
* horizontal scrolling is considered here.
|
604
|
-
*
|
605
|
-
* @param {object} e Mouse move event object
|
606
|
-
* @private
|
607
|
-
*/
|
608
|
-
_shiftScroll: function ( e )
|
609
|
-
{
|
610
|
-
var that = this;
|
611
|
-
var dt = this.s.dt;
|
612
|
-
var scroll = this.s.scroll;
|
613
|
-
var runInterval = false;
|
614
|
-
var scrollSpeed = 5;
|
615
|
-
var buffer = 65;
|
616
|
-
var
|
617
|
-
windowY = e.pageY - document.body.scrollTop,
|
618
|
-
windowVert,
|
619
|
-
dtVert;
|
620
|
-
|
621
|
-
// Window calculations - based on the mouse position in the window,
|
622
|
-
// regardless of scrolling
|
623
|
-
if ( windowY < buffer ) {
|
624
|
-
windowVert = scrollSpeed * -1;
|
625
|
-
}
|
626
|
-
else if ( windowY > scroll.windowHeight - buffer ) {
|
627
|
-
windowVert = scrollSpeed;
|
628
|
-
}
|
629
|
-
|
630
|
-
// DataTables scrolling calculations - based on the table's position in
|
631
|
-
// the document and the mouse position on the page
|
632
|
-
if ( scroll.dtTop !== null && e.pageY < scroll.dtTop + buffer ) {
|
633
|
-
dtVert = scrollSpeed * -1;
|
634
|
-
}
|
635
|
-
else if ( scroll.dtTop !== null && e.pageY > scroll.dtTop + scroll.dtHeight - buffer ) {
|
636
|
-
dtVert = scrollSpeed;
|
637
|
-
}
|
638
|
-
|
639
|
-
// This is where it gets interesting. We want to continue scrolling
|
640
|
-
// without requiring a mouse move, so we need an interval to be
|
641
|
-
// triggered. The interval should continue until it is no longer needed,
|
642
|
-
// but it must also use the latest scroll commands (for example consider
|
643
|
-
// that the mouse might move from scrolling up to scrolling left, all
|
644
|
-
// with the same interval running. We use the `scroll` object to "pass"
|
645
|
-
// this information to the interval. Can't use local variables as they
|
646
|
-
// wouldn't be the ones that are used by an already existing interval!
|
647
|
-
if ( windowVert || dtVert ) {
|
648
|
-
scroll.windowVert = windowVert;
|
649
|
-
scroll.dtVert = dtVert;
|
650
|
-
runInterval = true;
|
651
|
-
}
|
652
|
-
else if ( this.s.scrollInterval ) {
|
653
|
-
// Don't need to scroll - remove any existing timer
|
654
|
-
clearInterval( this.s.scrollInterval );
|
655
|
-
this.s.scrollInterval = null;
|
656
|
-
}
|
657
|
-
|
658
|
-
// If we need to run the interval to scroll and there is no existing
|
659
|
-
// interval (if there is an existing one, it will continue to run)
|
660
|
-
if ( ! this.s.scrollInterval && runInterval ) {
|
661
|
-
this.s.scrollInterval = setInterval( function () {
|
662
|
-
// Don't need to worry about setting scroll <0 or beyond the
|
663
|
-
// scroll bound as the browser will just reject that.
|
664
|
-
if ( scroll.windowVert ) {
|
665
|
-
document.body.scrollTop += scroll.windowVert;
|
666
|
-
}
|
667
|
-
|
668
|
-
// DataTables scrolling
|
669
|
-
if ( scroll.dtVert ) {
|
670
|
-
var scroller = that.dom.dtScroll[0];
|
671
|
-
|
672
|
-
if ( scroll.dtVert ) {
|
673
|
-
scroller.scrollTop += scroll.dtVert;
|
674
|
-
}
|
675
|
-
}
|
676
|
-
}, 20 );
|
677
|
-
}
|
678
|
-
}
|
679
|
-
} );
|
112
|
+
/** @type {array} Pixel positions for row insertion calculation */
|
113
|
+
middles: null,
|
680
114
|
|
115
|
+
/** @type {Object} Cached dimension information for use in the mouse move event handler */
|
116
|
+
scroll: {},
|
681
117
|
|
118
|
+
/** @type {integer} Interval object used for smooth scrolling */
|
119
|
+
scrollInterval: null,
|
120
|
+
|
121
|
+
/** @type {function} Data set function */
|
122
|
+
setDataFn: DataTable.ext.oApi._fnSetObjectDataFn(this.c.dataSrc),
|
123
|
+
|
124
|
+
/** @type {Object} Mouse down information */
|
125
|
+
start: {
|
126
|
+
top: 0,
|
127
|
+
left: 0,
|
128
|
+
offsetTop: 0,
|
129
|
+
offsetLeft: 0,
|
130
|
+
nodes: [],
|
131
|
+
rowIndex: 0
|
132
|
+
},
|
133
|
+
|
134
|
+
/** @type {integer} Window height cached value */
|
135
|
+
windowHeight: 0,
|
136
|
+
|
137
|
+
/** @type {integer} Document outer height cached value */
|
138
|
+
documentOuterHeight: 0,
|
139
|
+
|
140
|
+
/** @type {integer} DOM clone outer height cached value */
|
141
|
+
domCloneOuterHeight: 0,
|
142
|
+
|
143
|
+
/** @type {integer} Flag used for signing if the drop is enabled or not */
|
144
|
+
dropAllowed: true
|
145
|
+
};
|
146
|
+
|
147
|
+
// DOM items
|
148
|
+
this.dom = {
|
149
|
+
/** @type {jQuery} Cloned row being moved around */
|
150
|
+
clone: null,
|
151
|
+
cloneParent: null,
|
152
|
+
|
153
|
+
/** @type {jQuery} DataTables scrolling container */
|
154
|
+
dtScroll: $('div.dataTables_scrollBody', this.s.dt.table().container())
|
155
|
+
};
|
156
|
+
|
157
|
+
// Check if row reorder has already been initialised on this table
|
158
|
+
var settings = this.s.dt.settings()[0];
|
159
|
+
var exisiting = settings.rowreorder;
|
160
|
+
|
161
|
+
if (exisiting) {
|
162
|
+
return exisiting;
|
163
|
+
}
|
164
|
+
|
165
|
+
if (!this.dom.dtScroll.length) {
|
166
|
+
this.dom.dtScroll = $(this.s.dt.table().container(), 'tbody');
|
167
|
+
}
|
168
|
+
|
169
|
+
settings.rowreorder = this;
|
170
|
+
this._constructor();
|
171
|
+
};
|
172
|
+
|
173
|
+
$.extend(RowReorder.prototype, {
|
174
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
175
|
+
* Constructor
|
176
|
+
*/
|
177
|
+
|
178
|
+
/**
|
179
|
+
* Initialise the RowReorder instance
|
180
|
+
*
|
181
|
+
* @private
|
182
|
+
*/
|
183
|
+
_constructor: function () {
|
184
|
+
var that = this;
|
185
|
+
var dt = this.s.dt;
|
186
|
+
var table = $(dt.table().node());
|
187
|
+
|
188
|
+
// Need to be able to calculate the row positions relative to the table
|
189
|
+
if (table.css('position') === 'static') {
|
190
|
+
table.css('position', 'relative');
|
191
|
+
}
|
192
|
+
|
193
|
+
// listen for mouse down on the target column - we have to implement
|
194
|
+
// this rather than using HTML5 drag and drop as drag and drop doesn't
|
195
|
+
// appear to work on table rows at this time. Also mobile browsers are
|
196
|
+
// not supported.
|
197
|
+
// Use `table().container()` rather than just the table node for IE8 -
|
198
|
+
// otherwise it only works once...
|
199
|
+
$(dt.table().container()).on(
|
200
|
+
'mousedown.rowReorder touchstart.rowReorder',
|
201
|
+
this.c.selector,
|
202
|
+
function (e) {
|
203
|
+
if (!that.c.enable) {
|
204
|
+
return;
|
205
|
+
}
|
206
|
+
|
207
|
+
// Ignore excluded children of the selector
|
208
|
+
if ($(e.target).is(that.c.excludedChildren)) {
|
209
|
+
return true;
|
210
|
+
}
|
211
|
+
|
212
|
+
var tr = $(this).closest('tr');
|
213
|
+
var row = dt.row(tr);
|
214
|
+
|
215
|
+
// Double check that it is a DataTable row
|
216
|
+
if (row.any()) {
|
217
|
+
that._emitEvent('pre-row-reorder', {
|
218
|
+
node: row.node(),
|
219
|
+
index: row.index()
|
220
|
+
});
|
221
|
+
|
222
|
+
that._mouseDown(e, tr);
|
223
|
+
return false;
|
224
|
+
}
|
225
|
+
}
|
226
|
+
);
|
227
|
+
|
228
|
+
dt.on('destroy.rowReorder', function () {
|
229
|
+
$(dt.table().container()).off('.rowReorder');
|
230
|
+
dt.off('.rowReorder');
|
231
|
+
});
|
232
|
+
|
233
|
+
this._keyup = this._keyup.bind(this);
|
234
|
+
},
|
235
|
+
|
236
|
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
237
|
+
* Private methods
|
238
|
+
*/
|
239
|
+
|
240
|
+
/**
|
241
|
+
* Cache the measurements that RowReorder needs in the mouse move handler
|
242
|
+
* to attempt to speed things up, rather than reading from the DOM.
|
243
|
+
*
|
244
|
+
* @private
|
245
|
+
*/
|
246
|
+
_cachePositions: function () {
|
247
|
+
var dt = this.s.dt;
|
248
|
+
|
249
|
+
// Frustratingly, if we add `position:relative` to the tbody, the
|
250
|
+
// position is still relatively to the parent. So we need to adjust
|
251
|
+
// for that
|
252
|
+
var headerHeight = $(dt.table().node()).find('thead').outerHeight();
|
253
|
+
|
254
|
+
// Need to pass the nodes through jQuery to get them in document order,
|
255
|
+
// not what DataTables thinks it is, since we have been altering the
|
256
|
+
// order
|
257
|
+
var nodes = $.unique(dt.rows({ page: 'current' }).nodes().toArray());
|
258
|
+
var middles = $.map(nodes, function (node, i) {
|
259
|
+
var top = $(node).position().top - headerHeight;
|
260
|
+
|
261
|
+
return (top + top + $(node).outerHeight()) / 2;
|
262
|
+
});
|
263
|
+
|
264
|
+
this.s.middles = middles;
|
265
|
+
this.s.bodyTop = $(dt.table().body()).offset().top;
|
266
|
+
this.s.windowHeight = $(window).height();
|
267
|
+
this.s.documentOuterHeight = $(document).outerHeight();
|
268
|
+
this.s.bodyArea = this._calcBodyArea();
|
269
|
+
},
|
270
|
+
|
271
|
+
/**
|
272
|
+
* Clone a row so it can be floated around the screen
|
273
|
+
*
|
274
|
+
* @param {jQuery} target Node to be cloned
|
275
|
+
* @private
|
276
|
+
*/
|
277
|
+
_clone: function (target) {
|
278
|
+
var dt = this.s.dt;
|
279
|
+
var clone = $(dt.table().node().cloneNode(false))
|
280
|
+
.addClass('dt-rowReorder-float')
|
281
|
+
.append('<tbody/>')
|
282
|
+
.append(target.clone(false));
|
283
|
+
|
284
|
+
// Match the table and column widths - read all sizes before setting
|
285
|
+
// to reduce reflows
|
286
|
+
var tableWidth = target.outerWidth();
|
287
|
+
var tableHeight = target.outerHeight();
|
288
|
+
var scrollBody = $($(this.s.dt.table().node()).parent());
|
289
|
+
var scrollWidth = scrollBody.width();
|
290
|
+
var scrollLeft = scrollBody.scrollLeft();
|
291
|
+
var sizes = target.children().map(function () {
|
292
|
+
return $(this).width();
|
293
|
+
});
|
294
|
+
|
295
|
+
clone
|
296
|
+
.width(tableWidth)
|
297
|
+
.height(tableHeight)
|
298
|
+
.find('tr')
|
299
|
+
.children()
|
300
|
+
.each(function (i) {
|
301
|
+
this.style.width = sizes[i] + 'px';
|
302
|
+
});
|
303
|
+
|
304
|
+
var cloneParent = $('<div>')
|
305
|
+
.addClass('dt-rowReorder-float-parent')
|
306
|
+
.width(scrollWidth)
|
307
|
+
.append(clone)
|
308
|
+
.appendTo('body')
|
309
|
+
.scrollLeft(scrollLeft);
|
310
|
+
|
311
|
+
// Insert into the document to have it floating around
|
312
|
+
|
313
|
+
this.dom.clone = clone;
|
314
|
+
this.dom.cloneParent = cloneParent;
|
315
|
+
this.s.domCloneOuterHeight = clone.outerHeight();
|
316
|
+
},
|
317
|
+
|
318
|
+
/**
|
319
|
+
* Update the cloned item's position in the document
|
320
|
+
*
|
321
|
+
* @param {object} e Event giving the mouse's position
|
322
|
+
* @private
|
323
|
+
*/
|
324
|
+
_clonePosition: function (e) {
|
325
|
+
var start = this.s.start;
|
326
|
+
var topDiff = this._eventToPage(e, 'Y') - start.top;
|
327
|
+
var leftDiff = this._eventToPage(e, 'X') - start.left;
|
328
|
+
var snap = this.c.snapX;
|
329
|
+
var left;
|
330
|
+
var top = topDiff + start.offsetTop;
|
331
|
+
|
332
|
+
if (snap === true) {
|
333
|
+
left = start.offsetLeft;
|
334
|
+
}
|
335
|
+
else if (typeof snap === 'number') {
|
336
|
+
left = start.offsetLeft + snap;
|
337
|
+
}
|
338
|
+
else {
|
339
|
+
left = leftDiff + start.offsetLeft + this.dom.cloneParent.scrollLeft();
|
340
|
+
}
|
341
|
+
|
342
|
+
if (top < 0) {
|
343
|
+
top = 0;
|
344
|
+
}
|
345
|
+
else if (top + this.s.domCloneOuterHeight > this.s.documentOuterHeight) {
|
346
|
+
top = this.s.documentOuterHeight - this.s.domCloneOuterHeight;
|
347
|
+
}
|
348
|
+
|
349
|
+
this.dom.cloneParent.css({
|
350
|
+
top: top,
|
351
|
+
left: left
|
352
|
+
});
|
353
|
+
},
|
354
|
+
|
355
|
+
/**
|
356
|
+
* Emit an event on the DataTable for listeners
|
357
|
+
*
|
358
|
+
* @param {string} name Event name
|
359
|
+
* @param {array} args Event arguments
|
360
|
+
* @private
|
361
|
+
*/
|
362
|
+
_emitEvent: function ( name, args )
|
363
|
+
{
|
364
|
+
var ret;
|
365
|
+
|
366
|
+
this.s.dt.iterator( 'table', function ( ctx, i ) {
|
367
|
+
var innerRet = $(ctx.nTable).triggerHandler( name+'.dt', args );
|
368
|
+
|
369
|
+
if (innerRet !== undefined) {
|
370
|
+
ret = innerRet;
|
371
|
+
}
|
372
|
+
} );
|
373
|
+
|
374
|
+
return ret;
|
375
|
+
},
|
376
|
+
|
377
|
+
/**
|
378
|
+
* Get pageX/Y position from an event, regardless of if it is a mouse or
|
379
|
+
* touch event.
|
380
|
+
*
|
381
|
+
* @param {object} e Event
|
382
|
+
* @param {string} pos X or Y (must be a capital)
|
383
|
+
* @private
|
384
|
+
*/
|
385
|
+
_eventToPage: function (e, pos) {
|
386
|
+
if (e.type.indexOf('touch') !== -1) {
|
387
|
+
return e.originalEvent.touches[0]['page' + pos];
|
388
|
+
}
|
389
|
+
|
390
|
+
return e['page' + pos];
|
391
|
+
},
|
392
|
+
|
393
|
+
/**
|
394
|
+
* Mouse down event handler. Read initial positions and add event handlers
|
395
|
+
* for the move.
|
396
|
+
*
|
397
|
+
* @param {object} e Mouse event
|
398
|
+
* @param {jQuery} target TR element that is to be moved
|
399
|
+
* @private
|
400
|
+
*/
|
401
|
+
_mouseDown: function (e, target) {
|
402
|
+
var that = this;
|
403
|
+
var dt = this.s.dt;
|
404
|
+
var start = this.s.start;
|
405
|
+
var cancelable = this.c.cancelable;
|
406
|
+
|
407
|
+
var offset = target.offset();
|
408
|
+
start.top = this._eventToPage(e, 'Y');
|
409
|
+
start.left = this._eventToPage(e, 'X');
|
410
|
+
start.offsetTop = offset.top;
|
411
|
+
start.offsetLeft = offset.left;
|
412
|
+
start.nodes = $.unique(dt.rows({ page: 'current' }).nodes().toArray());
|
413
|
+
|
414
|
+
this._cachePositions();
|
415
|
+
this._clone(target);
|
416
|
+
this._clonePosition(e);
|
417
|
+
|
418
|
+
var bodyY = this._eventToPage(e, 'Y') - this.s.bodyTop;
|
419
|
+
start.rowIndex = this._calcRowIndexByPos(bodyY);
|
420
|
+
|
421
|
+
this.dom.target = target;
|
422
|
+
target.addClass('dt-rowReorder-moving');
|
423
|
+
|
424
|
+
$(document)
|
425
|
+
.on('mouseup.rowReorder touchend.rowReorder', function (e) {
|
426
|
+
that._mouseUp(e);
|
427
|
+
})
|
428
|
+
.on('mousemove.rowReorder touchmove.rowReorder', function (e) {
|
429
|
+
that._mouseMove(e);
|
430
|
+
});
|
431
|
+
|
432
|
+
// Check if window is x-scrolling - if not, disable it for the duration
|
433
|
+
// of the drag
|
434
|
+
if ($(window).width() === $(document).width()) {
|
435
|
+
$(document.body).addClass('dt-rowReorder-noOverflow');
|
436
|
+
}
|
437
|
+
|
438
|
+
// Cache scrolling information so mouse move doesn't need to read.
|
439
|
+
// This assumes that the window and DT scroller will not change size
|
440
|
+
// during an row drag, which I think is a fair assumption
|
441
|
+
var scrollWrapper = this.dom.dtScroll;
|
442
|
+
this.s.scroll = {
|
443
|
+
windowHeight: $(window).height(),
|
444
|
+
windowWidth: $(window).width(),
|
445
|
+
dtTop: scrollWrapper.length ? scrollWrapper.offset().top : null,
|
446
|
+
dtLeft: scrollWrapper.length ? scrollWrapper.offset().left : null,
|
447
|
+
dtHeight: scrollWrapper.length ? scrollWrapper.outerHeight() : null,
|
448
|
+
dtWidth: scrollWrapper.length ? scrollWrapper.outerWidth() : null
|
449
|
+
};
|
450
|
+
|
451
|
+
// Add keyup handler if dragging is cancelable
|
452
|
+
if (cancelable) {
|
453
|
+
$(document).on('keyup', this._keyup);
|
454
|
+
}
|
455
|
+
},
|
456
|
+
|
457
|
+
/**
|
458
|
+
* Mouse move event handler - move the cloned row and shuffle the table's
|
459
|
+
* rows if required.
|
460
|
+
*
|
461
|
+
* @param {object} e Mouse event
|
462
|
+
* @private
|
463
|
+
*/
|
464
|
+
_mouseMove: function (e) {
|
465
|
+
this._clonePosition(e);
|
466
|
+
|
467
|
+
var start = this.s.start;
|
468
|
+
var cancelable = this.c.cancelable;
|
469
|
+
|
470
|
+
if (cancelable) {
|
471
|
+
var bodyArea = this.s.bodyArea;
|
472
|
+
var cloneArea = this._calcCloneParentArea();
|
473
|
+
this.s.dropAllowed = this._rectanglesIntersect(bodyArea, cloneArea);
|
474
|
+
|
475
|
+
this.s.dropAllowed
|
476
|
+
? $(this.dom.cloneParent).removeClass('drop-not-allowed')
|
477
|
+
: $(this.dom.cloneParent).addClass('drop-not-allowed');
|
478
|
+
}
|
479
|
+
|
480
|
+
// Transform the mouse position into a position in the table's body
|
481
|
+
var bodyY = this._eventToPage(e, 'Y') - this.s.bodyTop;
|
482
|
+
var middles = this.s.middles;
|
483
|
+
var insertPoint = null;
|
484
|
+
|
485
|
+
// Determine where the row should be inserted based on the mouse
|
486
|
+
// position
|
487
|
+
for (var i = 0, ien = middles.length; i < ien; i++) {
|
488
|
+
if (bodyY < middles[i]) {
|
489
|
+
insertPoint = i;
|
490
|
+
break;
|
491
|
+
}
|
492
|
+
}
|
493
|
+
|
494
|
+
if (insertPoint === null) {
|
495
|
+
insertPoint = middles.length;
|
496
|
+
}
|
497
|
+
|
498
|
+
if (cancelable) {
|
499
|
+
if (!this.s.dropAllowed) {
|
500
|
+
// Move the row back to its original position becasuse the drop is not allowed
|
501
|
+
insertPoint =
|
502
|
+
start.rowIndex > this.s.lastInsert ? start.rowIndex + 1 : start.rowIndex;
|
503
|
+
}
|
504
|
+
|
505
|
+
this.dom.target.toggleClass('dt-rowReorder-moving', this.s.dropAllowed);
|
506
|
+
}
|
507
|
+
|
508
|
+
this._moveTargetIntoPosition(insertPoint);
|
509
|
+
|
510
|
+
this._shiftScroll(e);
|
511
|
+
},
|
512
|
+
|
513
|
+
/**
|
514
|
+
* Mouse up event handler - release the event handlers and perform the
|
515
|
+
* table updates
|
516
|
+
*
|
517
|
+
* @param {object} e Mouse event
|
518
|
+
* @private
|
519
|
+
*/
|
520
|
+
_mouseUp: function (e) {
|
521
|
+
var that = this;
|
522
|
+
var dt = this.s.dt;
|
523
|
+
var i, ien;
|
524
|
+
var dataSrc = this.c.dataSrc;
|
525
|
+
var dropAllowed = this.s.dropAllowed;
|
526
|
+
|
527
|
+
if (!dropAllowed) {
|
528
|
+
that._cancel();
|
529
|
+
return;
|
530
|
+
}
|
531
|
+
|
532
|
+
// Calculate the difference
|
533
|
+
var startNodes = this.s.start.nodes;
|
534
|
+
var endNodes = $.unique(dt.rows({ page: 'current' }).nodes().toArray());
|
535
|
+
var idDiff = {};
|
536
|
+
var fullDiff = [];
|
537
|
+
var diffNodes = [];
|
538
|
+
var getDataFn = this.s.getDataFn;
|
539
|
+
var setDataFn = this.s.setDataFn;
|
540
|
+
|
541
|
+
for (i = 0, ien = startNodes.length; i < ien; i++) {
|
542
|
+
if (startNodes[i] !== endNodes[i]) {
|
543
|
+
var id = dt.row(endNodes[i]).id();
|
544
|
+
var endRowData = dt.row(endNodes[i]).data();
|
545
|
+
var startRowData = dt.row(startNodes[i]).data();
|
546
|
+
|
547
|
+
if (id) {
|
548
|
+
idDiff[id] = getDataFn(startRowData);
|
549
|
+
}
|
550
|
+
|
551
|
+
fullDiff.push({
|
552
|
+
node: endNodes[i],
|
553
|
+
oldData: getDataFn(endRowData),
|
554
|
+
newData: getDataFn(startRowData),
|
555
|
+
newPosition: i,
|
556
|
+
oldPosition: $.inArray(endNodes[i], startNodes)
|
557
|
+
});
|
558
|
+
|
559
|
+
diffNodes.push(endNodes[i]);
|
560
|
+
}
|
561
|
+
}
|
562
|
+
|
563
|
+
// Create event args
|
564
|
+
var eventArgs = [
|
565
|
+
fullDiff,
|
566
|
+
{
|
567
|
+
dataSrc: dataSrc,
|
568
|
+
nodes: diffNodes,
|
569
|
+
values: idDiff,
|
570
|
+
triggerRow: dt.row(this.dom.target),
|
571
|
+
originalEvent: e
|
572
|
+
}
|
573
|
+
];
|
574
|
+
|
575
|
+
// Emit event
|
576
|
+
var eventResult = this._emitEvent( 'row-reorder', eventArgs );
|
577
|
+
|
578
|
+
if (eventResult === false) {
|
579
|
+
that._cancel();
|
580
|
+
return;
|
581
|
+
}
|
582
|
+
|
583
|
+
// Remove cloned elements, handlers, etc
|
584
|
+
this._cleanupDragging();
|
585
|
+
|
586
|
+
var update = function () {
|
587
|
+
if (that.c.update) {
|
588
|
+
for (i = 0, ien = fullDiff.length; i < ien; i++) {
|
589
|
+
var row = dt.row(fullDiff[i].node);
|
590
|
+
var rowData = row.data();
|
591
|
+
|
592
|
+
setDataFn(rowData, fullDiff[i].newData);
|
593
|
+
|
594
|
+
// Invalidate the cell that has the same data source as the dataSrc
|
595
|
+
dt.columns().every(function () {
|
596
|
+
if (this.dataSrc() === dataSrc) {
|
597
|
+
dt.cell(fullDiff[i].node, this.index()).invalidate('data');
|
598
|
+
}
|
599
|
+
});
|
600
|
+
}
|
601
|
+
|
602
|
+
// Trigger row reordered event
|
603
|
+
that._emitEvent('row-reordered', eventArgs);
|
604
|
+
|
605
|
+
dt.draw(false);
|
606
|
+
}
|
607
|
+
};
|
608
|
+
|
609
|
+
// Editor interface
|
610
|
+
if (this.c.editor) {
|
611
|
+
// Disable user interaction while Editor is submitting
|
612
|
+
this.c.enable = false;
|
613
|
+
|
614
|
+
this.c.editor
|
615
|
+
.edit(diffNodes, false, $.extend({ submit: 'changed' }, this.c.formOptions))
|
616
|
+
.multiSet(dataSrc, idDiff)
|
617
|
+
.one('preSubmitCancelled.rowReorder', function () {
|
618
|
+
that.c.enable = true;
|
619
|
+
that.c.editor.off('.rowReorder');
|
620
|
+
dt.draw(false);
|
621
|
+
})
|
622
|
+
.one('submitUnsuccessful.rowReorder', function () {
|
623
|
+
dt.draw(false);
|
624
|
+
})
|
625
|
+
.one('submitSuccess.rowReorder', function () {
|
626
|
+
update();
|
627
|
+
})
|
628
|
+
.one('submitComplete', function () {
|
629
|
+
that.c.enable = true;
|
630
|
+
that.c.editor.off('.rowReorder');
|
631
|
+
})
|
632
|
+
.submit();
|
633
|
+
}
|
634
|
+
else {
|
635
|
+
update();
|
636
|
+
}
|
637
|
+
},
|
638
|
+
|
639
|
+
/**
|
640
|
+
* Moves the current target into the given position within the table
|
641
|
+
* and caches the new positions
|
642
|
+
*
|
643
|
+
* @param {integer} insertPoint Position
|
644
|
+
* @private
|
645
|
+
*/
|
646
|
+
_moveTargetIntoPosition: function (insertPoint) {
|
647
|
+
var dt = this.s.dt;
|
648
|
+
|
649
|
+
// Perform the DOM shuffle if it has changed from last time
|
650
|
+
if (this.s.lastInsert === null || this.s.lastInsert !== insertPoint) {
|
651
|
+
var nodes = $.unique(dt.rows({ page: 'current' }).nodes().toArray());
|
652
|
+
var insertPlacement = '';
|
653
|
+
|
654
|
+
if (insertPoint > this.s.lastInsert) {
|
655
|
+
this.dom.target.insertAfter(nodes[insertPoint - 1]);
|
656
|
+
insertPlacement = 'after';
|
657
|
+
}
|
658
|
+
else {
|
659
|
+
this.dom.target.insertBefore(nodes[insertPoint]);
|
660
|
+
insertPlacement = 'before';
|
661
|
+
}
|
662
|
+
|
663
|
+
this._cachePositions();
|
664
|
+
|
665
|
+
this.s.lastInsert = insertPoint;
|
666
|
+
|
667
|
+
this._emitEvent('row-reorder-changed', {
|
668
|
+
insertPlacement,
|
669
|
+
insertPoint,
|
670
|
+
row: dt.row(this.dom.target)
|
671
|
+
});
|
672
|
+
}
|
673
|
+
},
|
674
|
+
|
675
|
+
/**
|
676
|
+
* Removes the cloned elements, event handlers, scrolling intervals, etc
|
677
|
+
*
|
678
|
+
* @private
|
679
|
+
*/
|
680
|
+
_cleanupDragging: function () {
|
681
|
+
var cancelable = this.c.cancelable;
|
682
|
+
|
683
|
+
this.dom.clone.remove();
|
684
|
+
this.dom.cloneParent.remove();
|
685
|
+
this.dom.clone = null;
|
686
|
+
this.dom.cloneParent = null;
|
687
|
+
|
688
|
+
this.dom.target.removeClass('dt-rowReorder-moving');
|
689
|
+
//this.dom.target = null;
|
690
|
+
|
691
|
+
$(document).off('.rowReorder');
|
692
|
+
$(document.body).removeClass('dt-rowReorder-noOverflow');
|
693
|
+
|
694
|
+
clearInterval(this.s.scrollInterval);
|
695
|
+
this.s.scrollInterval = null;
|
696
|
+
|
697
|
+
if (cancelable) {
|
698
|
+
$(document).off('keyup', this._keyup);
|
699
|
+
}
|
700
|
+
},
|
701
|
+
|
702
|
+
/**
|
703
|
+
* Move the window and DataTables scrolling during a drag to scroll new
|
704
|
+
* content into view.
|
705
|
+
*
|
706
|
+
* This matches the `_shiftScroll` method used in AutoFill, but only
|
707
|
+
* horizontal scrolling is considered here.
|
708
|
+
*
|
709
|
+
* @param {object} e Mouse move event object
|
710
|
+
* @private
|
711
|
+
*/
|
712
|
+
_shiftScroll: function (e) {
|
713
|
+
var that = this;
|
714
|
+
var dt = this.s.dt;
|
715
|
+
var scroll = this.s.scroll;
|
716
|
+
var runInterval = false;
|
717
|
+
var scrollSpeed = 5;
|
718
|
+
var buffer = 65;
|
719
|
+
var windowY = e.pageY - document.body.scrollTop,
|
720
|
+
windowVert,
|
721
|
+
dtVert;
|
722
|
+
|
723
|
+
// Window calculations - based on the mouse position in the window,
|
724
|
+
// regardless of scrolling
|
725
|
+
if (windowY < $(window).scrollTop() + buffer) {
|
726
|
+
windowVert = scrollSpeed * -1;
|
727
|
+
}
|
728
|
+
else if (windowY > scroll.windowHeight + $(window).scrollTop() - buffer) {
|
729
|
+
windowVert = scrollSpeed;
|
730
|
+
}
|
731
|
+
|
732
|
+
// DataTables scrolling calculations - based on the table's position in
|
733
|
+
// the document and the mouse position on the page
|
734
|
+
if (scroll.dtTop !== null && e.pageY < scroll.dtTop + buffer) {
|
735
|
+
dtVert = scrollSpeed * -1;
|
736
|
+
}
|
737
|
+
else if (scroll.dtTop !== null && e.pageY > scroll.dtTop + scroll.dtHeight - buffer) {
|
738
|
+
dtVert = scrollSpeed;
|
739
|
+
}
|
740
|
+
|
741
|
+
// This is where it gets interesting. We want to continue scrolling
|
742
|
+
// without requiring a mouse move, so we need an interval to be
|
743
|
+
// triggered. The interval should continue until it is no longer needed,
|
744
|
+
// but it must also use the latest scroll commands (for example consider
|
745
|
+
// that the mouse might move from scrolling up to scrolling left, all
|
746
|
+
// with the same interval running. We use the `scroll` object to "pass"
|
747
|
+
// this information to the interval. Can't use local variables as they
|
748
|
+
// wouldn't be the ones that are used by an already existing interval!
|
749
|
+
if (windowVert || dtVert) {
|
750
|
+
scroll.windowVert = windowVert;
|
751
|
+
scroll.dtVert = dtVert;
|
752
|
+
runInterval = true;
|
753
|
+
}
|
754
|
+
else if (this.s.scrollInterval) {
|
755
|
+
// Don't need to scroll - remove any existing timer
|
756
|
+
clearInterval(this.s.scrollInterval);
|
757
|
+
this.s.scrollInterval = null;
|
758
|
+
}
|
759
|
+
|
760
|
+
// If we need to run the interval to scroll and there is no existing
|
761
|
+
// interval (if there is an existing one, it will continue to run)
|
762
|
+
if (!this.s.scrollInterval && runInterval) {
|
763
|
+
this.s.scrollInterval = setInterval(function () {
|
764
|
+
// Don't need to worry about setting scroll <0 or beyond the
|
765
|
+
// scroll bound as the browser will just reject that.
|
766
|
+
if (scroll.windowVert) {
|
767
|
+
var top = $(document).scrollTop();
|
768
|
+
$(document).scrollTop(top + scroll.windowVert);
|
769
|
+
|
770
|
+
if (top !== $(document).scrollTop()) {
|
771
|
+
var move = parseFloat(that.dom.cloneParent.css('top'));
|
772
|
+
that.dom.cloneParent.css('top', move + scroll.windowVert);
|
773
|
+
}
|
774
|
+
}
|
775
|
+
|
776
|
+
// DataTables scrolling
|
777
|
+
if (scroll.dtVert) {
|
778
|
+
var scroller = that.dom.dtScroll[0];
|
779
|
+
|
780
|
+
if (scroll.dtVert) {
|
781
|
+
scroller.scrollTop += scroll.dtVert;
|
782
|
+
}
|
783
|
+
}
|
784
|
+
}, 20);
|
785
|
+
}
|
786
|
+
},
|
787
|
+
|
788
|
+
/**
|
789
|
+
* Calculates the current area of the table body and returns it as a rectangle
|
790
|
+
*
|
791
|
+
* @private
|
792
|
+
*/
|
793
|
+
_calcBodyArea: function (e) {
|
794
|
+
var dt = this.s.dt;
|
795
|
+
var offset = $(dt.table().body()).offset();
|
796
|
+
var area = {
|
797
|
+
left: offset.left,
|
798
|
+
top: offset.top,
|
799
|
+
right: offset.left + $(dt.table().body()).width(),
|
800
|
+
bottom: offset.top + $(dt.table().body()).height()
|
801
|
+
};
|
802
|
+
|
803
|
+
return area;
|
804
|
+
},
|
805
|
+
|
806
|
+
/**
|
807
|
+
* Calculates the current area of the cloned parent element and returns it as a rectangle
|
808
|
+
*
|
809
|
+
* @private
|
810
|
+
*/
|
811
|
+
_calcCloneParentArea: function (e) {
|
812
|
+
var dt = this.s.dt;
|
813
|
+
var offset = $(this.dom.cloneParent).offset();
|
814
|
+
var area = {
|
815
|
+
left: offset.left,
|
816
|
+
top: offset.top,
|
817
|
+
right: offset.left + $(this.dom.cloneParent).width(),
|
818
|
+
bottom: offset.top + $(this.dom.cloneParent).height()
|
819
|
+
};
|
820
|
+
|
821
|
+
return area;
|
822
|
+
},
|
823
|
+
|
824
|
+
/**
|
825
|
+
* Returns whether the given reactangles intersect or not
|
826
|
+
*
|
827
|
+
* @private
|
828
|
+
*/
|
829
|
+
_rectanglesIntersect: function (a, b) {
|
830
|
+
var noOverlap =
|
831
|
+
a.left >= b.right || b.left >= a.right || a.top >= b.bottom || b.top >= a.bottom;
|
832
|
+
|
833
|
+
return !noOverlap;
|
834
|
+
},
|
835
|
+
|
836
|
+
/**
|
837
|
+
* Calculates the index of the row which lays under the given Y position or
|
838
|
+
* returns -1 if no such row
|
839
|
+
*
|
840
|
+
* @param {integer} insertPoint Position
|
841
|
+
* @private
|
842
|
+
*/
|
843
|
+
_calcRowIndexByPos: function (bodyY) {
|
844
|
+
// Determine where the row is located based on the mouse
|
845
|
+
// position
|
846
|
+
|
847
|
+
var dt = this.s.dt;
|
848
|
+
var nodes = $.unique(dt.rows({ page: 'current' }).nodes().toArray());
|
849
|
+
var rowIndex = -1;
|
850
|
+
var headerHeight = $(dt.table().node()).find('thead').outerHeight();
|
851
|
+
|
852
|
+
$.each(nodes, function (i, node) {
|
853
|
+
var top = $(node).position().top - headerHeight;
|
854
|
+
var bottom = top + $(node).outerHeight();
|
855
|
+
|
856
|
+
if (bodyY >= top && bodyY <= bottom) {
|
857
|
+
rowIndex = i;
|
858
|
+
}
|
859
|
+
});
|
860
|
+
|
861
|
+
return rowIndex;
|
862
|
+
},
|
863
|
+
|
864
|
+
/**
|
865
|
+
* Handles key up events and cancels the dragging if ESC key is pressed
|
866
|
+
*
|
867
|
+
* @param {object} e Mouse move event object
|
868
|
+
* @private
|
869
|
+
*/
|
870
|
+
_keyup: function (e) {
|
871
|
+
var cancelable = this.c.cancelable;
|
872
|
+
|
873
|
+
if (cancelable && e.which === 27) {
|
874
|
+
// ESC key is up
|
875
|
+
e.preventDefault();
|
876
|
+
this._cancel();
|
877
|
+
}
|
878
|
+
},
|
879
|
+
|
880
|
+
/**
|
881
|
+
* Cancels the dragging, moves target back into its original position
|
882
|
+
* and cleans up the dragging
|
883
|
+
*
|
884
|
+
* @param {object} e Mouse move event object
|
885
|
+
* @private
|
886
|
+
*/
|
887
|
+
_cancel: function () {
|
888
|
+
var start = this.s.start;
|
889
|
+
var insertPoint = start.rowIndex > this.s.lastInsert ? start.rowIndex + 1 : start.rowIndex;
|
890
|
+
|
891
|
+
this._moveTargetIntoPosition(insertPoint);
|
892
|
+
|
893
|
+
this._cleanupDragging();
|
894
|
+
|
895
|
+
// Emit event
|
896
|
+
this._emitEvent('row-reorder-canceled', [this.s.start.rowIndex]);
|
897
|
+
}
|
898
|
+
});
|
682
899
|
|
683
900
|
/**
|
684
901
|
* RowReorder default settings for initialisation
|
@@ -688,99 +905,104 @@ $.extend( RowReorder.prototype, {
|
|
688
905
|
* @static
|
689
906
|
*/
|
690
907
|
RowReorder.defaults = {
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
908
|
+
/**
|
909
|
+
* Data point in the host row's data source object for where to get and set
|
910
|
+
* the data to reorder. This will normally also be the sorting column.
|
911
|
+
*
|
912
|
+
* @type {Number}
|
913
|
+
*/
|
914
|
+
dataSrc: 0,
|
915
|
+
|
916
|
+
/**
|
917
|
+
* Editor instance that will be used to perform the update
|
918
|
+
*
|
919
|
+
* @type {DataTable.Editor}
|
920
|
+
*/
|
921
|
+
editor: null,
|
922
|
+
|
923
|
+
/**
|
924
|
+
* Enable / disable RowReorder's user interaction
|
925
|
+
* @type {Boolean}
|
926
|
+
*/
|
927
|
+
enable: true,
|
928
|
+
|
929
|
+
/**
|
930
|
+
* Form options to pass to Editor when submitting a change in the row order.
|
931
|
+
* See the Editor `from-options` object for details of the options
|
932
|
+
* available.
|
933
|
+
* @type {Object}
|
934
|
+
*/
|
935
|
+
formOptions: {},
|
936
|
+
|
937
|
+
/**
|
938
|
+
* Drag handle selector. This defines the element that when dragged will
|
939
|
+
* reorder a row.
|
940
|
+
*
|
941
|
+
* @type {String}
|
942
|
+
*/
|
943
|
+
selector: 'td:first-child',
|
944
|
+
|
945
|
+
/**
|
946
|
+
* Optionally lock the dragged row's x-position. This can be `true` to
|
947
|
+
* fix the position match the host table's, `false` to allow free movement
|
948
|
+
* of the row, or a number to define an offset from the host table.
|
949
|
+
*
|
950
|
+
* @type {Boolean|number}
|
951
|
+
*/
|
952
|
+
snapX: false,
|
953
|
+
|
954
|
+
/**
|
955
|
+
* Update the table's data on drop
|
956
|
+
*
|
957
|
+
* @type {Boolean}
|
958
|
+
*/
|
959
|
+
update: true,
|
960
|
+
|
961
|
+
/**
|
962
|
+
* Selector for children of the drag handle selector that mouseDown events
|
963
|
+
* will be passed through to and drag will not activate
|
964
|
+
*
|
965
|
+
* @type {String}
|
966
|
+
*/
|
967
|
+
excludedChildren: 'a',
|
968
|
+
|
969
|
+
/**
|
970
|
+
* Enable / disable the canceling of the drag & drop interaction
|
971
|
+
*
|
972
|
+
* @type {Boolean}
|
973
|
+
*/
|
974
|
+
cancelable: false
|
751
975
|
};
|
752
976
|
|
753
|
-
|
754
977
|
/*
|
755
978
|
* API
|
756
979
|
*/
|
757
980
|
var Api = $.fn.dataTable.Api;
|
758
981
|
|
759
982
|
// Doesn't do anything - work around for a bug in DT... Not documented
|
760
|
-
Api.register(
|
761
|
-
|
762
|
-
}
|
763
|
-
|
764
|
-
Api.register(
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
}
|
775
|
-
|
776
|
-
Api.register(
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
}
|
783
|
-
|
983
|
+
Api.register('rowReorder()', function () {
|
984
|
+
return this;
|
985
|
+
});
|
986
|
+
|
987
|
+
Api.register('rowReorder.enable()', function (toggle) {
|
988
|
+
if (toggle === undefined) {
|
989
|
+
toggle = true;
|
990
|
+
}
|
991
|
+
|
992
|
+
return this.iterator('table', function (ctx) {
|
993
|
+
if (ctx.rowreorder) {
|
994
|
+
ctx.rowreorder.c.enable = toggle;
|
995
|
+
}
|
996
|
+
});
|
997
|
+
});
|
998
|
+
|
999
|
+
Api.register('rowReorder.disable()', function () {
|
1000
|
+
return this.iterator('table', function (ctx) {
|
1001
|
+
if (ctx.rowreorder) {
|
1002
|
+
ctx.rowreorder.c.enable = false;
|
1003
|
+
}
|
1004
|
+
});
|
1005
|
+
});
|
784
1006
|
|
785
1007
|
/**
|
786
1008
|
* Version information
|
@@ -788,31 +1010,30 @@ Api.register( 'rowReorder.disable()', function () {
|
|
788
1010
|
* @name RowReorder.version
|
789
1011
|
* @static
|
790
1012
|
*/
|
791
|
-
RowReorder.version = '1.
|
792
|
-
|
1013
|
+
RowReorder.version = '1.4.1';
|
793
1014
|
|
794
1015
|
$.fn.dataTable.RowReorder = RowReorder;
|
795
1016
|
$.fn.DataTable.RowReorder = RowReorder;
|
796
1017
|
|
797
1018
|
// Attach a listener to the document which listens for DataTables initialisation
|
798
1019
|
// events so we can automatically initialise
|
799
|
-
$(document).on(
|
800
|
-
|
801
|
-
|
802
|
-
|
1020
|
+
$(document).on('init.dt.dtr', function (e, settings, json) {
|
1021
|
+
if (e.namespace !== 'dt') {
|
1022
|
+
return;
|
1023
|
+
}
|
803
1024
|
|
804
|
-
|
805
|
-
|
1025
|
+
var init = settings.oInit.rowReorder;
|
1026
|
+
var defaults = DataTable.defaults.rowReorder;
|
806
1027
|
|
807
|
-
|
808
|
-
|
1028
|
+
if (init || defaults) {
|
1029
|
+
var opts = $.extend({}, init, defaults);
|
809
1030
|
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
}
|
1031
|
+
if (init !== false) {
|
1032
|
+
new RowReorder(settings, opts);
|
1033
|
+
}
|
1034
|
+
}
|
1035
|
+
});
|
815
1036
|
|
816
1037
|
|
817
|
-
return
|
1038
|
+
return DataTable;
|
818
1039
|
}));
|