Show More
Commit Description:
user admin
Commit Description:
user admin
References:
File last commit:
Show/Diff file:
Action:
vendor/javascript/datatables/RowReorder-1.2.8/js/dataTables.rowReorder.js
| 820 lines
| 20.8 KiB
| application/javascript
| JavascriptLexer
|
r866 | /*! RowReorder 1.2.8 | |||
* 2015-2020 SpryMedia Ltd - datatables.net/license | ||||
*/ | ||||
/** | ||||
* @summary RowReorder | ||||
* @description Row reordering extension for DataTables | ||||
* @version 1.2.8 | ||||
* @file dataTables.rowReorder.js | ||||
* @author SpryMedia Ltd (www.sprymedia.co.uk) | ||||
* @contact www.sprymedia.co.uk/contact | ||||
* @copyright Copyright 2015-2020 SpryMedia Ltd. | ||||
* | ||||
* This source file is free software, available under the following license: | ||||
* MIT license - http://datatables.net/license/mit | ||||
* | ||||
* This source file is distributed in the hope that it will be useful, but | ||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. | ||||
* | ||||
* For details please refer to: http://www.datatables.net | ||||
*/ | ||||
(function( factory ){ | ||||
if ( typeof define === 'function' && define.amd ) { | ||||
// AMD | ||||
define( ['jquery', 'datatables.net'], function ( $ ) { | ||||
return factory( $, window, document ); | ||||
} ); | ||||
} | ||||
else if ( typeof exports === 'object' ) { | ||||
// CommonJS | ||||
module.exports = function (root, $) { | ||||
if ( ! root ) { | ||||
root = window; | ||||
} | ||||
if ( ! $ || ! $.fn.dataTable ) { | ||||
$ = require('datatables.net')(root, $).$; | ||||
} | ||||
return factory( $, root, root.document ); | ||||
}; | ||||
} | ||||
else { | ||||
// Browser | ||||
factory( jQuery, window, document ); | ||||
} | ||||
}(function( $, window, document, undefined ) { | ||||
'use strict'; | ||||
var DataTable = $.fn.dataTable; | ||||
/** | ||||
* RowReorder provides the ability in DataTables to click and drag rows to | ||||
* reorder them. When a row is dropped the data for the rows effected will be | ||||
* updated to reflect the change. Normally this data point should also be the | ||||
* column being sorted upon in the DataTable but this does not need to be the | ||||
* case. RowReorder implements a "data swap" method - so the rows being | ||||
* reordered take the value of the data point from the row that used to occupy | ||||
* the row's new position. | ||||
* | ||||
* Initialisation is done by either: | ||||
* | ||||
* * `rowReorder` parameter in the DataTable initialisation object | ||||
* * `new $.fn.dataTable.RowReorder( table, opts )` after DataTables | ||||
* initialisation. | ||||
* | ||||
* @class | ||||
* @param {object} settings DataTables settings object for the host table | ||||
* @param {object} [opts] Configuration options | ||||
* @requires jQuery 1.7+ | ||||
* @requires DataTables 1.10.7+ | ||||
*/ | ||||
var RowReorder = function ( dt, opts ) { | ||||
// Sanity check that we are using DataTables 1.10 or newer | ||||
if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.8' ) ) { | ||||
throw 'DataTables RowReorder requires DataTables 1.10.8 or newer'; | ||||
} | ||||
// User and defaults configuration object | ||||
this.c = $.extend( true, {}, | ||||
DataTable.defaults.rowReorder, | ||||
RowReorder.defaults, | ||||
opts | ||||
); | ||||
// Internal settings | ||||
this.s = { | ||||
/** @type {integer} Scroll body top cache */ | ||||
bodyTop: null, | ||||
/** @type {DataTable.Api} DataTables' API instance */ | ||||
dt: new DataTable.Api( dt ), | ||||
/** @type {function} Data fetch function */ | ||||
getDataFn: DataTable.ext.oApi._fnGetObjectDataFn( this.c.dataSrc ), | ||||
/** @type {array} Pixel positions for row insertion calculation */ | ||||
middles: null, | ||||
/** @type {Object} Cached dimension information for use in the mouse move event handler */ | ||||
scroll: {}, | ||||
/** @type {integer} Interval object used for smooth scrolling */ | ||||
scrollInterval: null, | ||||
/** @type {function} Data set function */ | ||||
setDataFn: DataTable.ext.oApi._fnSetObjectDataFn( this.c.dataSrc ), | ||||
/** @type {Object} Mouse down information */ | ||||
start: { | ||||
top: 0, | ||||
left: 0, | ||||
offsetTop: 0, | ||||
offsetLeft: 0, | ||||
nodes: [] | ||||
}, | ||||
/** @type {integer} Window height cached value */ | ||||
windowHeight: 0, | ||||
/** @type {integer} Document outer height cached value */ | ||||
documentOuterHeight: 0, | ||||
/** @type {integer} DOM clone outer height cached value */ | ||||
domCloneOuterHeight: 0 | ||||
}; | ||||
// DOM items | ||||
this.dom = { | ||||
/** @type {jQuery} Cloned row being moved around */ | ||||
clone: null, | ||||
/** @type {jQuery} DataTables scrolling container */ | ||||
dtScroll: $('div.dataTables_scrollBody', this.s.dt.table().container()) | ||||
}; | ||||
// Check if row reorder has already been initialised on this table | ||||
var settings = this.s.dt.settings()[0]; | ||||
var exisiting = settings.rowreorder; | ||||
if ( exisiting ) { | ||||
return exisiting; | ||||
} | ||||
if ( !this.dom.dtScroll.length ) { | ||||
this.dom.dtScroll = $(this.s.dt.table().container(), 'tbody') | ||||
} | ||||
settings.rowreorder = this; | ||||
this._constructor(); | ||||
}; | ||||
$.extend( RowReorder.prototype, { | ||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||||
* Constructor | ||||
*/ | ||||
/** | ||||
* Initialise the RowReorder instance | ||||
* | ||||
* @private | ||||
*/ | ||||
_constructor: function () | ||||
{ | ||||
var that = this; | ||||
var dt = this.s.dt; | ||||
var table = $( dt.table().node() ); | ||||
// Need to be able to calculate the row positions relative to the table | ||||
if ( table.css('position') === 'static' ) { | ||||
table.css( 'position', 'relative' ); | ||||
} | ||||
// listen for mouse down on the target column - we have to implement | ||||
// this rather than using HTML5 drag and drop as drag and drop doesn't | ||||
// appear to work on table rows at this time. Also mobile browsers are | ||||
// not supported. | ||||
// Use `table().container()` rather than just the table node for IE8 - | ||||
// otherwise it only works once... | ||||
$(dt.table().container()).on( 'mousedown.rowReorder touchstart.rowReorder', this.c.selector, function (e) { | ||||
if ( ! that.c.enable ) { | ||||
return; | ||||
} | ||||
// Ignore excluded children of the selector | ||||
if ( $(e.target).is(that.c.excludedChildren) ) { | ||||
return true; | ||||
} | ||||
var tr = $(this).closest('tr'); | ||||
var row = dt.row( tr ); | ||||
// Double check that it is a DataTable row | ||||
if ( row.any() ) { | ||||
that._emitEvent( 'pre-row-reorder', { | ||||
node: row.node(), | ||||
index: row.index() | ||||
} ); | ||||
that._mouseDown( e, tr ); | ||||
return false; | ||||
} | ||||
} ); | ||||
dt.on( 'destroy.rowReorder', function () { | ||||
$(dt.table().container()).off( '.rowReorder' ); | ||||
dt.off( '.rowReorder' ); | ||||
} ); | ||||
}, | ||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||||
* Private methods | ||||
*/ | ||||
/** | ||||
* Cache the measurements that RowReorder needs in the mouse move handler | ||||
* to attempt to speed things up, rather than reading from the DOM. | ||||
* | ||||
* @private | ||||
*/ | ||||
_cachePositions: function () | ||||
{ | ||||
var dt = this.s.dt; | ||||
// Frustratingly, if we add `position:relative` to the tbody, the | ||||
// position is still relatively to the parent. So we need to adjust | ||||
// for that | ||||
var headerHeight = $( dt.table().node() ).find('thead').outerHeight(); | ||||
// Need to pass the nodes through jQuery to get them in document order, | ||||
// not what DataTables thinks it is, since we have been altering the | ||||
// order | ||||
var nodes = $.unique( dt.rows( { page: 'current' } ).nodes().toArray() ); | ||||
var middles = $.map( nodes, function ( node, i ) { | ||||
var top = $(node).position().top - headerHeight; | ||||
return (top + top + $(node).outerHeight() ) / 2; | ||||
} ); | ||||
this.s.middles = middles; | ||||
this.s.bodyTop = $( dt.table().body() ).offset().top; | ||||
this.s.windowHeight = $(window).height(); | ||||
this.s.documentOuterHeight = $(document).outerHeight(); | ||||
}, | ||||
/** | ||||
* Clone a row so it can be floated around the screen | ||||
* | ||||
* @param {jQuery} target Node to be cloned | ||||
* @private | ||||
*/ | ||||
_clone: function ( target ) | ||||
{ | ||||
var dt = this.s.dt; | ||||
var clone = $( dt.table().node().cloneNode(false) ) | ||||
.addClass( 'dt-rowReorder-float' ) | ||||
.append('<tbody/>') | ||||
.append( target.clone( false ) ); | ||||
// Match the table and column widths - read all sizes before setting | ||||
// to reduce reflows | ||||
var tableWidth = target.outerWidth(); | ||||
var tableHeight = target.outerHeight(); | ||||
var sizes = target.children().map( function () { | ||||
return $(this).width(); | ||||
} ); | ||||
clone | ||||
.width( tableWidth ) | ||||
.height( tableHeight ) | ||||
.find('tr').children().each( function (i) { | ||||
this.style.width = sizes[i]+'px'; | ||||
} ); | ||||
// Insert into the document to have it floating around | ||||
clone.appendTo( 'body' ); | ||||
this.dom.clone = clone; | ||||
this.s.domCloneOuterHeight = clone.outerHeight(); | ||||
}, | ||||
/** | ||||
* Update the cloned item's position in the document | ||||
* | ||||
* @param {object} e Event giving the mouse's position | ||||
* @private | ||||
*/ | ||||
_clonePosition: function ( e ) | ||||
{ | ||||
var start = this.s.start; | ||||
var topDiff = this._eventToPage( e, 'Y' ) - start.top; | ||||
var leftDiff = this._eventToPage( e, 'X' ) - start.left; | ||||
var snap = this.c.snapX; | ||||
var left; | ||||
var top = topDiff + start.offsetTop; | ||||
if ( snap === true ) { | ||||
left = start.offsetLeft; | ||||
} | ||||
else if ( typeof snap === 'number' ) { | ||||
left = start.offsetLeft + snap; | ||||
} | ||||
else { | ||||
left = leftDiff + start.offsetLeft; | ||||
} | ||||
if(top < 0) { | ||||
top = 0 | ||||
} | ||||
else if(top + this.s.domCloneOuterHeight > this.s.documentOuterHeight) { | ||||
top = this.s.documentOuterHeight - this.s.domCloneOuterHeight; | ||||
} | ||||
this.dom.clone.css( { | ||||
top: top, | ||||
left: left | ||||
} ); | ||||
}, | ||||
/** | ||||
* Emit an event on the DataTable for listeners | ||||
* | ||||
* @param {string} name Event name | ||||
* @param {array} args Event arguments | ||||
* @private | ||||
*/ | ||||
_emitEvent: function ( name, args ) | ||||
{ | ||||
this.s.dt.iterator( 'table', function ( ctx, i ) { | ||||
$(ctx.nTable).triggerHandler( name+'.dt', args ); | ||||
} ); | ||||
}, | ||||
/** | ||||
* Get pageX/Y position from an event, regardless of if it is a mouse or | ||||
* touch event. | ||||
* | ||||
* @param {object} e Event | ||||
* @param {string} pos X or Y (must be a capital) | ||||
* @private | ||||
*/ | ||||
_eventToPage: function ( e, pos ) | ||||
{ | ||||
if ( e.type.indexOf( 'touch' ) !== -1 ) { | ||||
return e.originalEvent.touches[0][ 'page'+pos ]; | ||||
} | ||||
return e[ 'page'+pos ]; | ||||
}, | ||||
/** | ||||
* Mouse down event handler. Read initial positions and add event handlers | ||||
* for the move. | ||||
* | ||||
* @param {object} e Mouse event | ||||
* @param {jQuery} target TR element that is to be moved | ||||
* @private | ||||
*/ | ||||
_mouseDown: function ( e, target ) | ||||
{ | ||||
var that = this; | ||||
var dt = this.s.dt; | ||||
var start = this.s.start; | ||||
var offset = target.offset(); | ||||
start.top = this._eventToPage( e, 'Y' ); | ||||
start.left = this._eventToPage( e, 'X' ); | ||||
start.offsetTop = offset.top; | ||||
start.offsetLeft = offset.left; | ||||
start.nodes = $.unique( dt.rows( { page: 'current' } ).nodes().toArray() ); | ||||
this._cachePositions(); | ||||
this._clone( target ); | ||||
this._clonePosition( e ); | ||||
this.dom.target = target; | ||||
target.addClass( 'dt-rowReorder-moving' ); | ||||
$( document ) | ||||
.on( 'mouseup.rowReorder touchend.rowReorder', function (e) { | ||||
that._mouseUp(e); | ||||
} ) | ||||
.on( 'mousemove.rowReorder touchmove.rowReorder', function (e) { | ||||
that._mouseMove(e); | ||||
} ); | ||||
// Check if window is x-scrolling - if not, disable it for the duration | ||||
// of the drag | ||||
if ( $(window).width() === $(document).width() ) { | ||||
$(document.body).addClass( 'dt-rowReorder-noOverflow' ); | ||||
} | ||||
// Cache scrolling information so mouse move doesn't need to read. | ||||
// This assumes that the window and DT scroller will not change size | ||||
// during an row drag, which I think is a fair assumption | ||||
var scrollWrapper = this.dom.dtScroll; | ||||
this.s.scroll = { | ||||
windowHeight: $(window).height(), | ||||
windowWidth: $(window).width(), | ||||
dtTop: scrollWrapper.length ? scrollWrapper.offset().top : null, | ||||
dtLeft: scrollWrapper.length ? scrollWrapper.offset().left : null, | ||||
dtHeight: scrollWrapper.length ? scrollWrapper.outerHeight() : null, | ||||
dtWidth: scrollWrapper.length ? scrollWrapper.outerWidth() : null | ||||
}; | ||||
}, | ||||
/** | ||||
* Mouse move event handler - move the cloned row and shuffle the table's | ||||
* rows if required. | ||||
* | ||||
* @param {object} e Mouse event | ||||
* @private | ||||
*/ | ||||
_mouseMove: function ( e ) | ||||
{ | ||||
this._clonePosition( e ); | ||||
// Transform the mouse position into a position in the table's body | ||||
var bodyY = this._eventToPage( e, 'Y' ) - this.s.bodyTop; | ||||
var middles = this.s.middles; | ||||
var insertPoint = null; | ||||
var dt = this.s.dt; | ||||
// Determine where the row should be inserted based on the mouse | ||||
// position | ||||
for ( var i=0, ien=middles.length ; i<ien ; i++ ) { | ||||
if ( bodyY < middles[i] ) { | ||||
insertPoint = i; | ||||
break; | ||||
} | ||||
} | ||||
if ( insertPoint === null ) { | ||||
insertPoint = middles.length; | ||||
} | ||||
// Perform the DOM shuffle if it has changed from last time | ||||
if ( this.s.lastInsert === null || this.s.lastInsert !== insertPoint ) { | ||||
var nodes = $.unique( dt.rows( { page: 'current' } ).nodes().toArray() ); | ||||
if ( insertPoint > this.s.lastInsert ) { | ||||
this.dom.target.insertAfter( nodes[ insertPoint-1 ] ); | ||||
} | ||||
else { | ||||
this.dom.target.insertBefore( nodes[ insertPoint ] ); | ||||
} | ||||
this._cachePositions(); | ||||
this.s.lastInsert = insertPoint; | ||||
} | ||||
this._shiftScroll( e ); | ||||
}, | ||||
/** | ||||
* Mouse up event handler - release the event handlers and perform the | ||||
* table updates | ||||
* | ||||
* @param {object} e Mouse event | ||||
* @private | ||||
*/ | ||||
_mouseUp: function ( e ) | ||||
{ | ||||
var that = this; | ||||
var dt = this.s.dt; | ||||
var i, ien; | ||||
var dataSrc = this.c.dataSrc; | ||||
this.dom.clone.remove(); | ||||
this.dom.clone = null; | ||||
this.dom.target.removeClass( 'dt-rowReorder-moving' ); | ||||
//this.dom.target = null; | ||||
$(document).off( '.rowReorder' ); | ||||
$(document.body).removeClass( 'dt-rowReorder-noOverflow' ); | ||||
clearInterval( this.s.scrollInterval ); | ||||
this.s.scrollInterval = null; | ||||
// Calculate the difference | ||||
var startNodes = this.s.start.nodes; | ||||
var endNodes = $.unique( dt.rows( { page: 'current' } ).nodes().toArray() ); | ||||
var idDiff = {}; | ||||
var fullDiff = []; | ||||
var diffNodes = []; | ||||
var getDataFn = this.s.getDataFn; | ||||
var setDataFn = this.s.setDataFn; | ||||
for ( i=0, ien=startNodes.length ; i<ien ; i++ ) { | ||||
if ( startNodes[i] !== endNodes[i] ) { | ||||
var id = dt.row( endNodes[i] ).id(); | ||||
var endRowData = dt.row( endNodes[i] ).data(); | ||||
var startRowData = dt.row( startNodes[i] ).data(); | ||||
if ( id ) { | ||||
idDiff[ id ] = getDataFn( startRowData ); | ||||
} | ||||
fullDiff.push( { | ||||
node: endNodes[i], | ||||
oldData: getDataFn( endRowData ), | ||||
newData: getDataFn( startRowData ), | ||||
newPosition: i, | ||||
oldPosition: $.inArray( endNodes[i], startNodes ) | ||||
} ); | ||||
diffNodes.push( endNodes[i] ); | ||||
} | ||||
} | ||||
// Create event args | ||||
var eventArgs = [ fullDiff, { | ||||
dataSrc: dataSrc, | ||||
nodes: diffNodes, | ||||
values: idDiff, | ||||
triggerRow: dt.row( this.dom.target ), | ||||
originalEvent: e | ||||
} ]; | ||||
// Emit event | ||||
this._emitEvent( 'row-reorder', eventArgs ); | ||||
var update = function () { | ||||
if ( that.c.update ) { | ||||
for ( i=0, ien=fullDiff.length ; i<ien ; i++ ) { | ||||
var row = dt.row( fullDiff[i].node ); | ||||
var rowData = row.data(); | ||||
setDataFn( rowData, fullDiff[i].newData ); | ||||
// Invalidate the cell that has the same data source as the dataSrc | ||||
dt.columns().every( function () { | ||||
if ( this.dataSrc() === dataSrc ) { | ||||
dt.cell( fullDiff[i].node, this.index() ).invalidate( 'data' ); | ||||
} | ||||
} ); | ||||
} | ||||
// Trigger row reordered event | ||||
that._emitEvent( 'row-reordered', eventArgs ); | ||||
dt.draw( false ); | ||||
} | ||||
}; | ||||
// Editor interface | ||||
if ( this.c.editor ) { | ||||
// Disable user interaction while Editor is submitting | ||||
this.c.enable = false; | ||||
this.c.editor | ||||
.edit( | ||||
diffNodes, | ||||
false, | ||||
$.extend( {submit: 'changed'}, this.c.formOptions ) | ||||
) | ||||
.multiSet( dataSrc, idDiff ) | ||||
.one( 'preSubmitCancelled.rowReorder', function () { | ||||
that.c.enable = true; | ||||
that.c.editor.off( '.rowReorder' ); | ||||
dt.draw( false ); | ||||
} ) | ||||
.one( 'submitUnsuccessful.rowReorder', function () { | ||||
dt.draw( false ); | ||||
} ) | ||||
.one( 'submitSuccess.rowReorder', function () { | ||||
update(); | ||||
} ) | ||||
.one( 'submitComplete', function () { | ||||
that.c.enable = true; | ||||
that.c.editor.off( '.rowReorder' ); | ||||
} ) | ||||
.submit(); | ||||
} | ||||
else { | ||||
update(); | ||||
} | ||||
}, | ||||
/** | ||||
* Move the window and DataTables scrolling during a drag to scroll new | ||||
* content into view. | ||||
* | ||||
* This matches the `_shiftScroll` method used in AutoFill, but only | ||||
* horizontal scrolling is considered here. | ||||
* | ||||
* @param {object} e Mouse move event object | ||||
* @private | ||||
*/ | ||||
_shiftScroll: function ( e ) | ||||
{ | ||||
var that = this; | ||||
var dt = this.s.dt; | ||||
var scroll = this.s.scroll; | ||||
var runInterval = false; | ||||
var scrollSpeed = 5; | ||||
var buffer = 65; | ||||
var | ||||
windowY = e.pageY - document.body.scrollTop, | ||||
windowVert, | ||||
dtVert; | ||||
// Window calculations - based on the mouse position in the window, | ||||
// regardless of scrolling | ||||
if ( windowY < $(window).scrollTop() + buffer ) { | ||||
windowVert = scrollSpeed * -1; | ||||
} | ||||
else if ( windowY > scroll.windowHeight + $(window).scrollTop() - buffer ) { | ||||
windowVert = scrollSpeed; | ||||
} | ||||
// DataTables scrolling calculations - based on the table's position in | ||||
// the document and the mouse position on the page | ||||
if ( scroll.dtTop !== null && e.pageY < scroll.dtTop + buffer ) { | ||||
dtVert = scrollSpeed * -1; | ||||
} | ||||
else if ( scroll.dtTop !== null && e.pageY > scroll.dtTop + scroll.dtHeight - buffer ) { | ||||
dtVert = scrollSpeed; | ||||
} | ||||
// This is where it gets interesting. We want to continue scrolling | ||||
// without requiring a mouse move, so we need an interval to be | ||||
// triggered. The interval should continue until it is no longer needed, | ||||
// but it must also use the latest scroll commands (for example consider | ||||
// that the mouse might move from scrolling up to scrolling left, all | ||||
// with the same interval running. We use the `scroll` object to "pass" | ||||
// this information to the interval. Can't use local variables as they | ||||
// wouldn't be the ones that are used by an already existing interval! | ||||
if ( windowVert || dtVert ) { | ||||
scroll.windowVert = windowVert; | ||||
scroll.dtVert = dtVert; | ||||
runInterval = true; | ||||
} | ||||
else if ( this.s.scrollInterval ) { | ||||
// Don't need to scroll - remove any existing timer | ||||
clearInterval( this.s.scrollInterval ); | ||||
this.s.scrollInterval = null; | ||||
} | ||||
// If we need to run the interval to scroll and there is no existing | ||||
// interval (if there is an existing one, it will continue to run) | ||||
if ( ! this.s.scrollInterval && runInterval ) { | ||||
this.s.scrollInterval = setInterval( function () { | ||||
// Don't need to worry about setting scroll <0 or beyond the | ||||
// scroll bound as the browser will just reject that. | ||||
if ( scroll.windowVert ) { | ||||
var top = $(document).scrollTop(); | ||||
$(document).scrollTop(top + scroll.windowVert); | ||||
if ( top !== $(document).scrollTop() ) { | ||||
var move = parseFloat(that.dom.clone.css("top")); | ||||
that.dom.clone.css("top", move + scroll.windowVert); | ||||
} | ||||
} | ||||
// DataTables scrolling | ||||
if ( scroll.dtVert ) { | ||||
var scroller = that.dom.dtScroll[0]; | ||||
if ( scroll.dtVert ) { | ||||
scroller.scrollTop += scroll.dtVert; | ||||
} | ||||
} | ||||
}, 20 ); | ||||
} | ||||
} | ||||
} ); | ||||
/** | ||||
* RowReorder default settings for initialisation | ||||
* | ||||
* @namespace | ||||
* @name RowReorder.defaults | ||||
* @static | ||||
*/ | ||||
RowReorder.defaults = { | ||||
/** | ||||
* Data point in the host row's data source object for where to get and set | ||||
* the data to reorder. This will normally also be the sorting column. | ||||
* | ||||
* @type {Number} | ||||
*/ | ||||
dataSrc: 0, | ||||
/** | ||||
* Editor instance that will be used to perform the update | ||||
* | ||||
* @type {DataTable.Editor} | ||||
*/ | ||||
editor: null, | ||||
/** | ||||
* Enable / disable RowReorder's user interaction | ||||
* @type {Boolean} | ||||
*/ | ||||
enable: true, | ||||
/** | ||||
* Form options to pass to Editor when submitting a change in the row order. | ||||
* See the Editor `from-options` object for details of the options | ||||
* available. | ||||
* @type {Object} | ||||
*/ | ||||
formOptions: {}, | ||||
/** | ||||
* Drag handle selector. This defines the element that when dragged will | ||||
* reorder a row. | ||||
* | ||||
* @type {String} | ||||
*/ | ||||
selector: 'td:first-child', | ||||
/** | ||||
* Optionally lock the dragged row's x-position. This can be `true` to | ||||
* fix the position match the host table's, `false` to allow free movement | ||||
* of the row, or a number to define an offset from the host table. | ||||
* | ||||
* @type {Boolean|number} | ||||
*/ | ||||
snapX: false, | ||||
/** | ||||
* Update the table's data on drop | ||||
* | ||||
* @type {Boolean} | ||||
*/ | ||||
update: true, | ||||
/** | ||||
* Selector for children of the drag handle selector that mouseDown events | ||||
* will be passed through to and drag will not activate | ||||
* | ||||
* @type {String} | ||||
*/ | ||||
excludedChildren: 'a' | ||||
}; | ||||
/* | ||||
* API | ||||
*/ | ||||
var Api = $.fn.dataTable.Api; | ||||
// Doesn't do anything - work around for a bug in DT... Not documented | ||||
Api.register( 'rowReorder()', function () { | ||||
return this; | ||||
} ); | ||||
Api.register( 'rowReorder.enable()', function ( toggle ) { | ||||
if ( toggle === undefined ) { | ||||
toggle = true; | ||||
} | ||||
return this.iterator( 'table', function ( ctx ) { | ||||
if ( ctx.rowreorder ) { | ||||
ctx.rowreorder.c.enable = toggle; | ||||
} | ||||
} ); | ||||
} ); | ||||
Api.register( 'rowReorder.disable()', function () { | ||||
return this.iterator( 'table', function ( ctx ) { | ||||
if ( ctx.rowreorder ) { | ||||
ctx.rowreorder.c.enable = false; | ||||
} | ||||
} ); | ||||
} ); | ||||
/** | ||||
* Version information | ||||
* | ||||
* @name RowReorder.version | ||||
* @static | ||||
*/ | ||||
RowReorder.version = '1.2.8'; | ||||
$.fn.dataTable.RowReorder = RowReorder; | ||||
$.fn.DataTable.RowReorder = RowReorder; | ||||
// Attach a listener to the document which listens for DataTables initialisation | ||||
// events so we can automatically initialise | ||||
$(document).on( 'init.dt.dtr', function (e, settings, json) { | ||||
if ( e.namespace !== 'dt' ) { | ||||
return; | ||||
} | ||||
var init = settings.oInit.rowReorder; | ||||
var defaults = DataTable.defaults.rowReorder; | ||||
if ( init || defaults ) { | ||||
var opts = $.extend( {}, init, defaults ); | ||||
if ( init !== false ) { | ||||
new RowReorder( settings, opts ); | ||||
} | ||||
} | ||||
} ); | ||||
return RowReorder; | ||||
})); | ||||