2015-10-31 16:06:09 +00:00
/*! Dragtable Mod for TableSorter - updated 10/31/2015 (v2.24.0) */
2015-10-31 15:08:21 +00:00
/ *
* Requires
* tablesorter v2 . 8 +
* jQuery 1.7 +
* jQuery UI ( Core , Widget , Mouse & Sortable )
* Dragtable by Akottr ( https : //github.com/akottr) modified by Rob Garrison
* /
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
! function ( a ) { "use strict" ;
// css properties to disable user-select on the body tag by appending a <style> tag to the <head>
// remove any current document selections
function b ( ) {
// jQuery doesn't support the element.text attribute in MSIE 8
// http://stackoverflow.com/questions/2692770/style-style-textcss-appendtohead-does-not-work-in-ie
var b = a ( '<style id="__dragtable_disable_text_selection__" type="text/css">body { -ms-user-select:none;-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;user-select:none; }</style>' ) ; a ( document . head ) . append ( b ) , a ( document . body ) . attr ( "onselectstart" , "return false;" ) . attr ( "unselectable" , "on" ) , window . getSelection ? window . getSelection ( ) . removeAllRanges ( ) : document . selection . empty ( ) }
// remove the <style> tag, and restore the original <body> onselectstart attribute
function c ( ) { a ( "#__dragtable_disable_text_selection__" ) . remove ( ) , f ? a ( document . body ) . attr ( "onselectstart" , f ) : a ( document . body ) . removeAttr ( "onselectstart" ) , g ? a ( document . body ) . attr ( "unselectable" , g ) : a ( document . body ) . removeAttr ( "unselectable" ) } var d , e = a . tablesorter ; e . dragtable = { create : function ( b ) { var c , d = b . originalTable . el , e = b . options . dragHandle . replace ( "." , "" ) ; d . children ( "thead" ) . children ( ) . children ( "th,td" ) . each ( function ( ) { var d = a ( this ) ; d . find ( b . options . dragHandle + ",." + e + "-disabled" ) . length || ( c = b . options . dragaccept ? d . hasClass ( b . options . dragaccept . replace ( "." , "" ) ) : ! 0 , d . wrapInner ( '<div class="' + b . options . sortClass . replace ( "." , "" ) + '"/>' ) . prepend ( '<div class="' + e + ( c ? "" : "-disabled" ) + '"></div>' ) ) } ) } , start : function ( b ) { b = a ( b ) [ 0 ] , b && b . config && ( b . config . widgetOptions . dragtableLast = { search : a ( b ) . data ( "lastSearch" ) , order : e . dragtable . getOrder ( b ) } ) } , update : function ( b ) { var c , d , f , g = b . originalTable , h = g . el [ 0 ] , i = a ( h ) , j = h . config , k = j && j . widgetOptions , l = g . startIndex - 1 , m = g . endIndex - 1 , n = e . dragtable . getOrder ( h ) || [ ] , o = e . hasWidget ( i , "filter" ) || ! 1 , p = k && k . dragtableLast || { } ,
// update moved filters
q = [ ] ;
// only trigger updateAll if column order changed
( p . order || [ ] ) . join ( "" ) !== n . join ( "" ) && ( j . sortList . length && ( d = a . extend ( ! 0 , [ ] , j . sortList ) , a . each ( n , function ( a , b ) { f = e . isValueInArray ( parseInt ( b , 10 ) , d ) , b !== p . order [ a ] && f >= 0 && ( j . sortList [ f ] [ 0 ] = a ) } ) ) ,
// update filter widget
o && a . each ( p . search || [ ] , function ( a ) { q [ a ] = p . search [ n [ a ] ] } ) , c = e . hasWidget ( j . $table , "editable" ) ? k . editable _columnsArray : ! 1 , c && ( j . widgetOptions . editable _columnsArray = e . dragtable . reindexArrayItem ( c , l , m ) ) , c = e . hasWidget ( j . $table , "math" ) ? k . math _ignore : ! 1 , c && ( j . widgetOptions . math _ignore = e . dragtable . reindexArrayItem ( c , l , m ) ) , c = e . hasWidget ( j . $table , "resizable" ) ? k . resizable _widths : ! 1 , c && ( k . resizable _widths = e . dragtable . moveArrayItem ( c , l , m ) ) , e . updateAll ( j , ! 1 , function ( ) { o && setTimeout ( function ( ) { j . lastCombinedFilter = null , j . $table . data ( "lastSearch" , q ) , e . setFilters ( i , q ) , a . isFunction ( b . options . tablesorterComplete ) && b . options . tablesorterComplete ( j . table ) } , 10 ) } ) ) } , getOrder : function ( b ) { return a ( b ) . children ( "thead" ) . children ( "." + e . css . headerRow ) . children ( ) . map ( function ( ) { return a ( this ) . attr ( "data-column" ) } ) . get ( ) || [ ] } ,
// bubble the moved col left or right
startColumnMove : function ( b ) { var c , d = b . el [ 0 ] . config , e = b . startIndex - 1 , f = b . endIndex - 1 , g = d . columns - 1 , h = f === g ? ! 1 : e >= f , i = d . $table . children ( ) . children ( "tr" ) ; d . debug && console . log ( "Inserting column " + e + ( h ? " before" : " after" ) + " column " + f ) , i . each ( function ( ) { c = a ( this ) . children ( ) , c . eq ( e ) [ h ? "insertBefore" : "insertAfter" ] ( c . eq ( f ) ) } ) , c = d . $table . children ( "colgroup" ) . children ( ) , c . eq ( e ) [ h ? "insertBefore" : "insertAfter" ] ( c . eq ( f ) ) } , swapNodes : function ( a , b ) { var c , d , e , f = a . length ; for ( c = 0 ; f > c ; c ++ ) d = a [ c ] . parentNode , e = a [ c ] . nextSibling === b [ c ] ? a [ c ] : a [ c ] . nextSibling , b [ c ] . parentNode . insertBefore ( a [ c ] , b [ c ] ) , d . insertBefore ( b [ c ] , e ) } ,
// http://stackoverflow.com/a/5306832/145346
moveArrayItem : function ( a , b , c ) { var e , f = a . length ; if ( c >= f ) for ( e = c - f ; e -- + 1 ; ) a . push ( d ) ; return a . splice ( c , 0 , a . splice ( b , 1 ) [ 0 ] ) , a } , reindexArrayItem : function ( b , c , d ) { var e = a . inArray ( d , b ) , f = a . inArray ( c , b ) , g = ( Math . max . apply ( Math , b ) , [ ] ) ;
// columns in the array were swapped so return original array
// columns in the array were swapped so return original array
// columns not in the array were moved
return e >= 0 && f >= 0 ? b : ( a . each ( b , function ( a , b ) {
// column (not in array) inserted between indexes
c > d ?
// ( [ 0,1,2,3 ], 5, 1 ) -> column inserted between 0 & 1 => [ 0,2,3,4 ]
b >= d ?
// 5 -> 1 [ 0, 2, 3 ] then 1 -> 0 [ 1, 2, 3 ]
g . push ( b + ( c > b ? 1 : 0 ) ) : g . push ( b ) : d > c && ( b === c ? g . push ( d ) : d > b && b >= c ? g . push ( b - 1 ) : d >= b ? g . push ( b ) : b > c && g . push ( b + ( d > b ? 0 : 1 ) ) ) } ) , g . sort ( ) ) } } , /*! dragtable v2.0.14 Mod */
/ *
* _ _ _ _ _ _
* | | _ _ _ _ | |
* | | | | . | . |
* | _ | _ | _ | _ _ _ | _ _ _ |
*
* Copyright ( c ) 2010 - 2013 , Andres akottr @ gmail . com
* Dual licensed under the MIT ( MIT - LICENSE . txt )
* and GPL ( GPL - LICENSE . txt ) licenses .
*
* Inspired by the the dragtable from Dan Vanderkam ( danvk . org / dragtable / )
* Thanks to the jquery and jqueryui comitters
*
* Any comment , bug report , feature - request is welcome
* Feel free to contact me .
* /
/ * T O K N O W :
* For IE7 you need this css rule :
* table {
* border - collapse : collapse ;
* }
* Or take a clean reset . css ( see http : //meyerweb.com/eric/tools/css/reset/)
* /
/ * T O D O : i n v e s t i g a t e
* Does not work properly with css rule :
* html {
* overflow : - moz - scrollbars - vertical ;
* }
* Workaround :
* Fixing Firefox issues by scrolling down the page
* http : //stackoverflow.com/questions/2451528/jquery-ui-sortable-scroll-helper-element-offset-firefox-issue
*
* var start = $ . noop ;
* var beforeStop = $ . noop ;
* if ( $ . browser . mozilla ) {
* var start = function ( event , ui ) {
* if ( ui . helper !== undefined )
* ui . helper . css ( 'position' , 'absolute' ) . css ( 'margin-top' , $ ( window ) . scrollTop ( ) ) ;
* }
* var beforeStop = function ( event , ui ) {
* if ( ui . offset !== undefined )
* ui . helper . css ( 'margin-top' , 0 ) ;
* }
* }
*
* and pass this as start and stop function to the sortable initialisation
* start : start ,
* beforeStop : beforeStop
* /
/ *
* Special thx to all pull requests comitters
* /
a . widget ( "akottr.dragtable" , { options : { revert : ! 1 , // smooth revert
dragHandle : ".table-handle" , // handle for moving cols, if not exists the whole 'th' is the handle
maxMovingRows : 40 , // 1 -> only header. 40 row should be enough, the rest is usually not in the viewport
excludeFooter : ! 1 , // excludes the footer row(s) while moving other columns. Make sense if there is a footer with a colspan. */
onlyHeaderThreshold : 100 , // TODO: not implemented yet, switch automatically between entire col moving / only header moving
dragaccept : null , // draggable cols -> default all
persistState : null , // url or function -> plug in your custom persistState function right here. function call is persistState(originalTable)
restoreState : null , // JSON-Object or function: some kind of experimental aka Quick-Hack TODO: do it better
exact : ! 0 , // removes pixels, so that the overlay table width fits exactly the original table width
clickDelay : 10 , // ms to wait before rendering sortable list and delegating click event
containment : null , // @see http://api.jqueryui.com/sortable/#option-containment, use it if you want to move in 2 dimesnions (together with axis: null)
cursor : "move" , // @see http://api.jqueryui.com/sortable/#option-cursor
cursorAt : ! 1 , // @see http://api.jqueryui.com/sortable/#option-cursorAt
distance : 0 , // @see http://api.jqueryui.com/sortable/#option-distance, for immediate feedback use "0"
tolerance : "pointer" , // @see http://api.jqueryui.com/sortable/#option-tolerance
axis : "x" , // @see http://api.jqueryui.com/sortable/#option-axis, Only vertical moving is allowed. Use 'x' or null. Use this in conjunction with the 'containment' setting
beforeStart : a . noop , // returning FALSE will stop the execution chain.
beforeMoving : a . noop , beforeReorganize : a . noop , beforeStop : a . noop ,
// new options
tablesorterComplete : null , sortClass : ".sorter" } , originalTable : { el : null , selectedHandle : null , sortOrder : null , startIndex : 0 , endIndex : 0 } , sortableTable : { el : a ( ) , selectedHandle : a ( ) , movingRow : a ( ) } , persistState : function ( ) { var b = this ; this . originalTable . el . find ( "th" ) . each ( function ( a ) { "" !== this . id && ( b . originalTable . sortOrder [ this . id ] = a ) } ) , a . ajax ( { url : this . options . persistState , data : this . originalTable . sortOrder } ) } , / *
* persistObj looks like
* { 'id1' : '2' , 'id3' : '3' , 'id2' : '1' }
* table looks like
* | id2 | id1 | id3 |
* /
_restoreState : function ( b ) { for ( var c in b ) c in b && ( this . originalTable . startIndex = a ( "#" + c ) . closest ( "th" ) . prevAll ( ) . length + 1 , this . originalTable . endIndex = parseInt ( b [ c ] , 10 ) + 1 , this . _bubbleCols ( ) ) } ,
// bubble the moved col left or right
_bubbleCols : function ( ) { e . dragtable . startColumnMove ( this . originalTable ) } , _rearrangeTableBackroundProcessing : function ( ) { var b = this ; return function ( ) { b . _bubbleCols ( ) , b . options . beforeStop ( b . originalTable ) , b . sortableTable . el . remove ( ) , c ( ) , e . dragtable . update ( b ) ,
// persist state if necessary
a . isFunction ( b . options . persistState ) ? b . options . persistState ( b . originalTable ) : b . persistState ( ) } } , _rearrangeTable : function ( ) { var a = this ; return function ( ) {
// remove handler-class -> handler is now finished
a . originalTable . selectedHandle . removeClass ( "dragtable-handle-selected" ) ,
// add disabled class -> reorgorganisation starts soon
a . sortableTable . el . sortable ( "disable" ) , a . sortableTable . el . addClass ( "dragtable-disabled" ) , a . options . beforeReorganize ( a . originalTable , a . sortableTable ) ,
// do reorganisation asynchronous
// for chrome a little bit more than 1 ms because we want to force a rerender
a . originalTable . endIndex = a . sortableTable . movingRow . prevAll ( ) . length + 1 , setTimeout ( a . _rearrangeTableBackroundProcessing ( ) , 50 ) } } , / *
* Disrupts the table . The original table stays the same .
* But on a layer above the original table we are constructing a list ( ul > li )
* each li with a separate table representig a single col of the original table .
* /
_generateSortable : function ( c ) { c . cancelBubble ? c . cancelBubble = ! 0 : c . stopPropagation ( ) ; for ( var d = this , e = this . originalTable . el [ 0 ] . attributes , f = "" , g = 0 ; g < e . length ; g ++ ) ( e [ g ] . value || e [ g ] . nodeValue ) && "id" != e [ g ] . nodeName && "width" != e [ g ] . nodeName && ( f += e [ g ] . nodeName + '="' + ( e [ g ] . value || e [ g ] . nodeValue ) + '" ' ) ;
// row attributes
var h = [ ] , i = [ ] ;
// don't save tfoot attributes because it messes up indexing
d . originalTable . el . children ( "thead, tbody" ) . children ( "tr:visible" ) . slice ( 0 , d . options . maxMovingRow ) . each ( function ( ) { for ( var b = this . attributes , c = "" , d = 0 ; d < b . length ; d ++ ) ( b [ d ] . value || b [ d ] . nodeValue ) && "id" != b [ d ] . nodeName && ( c += " " + b [ d ] . nodeName + '="' + ( b [ d ] . value || b [ d ] . nodeValue ) + '"' ) ; h . push ( c ) , i . push ( a ( this ) . height ( ) ) } ) ;
// compute width, no special handling for ie needed :-)
var j = [ ] , k = 0 , l = d . originalTable . el . children ( ) , m = l . filter ( "thead" ) . children ( "tr:visible" ) , n = l . filter ( "tbody" ) . children ( "tr:visible" ) ; if ( m . eq ( 0 ) . children ( "th, td" ) . filter ( ":visible" ) . each ( function ( ) { var b = a ( this ) . outerWidth ( ) ; j . push ( b ) , k += b } ) , d . options . exact ) { var o = k - d . originalTable . el . outerWidth ( ) ; j [ 0 ] -= o }
// one extra px on right and left side
k += 2 ; var p = 0 ; l . filter ( "caption" ) . each ( function ( ) { p += a ( this ) . outerHeight ( ) } ) ; var q , r = '<ul class="dragtable-sortable" style="position:absolute; width:' + k + 'px;">' , s = [ ] , t = m . eq ( 0 ) . children ( "th, td" ) . length ; /*jshint loopfunc:true */
for ( g = 0 ; t > g ; g ++ ) { var u = m . children ( ":nth-child(" + ( g + 1 ) + ")" ) ; u . is ( ":visible" ) && ( q = 0 , s [ g ] = '<li style="width:' + u . outerWidth ( ) + 'px;"><table ' + f + ">" + ( p ? '<caption style="height:' + p + 'px;"></caption>' : "" ) + "<thead>" , m . each ( function ( a ) { s [ g ] += "<tr " + h [ q ++ ] + ( i [ a ] ? ' style="height:' + i [ a ] + 'px;"' : "" ) + ">" + u [ a ] . outerHTML + "</tr>" } ) , s [ g ] += "</thead><tbody>" , u = n . children ( ":nth-child(" + ( g + 1 ) + ")" ) , d . options . maxMovingRows > 1 && ( u = u . add ( n . children ( ":nth-child(" + ( g + 1 ) + ")" ) . slice ( 0 , d . options . maxMovingRows - 1 ) ) ) , u . each ( function ( a ) { s [ g ] += "<tr " + h [ q ++ ] + ( i [ a ] ? ' style="height:' + i [ a ] + 'px;"' : "" ) + ">" + this . outerHTML + "</tr>" } ) , s [ g ] += "</tbody>" , d . options . excludeFooter || ( s [ g ] += "<tfoot><tr " + h [ q ++ ] + ">" + l . filter ( "tfoot" ) . children ( "tr:visible" ) . children ( ) [ g ] . outerHTML + "</tr></tfoot>" ) , s [ g ] += "</table></li>" ) } r += s . join ( "" ) + "</ul>" , this . sortableTable . el = this . originalTable . el . before ( r ) . prev ( ) , this . sortableTable . el . find ( "> li > table" ) . each ( function ( b ) { a ( this ) . css ( "width" , j [ b ] + "px" ) } ) , this . sortableTable . selectedHandle = this . sortableTable . el . find ( "th .dragtable-handle-selected" ) ; var v = this . options . dragaccept ? "li:has(" + this . options . dragaccept + ")" : "li" ; this . sortableTable . el . sortable ( { items : v , stop : this . _rearrangeTable ( ) ,
// pass thru options for sortable widget
revert : this . options . revert , tolerance : this . options . tolerance , containment : this . options . containment , cursor : this . options . cursor , cursorAt : this . options . cursorAt , distance : this . options . distance , axis : this . options . axis } ) ,
// assign start index
this . originalTable . startIndex = a ( c . target ) . closest ( "th,td" ) . prevAll ( ) . length + 1 , this . options . beforeMoving ( this . originalTable , this . sortableTable ) ,
// Start moving by delegating the original event to the new sortable table
this . sortableTable . movingRow = this . sortableTable . el . children ( "li:nth-child(" + this . originalTable . startIndex + ")" ) ,
// prevent the user from drag selecting "highlighting" surrounding page elements
b ( ) ,
// clone the initial event and trigger the sort with it
this . sortableTable . movingRow . trigger ( a . extend ( a . Event ( c . type ) , { which : 1 , clientX : c . clientX , clientY : c . clientY , pageX : c . pageX , pageY : c . pageY , screenX : c . screenX , screenY : c . screenY } ) ) ;
// Some inner divs to deliver the posibillity to style the placeholder more sophisticated
var w = this . sortableTable . el . find ( ".ui-sortable-placeholder" ) ; w . height ( ) > 0 && w . css ( "height" , this . sortableTable . el . find ( ".ui-sortable-helper" ) . height ( ) ) , w . html ( '<div class="outer" style="height:100%;"><div class="inner" style="height:100%;"></div></div>' ) } , bindTo : { } , _create : function ( ) { var b = this ; b . originalTable = { el : b . element , selectedHandle : a ( ) , sortOrder : { } , startIndex : 0 , endIndex : 0 } , e . dragtable . create ( b ) ,
// filter only the cols that are accepted
b . bindTo = "> thead > tr > " + ( b . options . dragaccept || "th, td" ) ,
// bind draggable to handle if exists
b . element . find ( b . bindTo ) . find ( b . options . dragHandle ) . length && ( b . bindTo += " " + b . options . dragHandle ) ,
// restore state if necessary
a . isFunction ( b . options . restoreState ) ? b . options . restoreState ( b . originalTable ) : b . _restoreState ( b . options . restoreState ) , b . originalTable . el . on ( "mousedown.dragtable" , b . bindTo , function ( c ) {
// listen only to left mouse click
1 === c . which && ( e . dragtable . start ( b . originalTable . el ) , b . options . beforeStart ( b . originalTable ) !== ! 1 && ( clearTimeout ( b . downTimer ) , b . downTimer = setTimeout ( function ( ) { b . originalTable . selectedHandle = a ( b ) , b . originalTable . selectedHandle . addClass ( "dragtable-handle-selected" ) , b . _generateSortable ( c ) } , b . options . clickDelay ) ) ) } ) . on ( "mouseup.dragtable" , b . options . dragHandle , function ( ) { clearTimeout ( b . downTimer ) } ) } , redraw : function ( ) { this . destroy ( ) , this . _create ( ) } , destroy : function ( ) { this . originalTable . el . off ( "mousedown.dragtable mouseup.dragtable" , this . bindTo ) , a . Widget . prototype . destroy . apply ( this , arguments ) } } ) ; /** closure-scoped "private" functions **/
var f = a ( document . body ) . attr ( "onselectstart" ) , g = a ( document . body ) . attr ( "unselectable" ) } ( jQuery ) ;