diff --git a/css/dragtable.mod.css b/css/dragtable.mod.css
index eea04bbf..e8b59d39 100644
--- a/css/dragtable.mod.css
+++ b/css/dragtable.mod.css
@@ -1,40 +1,64 @@
-/*
+/*
* dragtable
- *
- * @Version 2.0.14
- *
+ * @Version 2.0.14 MOD
* default css
- *
*/
-/*##### the dragtable stuff #####*/
-.dragtable-sortable {
- list-style-type: none; margin: 0; padding: 0; -moz-user-select: none;
+.dragtable-sortable {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ -moz-user-select: none;
+ z-index: 10;
}
.dragtable-sortable li {
- margin: 0; padding: 0; float: left; font-size: 1em; background: white;
+ margin: 0;
+ padding: 0;
+ float: left;
+ font-size: 1em;
}
-
-.dragtable-sortable th, .dragtable-sortable td{
- border-left: 0px;
+.dragtable-sortable table {
+ margin-top: 0;
+}
+.dragtable-sortable th, .dragtable-sortable td {
+ border-left: 0px;
}
-
.dragtable-sortable li:first-child th, .dragtable-sortable li:first-child td {
- border-left: 1px solid #CCC;
+ border-left: 1px solid #CCC;
+}
+.dragtable-handle-selected {
+ /* table-handle class while actively dragging a column */
}
-
.ui-sortable-helper {
- opacity: 0.7;filter: alpha(opacity=70);
+ opacity: 0.7;
+ filter: alpha(opacity=70);
}
-.ui-sortable-placeholder {
- -moz-box-shadow: 4px 5px 4px #C6C6C6 inset;
- -webkit-box-shadow: 4px 5px 4px #C6C6C6 inset;
- box-shadow: 4px 5px 4px #C6C6C6 inset;
- border-bottom: 1px solid #CCCCCC;
- border-top: 1px solid #CCCCCC;
- visibility: visible !important;
- background: #EFEFEF !important;
- visibility: visible !important;
+.ui-sortable-placeholder {
+ -moz-box-shadow: 4px 5px 4px rgba(0,0,0,0.2) inset;
+ -webkit-box-shadow: 4px 5px 4px rgba(0,0,0,0.2) inset;
+ box-shadow: 4px 5px 4px rgba(0,0,0,0.2) inset;
+ border-bottom: 1px solid rgba(0,0,0,0.2);
+ border-top: 1px solid rgba(0,0,0,0.2);
+ visibility: visible !important;
+ /* change the background color here to match the tablesorter theme */
+ background: #EFEFEF;
}
-.ui-sortable-placeholder * {
- opacity: 0.0; visibility: hidden;
+.ui-sortable-placeholder * {
+ opacity: 0.0;
+ visibility: hidden;
+}
+.table-handle, .table-handle-disabled {
+ /* background-image: url(images/dragtable-handle.png); */
+ /* background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAANAQMAAAC5Li2yAAAABlBMVEUAAAAzMzPI8eYgAAAAAnRSTlMAzORBQ6MAAAAOSURBVAjXYwABByyYAQAQWgFBLN2RnwAAAABJRU5ErkJggg=='); */
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyIiBoZWlnaHQ9IjEzIj48cmVjdCBzdHlsZT0iZmlsbDojMzMzO2ZpbGwtb3BhY2l0eTouODsiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHg9IjEiIHk9IjIiLz4JPHJlY3Qgc3R5bGU9ImZpbGw6IzMzMztmaWxsLW9wYWNpdHk6Ljg7IiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4PSIxIiB5PSI0Ii8+CTxyZWN0IHN0eWxlPSJmaWxsOiMzMzM7ZmlsbC1vcGFjaXR5Oi44OyIgd2lkdGg9IjEiIGhlaWdodD0iMSIgeD0iMSIgeT0iNiIvPjxyZWN0IHN0eWxlPSJmaWxsOiMzMzM7ZmlsbC1vcGFjaXR5Oi44OyIgd2lkdGg9IjEiIGhlaWdodD0iMSIgeD0iMSIgeT0iOCIvPjxyZWN0IHN0eWxlPSJmaWxsOiMzMzM7ZmlsbC1vcGFjaXR5Oi44OyIgd2lkdGg9IjEiIGhlaWdodD0iMSIgeD0iMSIgeT0iMTAiLz48L3N2Zz4=);
+ background-repeat: repeat-x;
+ height: 13px;
+ margin: 0 1px;
+ cursor: move;
+}
+.table-handle-disabled {
+ opacity: 0;
+ cursor: not-allowed;
+}
+.dragtable-sortable table {
+ margin-bottom: 0;
}
diff --git a/css/images/dragtable-handle.png b/css/images/dragtable-handle.png
new file mode 100644
index 00000000..ff64a7d5
Binary files /dev/null and b/css/images/dragtable-handle.png differ
diff --git a/css/images/dragtable-handle.svg b/css/images/dragtable-handle.svg
new file mode 100644
index 00000000..041ec1de
--- /dev/null
+++ b/css/images/dragtable-handle.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/css/jq.css b/docs/css/jq.css
index ebd3d60c..c45df496 100644
--- a/docs/css/jq.css
+++ b/docs/css/jq.css
@@ -83,6 +83,8 @@ span.alert { padding: 1px 3px; }
.fade { opacity: 0.5; }
.results { color: red; }
.clear { clear: both; }
+.good { color: #080; }
+.bad { color: #800; }
.bootstrap_buttons button { margin: 5px 0 0 0; }
#main .ui-accordion-header a, #main .ui-accordion-content { font-size: 14px; }
#banner small { font-size: 16px; vertical-align: super; }
diff --git a/docs/example-dragtable.html b/docs/example-dragtable.html
new file mode 100644
index 00000000..09bf49d7
--- /dev/null
+++ b/docs/example-dragtable.html
@@ -0,0 +1,245 @@
+
+
+
+
+ jQuery plugin: Tablesorter 2.0 - Dragtable Mod (beta)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This demo uses a modified version of the jQuery UI Dragtable widget (beta) to work with tablesorter.
+ This mod has been tested with the following widgets: alignChar , columns , cssStickyHeaders , editable , filter , grouping , headerTitles , math , output , pager print , reflow , resizable , repeatHeaders , staticRow , uitheme & zebra .
+ This mod does not currently work with the following widgets:
+
+ chart - needs more work to be compatible.
+ columnSelector - needs more work - making this compatible will require significant changes to the dragtable core.
+ saveSort - this saves the newly moved sorted column properly, but on page reload the column order is restored so it sorts the incorrect column.
+ scroller - way too much work to make this compatible.
+ stickyHeaders - needs more work - can't get the drag handle in the cloned sticky header from passing the mousedown on to the original drag handle.
+
+
+ Any widgets not listed above can be assumed to be incompatible, for now.
+
+
+
+
+
+ A complete javascript example can be found in the demo section, below the table.
+
+ To use this mod:
+
+ Initialize the dragtable mod script first, then initialize tablesorter.
+ Warning! When setting up the initialization code, make sure that the dragtable sortClass
option exactly matches the tablesorter selectorSort
option, or the table will be unsortable.
+ $('table')
+ .dragtable({ sortClass: '.sorter' }) // this is already the default value
+ .tablesorter({ selectorSort: '.sorter' }); // this default value is 'th, td'
+ Warning! Do not reference a column using jQuery data (e.g. $('th:contains(Name)').data('sorter', 'text');
) or by it's zero-based index(1) because these references do not get updated after a column move!
+
+ Instead, use one of the following methods (these examples set the column parser):
+ Set parser by data-attribute or header class
+ <tr>
+ <th class="col-id" data-sorter="digit">...</th> <!-- parser set by data-attribute -->
+ <th class="col-name drag-enable sorter-text">...</th> <!-- parser set by header class -->
+ <th class="col-date drag-enable">...</th> <!-- parser set by headers option (see below) -->
+</tr>
+ Or, set parser by headers
option
+ $('table').tablesorter({
+ headers : {
+ '.col-date' : { sorter : 'shortDate' }
+ }
+});
+ In order to get dragtable to work, the mod will add a div to act as a dragable handle and wrap the header text in a div(2) which needs to be targeted by the selectorSort
option to make it clickable for sorting.
+
+ The resulting HTML may look like this:
+ <tr>
+ <th class="col-id" data-sorter="digit">
+ <div class="table-handle-disabled"></div>
+ <!-- clicking on the "sort" wrapper below will not trigger a sort, because the cell is not set to sort -->
+ <div class="sorter">9999</div>
+ </th>
+ <th class="col-name sorter-text drag-enable">
+ <div class="table-handle"></div>
+ <div class="sorter">Name</div>
+ </th>
+ <th class="col-date drag-enable">
+ <div class="table-handle"></div>
+ <div class="sorter">1/1/2015</div>
+ </th>
+</tr>
+
+
+
(1) Options that use a column index (such as the
sortList
), or an array of settings (like the
resizable_widths
option) are updated internally by the mod.
+
+
(2) The class name for the dragable handle is set by the dragtable
dragHandle
option & the class name for the clickable div wrapping the header text is set by the dragtable
sortClass
option.
+
+
+
+
+
Demo
+
+ Student Grades
+
+
+ Name (0)
+ Major (1)
+ Sex (2)
+ English (3)
+ Japanese (4)
+ Calculus (5)
+ Geometry (6)
+
+
+
+ Name Major Sex English Japanese Calculus Geometry
+
+
+ Student01 (0) Languages (1) male (2) 80 (3) 70 (4) 75 (5) 80 (6)
+ Student02 Mathematics male 90 88 100 90
+ Student03 Languages female 85 95 80 85
+ Student04 Languages male 60 55 100 100
+ Student05 Languages female 68 80 95 80
+ Student06 Mathematics male 100 99 100 90
+ Student07 Mathematics male 85 68 90 90
+ Student08 Languages male 100 90 90 85
+ Student09 Mathematics male 80 50 65 75
+ Student10 Languages male 85 100 100 90
+ Student11 Languages male 86 85 100 100
+ Student12 Mathematics female 100 75 70 85
+ Student13 Languages female 100 80 100 90
+ Student14 Languages female 50 45 55 90
+ Student15 Languages male 95 35 100 90
+ Student16 Languages female 100 50 30 70
+ Student17 Languages female 80 100 55 65
+ Student18 Mathematics male 30 49 55 75
+ Student19 Languages male 68 90 88 70
+ Student20 Mathematics male 40 45 40 80
+
+
+
+
HTML
+
+
+
Javascript
+
+
+
Optional CSS
+
+
+
+
+
+
diff --git a/docs/index.html b/docs/index.html
index 9e6f17e2..b3828179 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -473,6 +473,7 @@
† Columns Highlight widget (v2.0.17)
Beta Column Selector widget (v2.15 ; v2.18.5 ).
Content Editable widget (v2.9; v2.18.0 ).
+ Beta Dragtable mod - (jQuery UI widget for column reordering [ref ]; v2.18.5 ).
† Filter Widget (v2.17.4 ):
basic (v2.0.18; v2.18.1 )
@@ -484,7 +485,7 @@
formatter: select2 (v2.16.0 ; v2.18.5 )
- Formatter widget (v2.18.5 ).
+ Beta Formatter widget (v2.18.5 ).
Grouping rows widget:
basic (v2.8; v2.18.0 ).
@@ -542,7 +543,7 @@
diff --git a/js/extras/jquery.dragtable.mod.js b/js/extras/jquery.dragtable.mod.js
index 32a4f23d..a9f43e6a 100644
--- a/js/extras/jquery.dragtable.mod.js
+++ b/js/extras/jquery.dragtable.mod.js
@@ -1,7 +1,211 @@
+/*! Dragtable Mod for TableSorter - 1/14/2015 (v2.18.5) *//*
+ * 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( $ ) {
+'use strict';
+ var undef,
+ ts = $.tablesorter;
+
+ ts.dragtable = {
+ create : function( _this ) {
+ var hasAccept,
+ $table = _this.originalTable.el,
+ handle = _this.options.dragHandle.replace('.', '');
+ $table.children('thead').children().children('th,td').each(function(){
+ var $this = $(this);
+ if ( !$this.find( _this.options.dragHandle + ',.' + handle + '-disabled' ).length ) {
+ hasAccept = _this.options.dragaccept ? $this.hasClass( _this.options.dragaccept.replace('.', '') ) : true;
+ $this
+ // sortClass includes a "." to match the tablesorter selectorSort option - for consistency
+ .wrapInner('
')
+ // add handle class + "-disabled" to drag-disabled columns
+ .prepend('
');
+ }
+ });
+ },
+ start : function( table ) {
+ table = $( table )[0];
+ if ( table && table.config ) {
+ table.config.widgetOptions.dragtableLast = {
+ search : $( table ).data( 'lastSearch' ),
+ order : ts.dragtable.getOrder( table )
+ };
+ }
+ },
+ update : function( _this ) {
+ var t, list, val,
+ dragTable = _this.originalTable,
+ table = dragTable.el[ 0 ],
+ $table = $( table ),
+ c = table.config,
+ wo = c && c.widgetOptions,
+ startIndex = dragTable.startIndex - 1,
+ endIndex = dragTable.endIndex - 1,
+ columnOrder = ts.dragtable.getOrder( table ) || [],
+ hasFilters = ts.hasWidget( $table, 'filter' ) || false,
+ last = wo && wo.dragtableLast || {},
+ // update moved filters
+ filters = [];
+
+ // only trigger updateAll if column order changed
+ if ( ( last.order || [] ).join( '' ) !== columnOrder.join( '' ) ) {
+
+ if ( c.sortList.length ) {
+ // must deep extend (nested arrays) to prevent list from changing with c.sortList
+ list = $.extend( true, [], c.sortList );
+ $.each( columnOrder, function( indx, value ) {
+ val = ts.isValueInArray( parseInt( value, 10 ), list );
+ if ( value !== last.order[ indx ] && val >= 0 ) {
+ c.sortList[ val ][ 0 ] = indx;
+ }
+ });
+ }
+
+ // update filter widget
+ if ( hasFilters ) {
+ $.each( last.search || [], function( indx ) {
+ filters[ indx ] = last.search[ columnOrder[ indx ] ];
+ });
+ }
+
+ // update preset editable widget columns
+ t = ( ts.hasWidget( c.$table, 'editable' ) || false ) ? wo.editable_columnsArray : false;
+ if ( t ) {
+ c.widgetOptions.editable_columnsArray = ts.dragtable.reindexArrayItem( t, startIndex, endIndex );
+ }
+ // update ignore math columns
+ t = ( ts.hasWidget( c.$table, 'math' ) || false ) ? wo.math_ignore : false;
+ if ( t ) {
+ c.widgetOptions.math_ignore = ts.dragtable.reindexArrayItem( t, startIndex, endIndex );
+ }
+ // update preset resizable widget widths
+ t = ( ts.hasWidget( c.$table, 'resizable' ) || false ) ? wo.resizable_widths : false;
+ if ( t ) {
+ // use zero-based indexes in the array
+ wo.resizable_widths = ts.dragtable.moveArrayItem( t, startIndex, endIndex );
+ }
+ /*
+ // chart widget WIP - there are other options that need to be rearranged!
+ t = ( ts.hasWidget( c.$table, 'chart' ) || false ) ? wo.chart_ignoreColumns : false;
+ if ( t ) {
+ // use zero-based indexes in the array
+ wo.chart_ignoreColumns = ts.dragtable.moveArrayItem( t, startIndex, endIndex );
+ }
+ */
+
+ $table.trigger('updateAll', [ false, function() {
+ if ( hasFilters ) {
+ setTimeout( function() {
+ // just update the filter values
+ c.lastCombinedFilter = null;
+ c.$table.data('lastSearch', filters);
+ ts.setFilters( $table, filters );
+ if ($.isFunction(_this.options.tablesorterComplete)) {
+ _this.options.tablesorterComplete( c.table );
+ }
+ }, 10 );
+ }
+ } ]);
+ }
+ },
+ getOrder : function( table ) {
+ return $( table ).children( 'thead' ).children( '.' + ts.css.headerRow ).children().map( function() {
+ return $( this ).attr( 'data-column' );
+ }).get() || [];
+ },
+ // bubble the moved col left or right
+ startColumnMove : function( dragTable ) {
+ var $cols,
+ c = dragTable.el[ 0 ].config,
+ startIndex = dragTable.startIndex - 1,
+ endIndex = dragTable.endIndex - 1,
+ cols = c.columns - 1,
+ pos = endIndex === cols ? false : endIndex <= startIndex,
+ $rows = c.$table.children().children( 'tr' );
+ if ( c.debug ) {
+ ts.log( 'Inserting column ' + startIndex + ( pos ? ' before' : ' after' ) + ' column ' + endIndex );
+ }
+ $rows.each( function() {
+ $cols = $( this ).children();
+ $cols.eq( startIndex )[ pos ? 'insertBefore' : 'insertAfter' ]( $cols.eq( endIndex ) );
+ });
+ // rearrange col in colgroup
+ $cols = c.$table.children( 'colgroup' ).children();
+ $cols.eq( startIndex )[ pos ? 'insertBefore' : 'insertAfter' ]( $cols.eq( endIndex ) );
+ },
+ swapNodes : function( a, b ) {
+ var indx, aparent, asibling,
+ len = a.length;
+ for ( indx = 0; indx < len; indx++ ) {
+ aparent = a[ indx ].parentNode;
+ asibling = a[ indx ].nextSibling === b[ indx ] ? a[ indx ] : a[ indx ].nextSibling;
+ b[ indx ].parentNode.insertBefore( a[ indx ], b[ indx ] );
+ aparent.insertBefore( b[ indx ], asibling );
+ }
+ },
+ // http://stackoverflow.com/a/5306832/145346
+ moveArrayItem : function( array, oldIndex, newIndex ) {
+ var indx, len = array.length;
+ if ( newIndex >= len ) {
+ indx = newIndex - len;
+ while ( ( indx-- ) + 1 ) {
+ array.push( undef );
+ }
+ }
+ array.splice( newIndex, 0, array.splice( oldIndex, 1 )[ 0 ] );
+ return array;
+ },
+ reindexArrayItem : function( array, oldIndex, newIndex ) {
+ var nIndx = $.inArray( newIndex, array ),
+ oIndx = $.inArray( oldIndex, array ),
+ max = Math.max.apply( Math, array ),
+ arry = [];
+ // columns in the array were swapped so return original array
+ if ( nIndx >= 0 && oIndx >= 0 ) {
+ return array;
+ }
+ // columns not in the array were moved
+ $.each( array, function( indx, value ) {
+ // column (not in array) inserted between indexes
+ if ( newIndex < oldIndex ) {
+ // ( [ 0,1,2,3 ], 5, 1 ) -> column inserted between 0 & 1 => [ 0,2,3,4 ]
+ if ( value >= newIndex ) {
+ // 5 -> 1 [ 0, 2, 3 ] then 1 -> 0 [ 1, 2, 3 ]
+ arry.push( value + ( value < oldIndex ? 1 : 0 ) );
+ } else {
+ arry.push( value );
+ }
+ } else if ( newIndex > oldIndex ) {
+ // ( [ 0,1,2,3 ], 1, 5 ) -> column in array moved outside => [ 0,1,2,5 ]
+ if ( value === oldIndex ) {
+ arry.push( newIndex );
+ } else if ( value < newIndex && value >= oldIndex ) {
+ arry.push( value - 1 );
+ } else if ( value <= newIndex ) {
+ arry.push( value );
+ } else if ( value > oldIndex ) {
+ arry.push( value + ( value < newIndex ? 0 : 1 ) );
+ }
+ }
+ });
+ return arry.sort();
+ }
+ };
+
/*!
* dragtable
+ * _____ _
+ * | |___ _| |
+ * | | | | . | . |
+ * |_|_|_|___|___|
*
- * @Version 2.0.14
+ * @Version 2.0.14 MOD
*
* Copyright (c) 2010-2013, Andres akottr@gmail.com
* Dual licensed under the MIT (MIT-LICENSE.txt)
@@ -52,7 +256,6 @@
* Special thx to all pull requests comitters
*/
-(function($) {
$.widget("akottr.dragtable", {
options: {
revert: false, // smooth revert
@@ -74,7 +277,10 @@
beforeStart: $.noop, // returning FALSE will stop the execution chain.
beforeMoving: $.noop,
beforeReorganize: $.noop,
- beforeStop: $.noop
+ beforeStop: $.noop,
+ // new options
+ tablesorterComplete: null,
+ sortClass : '.sorter'
},
originalTable: {
el: null,
@@ -108,44 +314,16 @@
*/
_restoreState: function(persistObj) {
for (var n in persistObj) {
- this.originalTable.startIndex = $('#' + n).closest('th').prevAll().size() + 1;
- this.originalTable.endIndex = parseInt(persistObj[n], 10) + 1;
- this._bubbleCols();
+ if (n in persistObj) {
+ this.originalTable.startIndex = $('#' + n).closest('th').prevAll().length + 1;
+ this.originalTable.endIndex = parseInt(persistObj[n], 10) + 1;
+ this._bubbleCols();
+ }
}
},
// bubble the moved col left or right
_bubbleCols: function() {
- var i, j, col1, col2;
- var from = this.originalTable.startIndex;
- var to = this.originalTable.endIndex;
- /* Find children thead and tbody.
- * Only to process the immediate tr-children. Bugfix for inner tables
- */
- var thtb = this.originalTable.el.children();
- if (this.options.excludeFooter) {
- thtb = thtb.not('tfoot');
- }
- if (from < to) {
- for (i = from; i < to; i++) {
- col1 = thtb.find('> tr > td:nth-child(' + i + ')')
- .add(thtb.find('> tr > th:nth-child(' + i + ')'));
- col2 = thtb.find('> tr > td:nth-child(' + (i + 1) + ')')
- .add(thtb.find('> tr > th:nth-child(' + (i + 1) + ')'));
- for (j = 0; j < col1.length; j++) {
- swapNodes(col1[j], col2[j]);
- }
- }
- } else {
- for (i = from; i > to; i--) {
- col1 = thtb.find('> tr > td:nth-child(' + i + ')')
- .add(thtb.find('> tr > th:nth-child(' + i + ')'));
- col2 = thtb.find('> tr > td:nth-child(' + (i - 1) + ')')
- .add(thtb.find('> tr > th:nth-child(' + (i - 1) + ')'));
- for (j = 0; j < col1.length; j++) {
- swapNodes(col1[j], col2[j]);
- }
- }
- }
+ ts.dragtable.startColumnMove(this.originalTable);
},
_rearrangeTableBackroundProcessing: function() {
var _this = this;
@@ -154,10 +332,14 @@
_this.options.beforeStop(_this.originalTable);
_this.sortableTable.el.remove();
restoreTextSelection();
+ ts.dragtable.update(_this);
// persist state if necessary
- if (_this.options.persistState !== null) {
- $.isFunction(_this.options.persistState) ? _this.options.persistState(_this.originalTable) : _this.persistState();
+ if ($.isFunction(_this.options.persistState)) {
+ _this.options.persistState(_this.originalTable);
+ } else {
+ _this.persistState();
}
+
};
},
_rearrangeTable: function() {
@@ -171,7 +353,7 @@
_this.options.beforeReorganize(_this.originalTable, _this.sortableTable);
// do reorganisation asynchronous
// for chrome a little bit more than 1 ms because we want to force a rerender
- _this.originalTable.endIndex = _this.sortableTable.movingRow.prevAll().size() + 1;
+ _this.originalTable.endIndex = _this.sortableTable.movingRow.prevAll().length + 1;
setTimeout(_this._rearrangeTableBackroundProcessing(), 50);
};
},
@@ -181,28 +363,33 @@
* each li with a separate table representig a single col of the original table.
*/
_generateSortable: function(e) {
- !e.cancelBubble && (e.cancelBubble = true);
+ if (e.cancelBubble) {
+ e.cancelBubble = true;
+ } else {
+ e.stopPropagation();
+ }
var _this = this;
// table attributes
var attrs = this.originalTable.el[0].attributes;
- var attrsString = '';
+ var tableAttrsString = '';
for (var i = 0; i < attrs.length; i++) {
- if (attrs[i].nodeValue && attrs[i].nodeName != 'id' && attrs[i].nodeName != 'width') {
- attrsString += attrs[i].nodeName + '="' + attrs[i].nodeValue + '" ';
+ if ( (attrs[i].value || attrs[i].nodeValue) && attrs[i].nodeName != 'id' && attrs[i].nodeName != 'width') {
+ tableAttrsString += attrs[i].nodeName + '="' + ( attrs[i].value || attrs[i].nodeValue ) + '" ';
}
}
-
// row attributes
var rowAttrsArr = [];
//compute height, special handling for ie needed :-(
var heightArr = [];
- this.originalTable.el.find('tr').slice(0, this.options.maxMovingRows).each(function(i, v) {
+
+ // don't save tfoot attributes because it messes up indexing
+ _this.originalTable.el.children('thead, tbody').children('tr:visible').slice(0, _this.options.maxMovingRow).each(function() {
// row attributes
var attrs = this.attributes;
- var attrsString = "";
+ var attrsString = '';
for (var j = 0; j < attrs.length; j++) {
- if (attrs[j].nodeValue && attrs[j].nodeName != 'id') {
- attrsString += " " + attrs[j].nodeName + '="' + attrs[j].nodeValue + '"';
+ if ( (attrs[j].value || attrs[j].nodeValue ) && attrs[j].nodeName != 'id') {
+ attrsString += ' ' + attrs[j].nodeName + '="' + ( attrs[j].value || attrs[j].nodeValue ) + '"';
}
}
rowAttrsArr.push(attrsString);
@@ -217,47 +404,72 @@
* Only to process the immediate tr-children. Bugfix for inner tables
*/
var thtb = _this.originalTable.el.children();
- if (this.options.excludeFooter) {
- thtb = thtb.not('tfoot');
- }
- thtb.find('> tr > th').each(function(i, v) {
+ var headerRows = thtb.filter('thead').children('tr:visible');
+ var visibleRows = thtb.filter('tbody').children('tr:visible');
+
+ headerRows.eq(0).children('th, td').filter(':visible').each(function() {
var w = $(this).outerWidth();
widthArr.push(w);
totalWidth += w;
});
if(_this.options.exact) {
- var difference = totalWidth - _this.originalTable.el.outerWidth();
- widthArr[0] -= difference;
+ var difference = totalWidth - _this.originalTable.el.outerWidth();
+ widthArr[0] -= difference;
}
// one extra px on right and left side
- totalWidth += 2
+ totalWidth += 2;
+
+ var captionHeight = 0;
+ thtb.filter('caption').each(function(){
+ captionHeight += $(this).outerHeight();
+ });
var sortableHtml = '';
+ var sortableColumn = [];
// assemble the needed html
- thtb.find('> tr > th').each(function(i, v) {
- var width_li = $(this).outerWidth();
- sortableHtml += '';
- sortableHtml += '';
- var row = thtb.find('> tr > th:nth-child(' + (i + 1) + ')');
- if (_this.options.maxMovingRows > 1) {
- row = row.add(thtb.find('> tr > td:nth-child(' + (i + 1) + ')').slice(0, _this.options.maxMovingRows - 1));
+ // build list
+ var rowIndex,
+ columns = headerRows.eq(0).children('th, td').length;
+ /*jshint loopfunc:true */
+ for (i = 0; i < columns; i++) {
+ var row = headerRows.children(':nth-child(' + (i + 1) + ')');
+ if (row.is(':visible')) {
+ rowIndex = 0;
+ sortableColumn[i] = '' +
+ '' +
+ ( captionHeight ? ' ' : '' ) +
+ '';
+ // thead
+ headerRows.each(function(j){
+ sortableColumn[i] += '' +
+ row[j].outerHTML + ' ';
+ });
+ sortableColumn[i] += ' ';
+ // tbody
+ row = visibleRows.children(':nth-child(' + (i + 1) + ')');
+ if (_this.options.maxMovingRows > 1) {
+ row = row.add(visibleRows.children(':nth-child(' + (i + 1) + ')').slice(0, _this.options.maxMovingRows - 1));
+ }
+ row.each(function(j) {
+ sortableColumn[i] += '' +
+ this.outerHTML + ' ';
+ });
+ sortableColumn[i] += ' ';
+
+ // add footer to end of max Rows
+ if (!_this.options.excludeFooter) {
+ sortableColumn[i] += '' +
+ thtb.filter('tfoot').children('tr:visible').children()[i].outerHTML + ' ';
+ }
+ sortableColumn[i] += '
';
}
- row.each(function(j) {
- // TODO: May cause duplicate style-Attribute
- var row_content = $(this).clone().wrap('
').parent().html();
- if (row_content.toLowerCase().indexOf('";
- sortableHtml += ' ';
- sortableHtml += row_content;
- if (row_content.toLowerCase().indexOf('";
- sortableHtml += ' ';
- });
- sortableHtml += '
';
- sortableHtml += ' ';
- });
- sortableHtml += ' ';
+ }
+ sortableHtml += sortableColumn.join('') + ' ';
this.sortableTable.el = this.originalTable.el.before(sortableHtml).prev();
// set width if necessary
- this.sortableTable.el.find('> li > table').each(function(i, v) {
+ this.sortableTable.el.find('> li > table').each(function(i) {
$(this).css('width', widthArr[i] + 'px');
});
@@ -279,11 +491,10 @@
});
// assign start index
- this.originalTable.startIndex = $(e.target).closest('th').prevAll().size() + 1;
-
+ this.originalTable.startIndex = $(e.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.find('> li:nth-child(' + this.originalTable.startIndex + ')');
+ this.sortableTable.movingRow = this.sortableTable.el.children('li:nth-child(' + this.originalTable.startIndex + ')');
// prevent the user from drag selecting "highlighting" surrounding page elements
disableTextSelection();
@@ -300,7 +511,7 @@
// Some inner divs to deliver the posibillity to style the placeholder more sophisticated
var placeholder = this.sortableTable.el.find('.ui-sortable-placeholder');
- if(!placeholder.height() <= 0) {
+ if(placeholder.height() > 0) {
placeholder.css('height', this.sortableTable.el.find('.ui-sortable-helper').height());
}
@@ -308,42 +519,42 @@
},
bindTo: {},
_create: function() {
- this.originalTable = {
- el: this.element,
+ var _this = this;
+ _this.originalTable = {
+ el: _this.element,
selectedHandle: $(),
sortOrder: {},
startIndex: 0,
endIndex: 0
};
- // bind draggable to 'th' by default
- this.bindTo = this.originalTable.el.find('th');
+ ts.dragtable.create( _this );
// filter only the cols that are accepted
- if (this.options.dragaccept) {
- this.bindTo = this.bindTo.filter(this.options.dragaccept);
- }
+ _this.bindTo = '> thead > tr > ' + ( _this.options.dragaccept || 'th, td' );
// bind draggable to handle if exists
- if (this.bindTo.find(this.options.dragHandle).size() > 0) {
- this.bindTo = this.bindTo.find(this.options.dragHandle);
+ if (_this.element.find(_this.bindTo).find(_this.options.dragHandle).length) {
+ _this.bindTo += ' ' + _this.options.dragHandle;
}
// restore state if necessary
- if (this.options.restoreState !== null) {
- $.isFunction(this.options.restoreState) ? this.options.restoreState(this.originalTable) : this._restoreState(this.options.restoreState);
+ if ($.isFunction(_this.options.restoreState)) {
+ _this.options.restoreState(_this.originalTable);
+ } else {
+ _this._restoreState(_this.options.restoreState);
}
- var _this = this;
- this.bindTo.mousedown(function(evt) {
+ _this.originalTable.el.on( 'mousedown.dragtable', _this.bindTo, function(evt) {
// listen only to left mouse click
- if(evt.which!==1) return;
+ if (evt.which!==1) return;
+ ts.dragtable.start( _this.originalTable.el );
if (_this.options.beforeStart(_this.originalTable) === false) {
return;
}
- clearTimeout(this.downTimer);
- this.downTimer = setTimeout(function() {
- _this.originalTable.selectedHandle = $(this);
+ clearTimeout(_this.downTimer);
+ _this.downTimer = setTimeout(function() {
+ _this.originalTable.selectedHandle = $(_this);
_this.originalTable.selectedHandle.addClass('dragtable-handle-selected');
_this._generateSortable(evt);
}, _this.options.clickDelay);
- }).mouseup(function(evt) {
- clearTimeout(this.downTimer);
+ }).on( 'mouseup.dragtable', _this.options.dragHandle,function() {
+ clearTimeout(_this.downTimer);
});
},
redraw: function(){
@@ -351,20 +562,18 @@
this._create();
},
destroy: function() {
- this.bindTo.unbind('mousedown');
+ _this.originalTable.el.off('mousedown.dragtable mouseup.dragtable', _this.bindTo);
$.Widget.prototype.destroy.apply(this, arguments); // default destroy
// now do other stuff particular to this widget
}
});
/** closure-scoped "private" functions **/
-
var body_onselectstart_save = $(document.body).attr('onselectstart'),
- body_unselectable_save = $(document.body).attr('unselectable');
+ body_unselectable_save = $(document.body).attr('unselectable');
// css properties to disable user-select on the body tag by appending a