tablesorter/beta-testing/widget-reorder.js
2018-03-18 09:18:20 -05:00

182 lines
5.4 KiB
JavaScript

/*! tablesorter column reorder - beta testing
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($) {
'use strict';
$.tablesorter.addWidget({
id: 'reorder',
priority: 70,
options : {
reorder_axis : 'xy', // x or xy
reorder_delay : 300,
reorder_helperClass : 'tablesorter-reorder-helper',
reorder_helperBar : 'tablesorter-reorder-helper-bar',
reorder_noReorder : 'reorder-false',
reorder_blocked : 'reorder-block-left reorder-block-end',
reorder_complete : null // callback
},
init: function(table, thisWidget, c, wo) {
var i, timer, $helper, $bar, clickOffset,
lastIndx = -1,
endIndex = -1,
startIndex = -1,
t = wo.reorder_blocked.split(' '),
noReorderLeft = t[0] || 'reorder-block-left',
noReorderLast = t[1] || 'reorder-block-end',
lastOffset = c.$headers.not('.' + noReorderLeft).first(),
offsets = c.$headers.map(function() {
var s, $t = $(this);
if ($t.hasClass(noReorderLeft)) {
s = lastOffset;
$t = s;
//lastOffset = $t;
}
lastOffset = $t;
return $t.offset().left;
}).get(),
len = offsets.length,
startReorder = function(e, $th) {
var p = $th.position(),
r = $th.parent().position(),
i = startIndex = $th.index();
clickOffset = [ e.pageX - p.left, e.pageY - r.top ];
$helper = c.$table.clone();
$helper.find('> thead > tr:first').children('[data-column!=' + i + ']').remove();
$helper.find('thead tr:gt(0), caption, colgroup, tbody, tfoot').remove();
$helper
.css({
position: 'absolute',
zIndex : 1,
left: p.left - clickOffset[0],
top: r.top - clickOffset[1],
width: $th.outerWidth()
})
.appendTo('head')
.find('th, td').addClass(wo.reorder_helperClass);
$bar = $('<div class="' + wo.reorder_helperBar + '" />')
.css({
position : 'absolute',
top : c.$table.find('thead').offset().top,
height : $th.closest('thead').outerHeight() + c.$table.find('tbody').height()
})
.appendTo('head');
positionBar(e);
lastIndx = endIndex;
},
positionBar = function(e) {
for (i = 0; i <= len; i++) {
if ( i > 0 && e.pageX < offsets[i-1] + (offsets[i] - offsets[i-1])/2 && !c.$headers.eq(i).hasClass(noReorderLeft) ) {
endIndex = i - 1;
// endIndex = offsets.lastIndexOf( offsets[i-1] ); // lastIndexOf not supported by IE8 and older
if (endIndex >= 0 && lastIndx === endIndex) { return false; }
lastIndx = endIndex;
if (c.debug) {
console.log( endIndex === 0 ? 'target before column 0' : endIndex === len ? 'target after last column' : 'target between columns ' + startIndex + ' and ' + endIndex);
}
$bar.css('left', offsets[i-1]);
return false;
}
}
if (endIndex < 0) {
endIndex = len;
$bar.css('left', offsets[len]);
}
},
finishReorder = function() {
$helper.remove();
$bar.remove();
// finish reorder
var adj, s = startIndex,
rows = c.$table.find('tr'),
cols;
startIndex = -1; // stop mousemove updates
if ( s > -1 && endIndex > -1 && s !== endIndex && s + 1 !== endIndex ) {
adj = endIndex !== 0;
if (c.debug) {
console.log( 'Inserting column ' + s + (adj ? ' after' : ' before') + ' column ' + (endIndex - adj ? 1 : 0) );
}
rows.each(function() {
cols = $(this).children();
cols.eq(s)[ adj ? 'insertAfter' : 'insertBefore' ]( cols.eq( endIndex - (adj ? 1 : 0) ) );
});
cols = [];
// stored header info needs to be modified too!
for (i = 0; i < len; i++) {
if (i === s) { continue; }
if (i === endIndex - (adj ? 1 : 0)) {
if (!adj) { cols.push(c.headerContent[s]); }
cols.push(c.headerContent[i]);
if (adj) { cols.push(c.headerContent[s]); }
} else {
cols.push(c.headerContent[i]);
}
}
c.headerContent = cols;
// cols = c.headerContent.splice(s, 1);
// c.headerContent.splice(endIndex - (adj ? 1 : 0), 0, cols);
c.$table.trigger('updateAll', [ true, wo.reorder_complete ]);
}
endIndex = -1;
},
mdown = function(e, el) {
var $t = $(el), evt = e;
if ($t.hasClass(wo.reorder_noReorder)) { return; }
timer = setTimeout(function() {
$t.addClass('tablesorter-reorder');
startReorder(evt, $t);
}, wo.reorder_delay);
};
console.log( c.$headers.last().hasClass(noReorderLast) );
if ( c.$headers.last().hasClass(noReorderLast) ) {
offsets.push( offsets[ offsets.length - 1 ] );
} else {
offsets.push( c.$table.offset().left + c.$table.outerWidth() );
}
c.$headers.not('.' + wo.reorder_noReorder).bind('mousedown.reorder', function(e) {
mdown(e, this);
});
$(document)
.bind('mousemove.reorder', function(e) {
if (startIndex !== -1) {
var c = { left : e.pageX - clickOffset[0] };
endIndex = -1;
if (/y/.test(wo.reorder_axis)) {
c.top = e.pageY - clickOffset[1];
}
$helper.css(c);
positionBar(e);
}
})
.add( c.$headers )
.bind('mouseup.reorder', function() {
clearTimeout(timer);
if (startIndex !== -1 && endIndex !== -1) {
finishReorder();
} else {
startIndex = -1;
}
});
// has sticky headers?
c.$table.bind('stickyHeadersInit', function() {
wo.$sticky.find('thead').children().not('.' + wo.reorder_noReorder).bind('mousedown.reorder', function(e) {
mdown(e, this);
});
});
}
});
// add mouse coordinates
$x = $('#main h1:last'); $(document).mousemove(function(e) { $x.html( e.pageX ); });
})(jQuery);