182 lines
5.4 KiB
JavaScript
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);
|