jquery-tablesorter 1.19.4 → 1.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/jquery-tablesorter/version.rb +2 -2
  4. data/vendor/assets/javascripts/jquery-tablesorter/addons/pager/jquery.tablesorter.pager.js +10 -10
  5. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.combined.js +210 -108
  6. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.js +151 -74
  7. data/vendor/assets/javascripts/jquery-tablesorter/jquery.tablesorter.widgets.js +59 -34
  8. data/vendor/assets/javascripts/jquery-tablesorter/parsers/parser-input-select.js +62 -32
  9. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-alignChar.js +1 -1
  10. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-build-table.js +1 -1
  11. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-columnSelector.js +2 -2
  12. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-editable.js +15 -12
  13. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter-type-insideRange.js +6 -5
  14. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-filter.js +53 -28
  15. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-grouping.js +1 -1
  16. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-math.js +154 -76
  17. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-pager.js +9 -9
  18. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-print.js +2 -2
  19. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-resizable.js +3 -3
  20. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-scroller.js +1 -1
  21. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-sort2Hash.js +2 -2
  22. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-staticRow.js +1 -1
  23. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-stickyHeaders.js +2 -2
  24. data/vendor/assets/javascripts/jquery-tablesorter/widgets/widget-view.js +2 -2
  25. metadata +2 -2
@@ -1,4 +1,4 @@
1
- /*! TableSorter (FORK) v2.24.6 *//*
1
+ /*! TableSorter (FORK) v2.25.0 *//*
2
2
  * Client-side table sorting with ease!
3
3
  * @requires jQuery v1.2.6+
4
4
  *
@@ -21,7 +21,7 @@
21
21
  'use strict';
22
22
  var ts = $.tablesorter = {
23
23
 
24
- version : '2.24.6',
24
+ version : '2.25.0',
25
25
 
26
26
  parsers : [],
27
27
  widgets : [],
@@ -62,6 +62,7 @@
62
62
 
63
63
  emptyTo : 'bottom', // sort empty cell to bottom, top, none, zero, emptyMax, emptyMin
64
64
  stringTo : 'max', // sort strings in numerical column as max, min, top, bottom, zero
65
+ duplicateSpan : true, // colspan cells in the tbody will have duplicated content in the cache for each spanned column
65
66
  textExtraction : 'basic', // text extraction method/function - function( node, table, cellIndex ){}
66
67
  textAttribute : 'data-text',// data-attribute that contains alternate cell text (used in default textExtraction function)
67
68
  textSorter : null, // choose overall or specific column sorter function( a, b, direction, table, columnIndex ) [alt: ts.sortText]
@@ -209,7 +210,7 @@
209
210
  if ( table.hasInitialized ) {
210
211
  console.warn( 'Stopping initialization. Tablesorter has already been initialized' );
211
212
  } else {
212
- console.error( 'Stopping initialization! No table, thead or tbody' );
213
+ console.error( 'Stopping initialization! No table, thead or tbody', table );
213
214
  }
214
215
  }
215
216
  return;
@@ -332,7 +333,7 @@
332
333
  console.log( 'Overall initialization time: ' + ts.benchmark( $.data( table, 'startoveralltimer' ) ) );
333
334
  if ( c.debug && console.groupEnd ) { console.groupEnd(); }
334
335
  }
335
- $table.trigger( 'tablesorter-initialized', table );
336
+ $table.triggerHandler( 'tablesorter-initialized', table );
336
337
  if ( typeof c.initialized === 'function' ) {
337
338
  c.initialized( table );
338
339
  }
@@ -394,7 +395,7 @@
394
395
  })
395
396
  .bind( 'applyWidgetId' + namespace, function( e, id ) {
396
397
  e.stopPropagation();
397
- ts.getWidgetById( id ).format( this, this.config, this.config.widgetOptions );
398
+ ts.applyWidgetId( this, id );
398
399
  })
399
400
  .bind( 'applyWidgets' + namespace, function( e, init ) {
400
401
  e.stopPropagation();
@@ -405,6 +406,10 @@
405
406
  e.stopPropagation();
406
407
  ts.refreshWidgets( this, all, dontapply );
407
408
  })
409
+ .bind( 'removeWidget' + namespace, function( e, name, refreshing ) {
410
+ e.stopPropagation();
411
+ ts.removeWidget( this, name, refreshing );
412
+ })
408
413
  .bind( 'destroy' + namespace, function( e, removeClasses, callback ) {
409
414
  e.stopPropagation();
410
415
  ts.destroy( this, removeClasses, callback );
@@ -517,6 +522,7 @@
517
522
  timer = new Date();
518
523
  }
519
524
  // children tr in tfoot - see issue #196 & #547
525
+ // don't pass table.config to computeColumnIndex here - widgets (math) pass it to "quickly" index tbody cells
520
526
  c.columns = ts.computeColumnIndex( c.$table.children( 'thead, tfoot' ).children( 'tr' ) );
521
527
  // add icon if cssIcon option exists
522
528
  icon = c.cssIcon ?
@@ -556,7 +562,7 @@
556
562
  // this may get updated numerous times if there are multiple rows
557
563
  c.sortVars[ column ] = {
558
564
  count : -1, // set to -1 because clicking on the header automatically adds one
559
- order: ts.formatSortingOrder( tmp ) ?
565
+ order: ts.getOrder( tmp ) ?
560
566
  [ 1, 0, 2 ] : // desc, asc, unsorted
561
567
  [ 0, 1, 2 ], // asc, desc, unsorted
562
568
  lockedOrder : false
@@ -564,7 +570,7 @@
564
570
  tmp = ts.getData( $elem, configHeaders, 'lockedOrder' ) || false;
565
571
  if ( typeof tmp !== 'undefined' && tmp !== false ) {
566
572
  c.sortVars[ column ].lockedOrder = true;
567
- c.sortVars[ column ].order = ts.formatSortingOrder( tmp ) ? [ 1, 1, 1 ] : [ 0, 0, 0 ];
573
+ c.sortVars[ column ].order = ts.getOrder( tmp ) ? [ 1, 1, 1 ] : [ 0, 0, 0 ];
568
574
  }
569
575
  // add cell to headerList
570
576
  c.headerList[ index ] = elem;
@@ -687,6 +693,12 @@
687
693
  if ( span > 0 ) {
688
694
  colIndex += span;
689
695
  max += span;
696
+ while ( span + 1 > 0 ) {
697
+ // set colspan columns to use the same parsers & extractors
698
+ list.parsers[ colIndex - span ] = parser;
699
+ list.extractors[ colIndex - span ] = extractor;
700
+ span--;
701
+ }
690
702
  }
691
703
  }
692
704
  colIndex++;
@@ -829,7 +841,7 @@
829
841
  buildCache : function( c, callback, $tbodies ) {
830
842
  var cache, val, txt, rowIndex, colIndex, tbodyIndex, $tbody, $row,
831
843
  cols, $cells, cell, cacheTime, totalRows, rowData, prevRowData,
832
- colMax, span, cacheIndex, max, len,
844
+ colMax, span, cacheIndex, hasParser, max, len, index,
833
845
  table = c.table,
834
846
  parsers = c.parsers;
835
847
  // update tbody variable
@@ -904,22 +916,31 @@
904
916
  max = c.columns;
905
917
  for ( colIndex = 0; colIndex < max; ++colIndex ) {
906
918
  cell = $row[ 0 ].cells[ colIndex ];
907
- if ( typeof parsers[ cacheIndex ] === 'undefined' ) {
908
- if ( c.debug ) {
909
- console.warn( 'No parser found for column ' + colIndex + '; cell:', cell, 'does it have a header?' );
919
+ if ( cell && cacheIndex < c.columns ) {
920
+ hasParser = typeof parsers[ cacheIndex ] !== 'undefined';
921
+ if ( !hasParser && c.debug ) {
922
+ console.warn( 'No parser found for row: ' + rowIndex + ', column: ' + colIndex +
923
+ '; cell containing: "' + $(cell).text() + '"; does it have a header?' );
910
924
  }
911
- } else if ( cell ) {
912
925
  val = ts.getElementText( c, cell, cacheIndex );
913
926
  rowData.raw[ cacheIndex ] = val; // save original row text
927
+ // save raw column text even if there is no parser set
914
928
  txt = ts.getParsedText( c, cell, cacheIndex, val );
915
929
  cols[ cacheIndex ] = txt;
916
- if ( ( parsers[ cacheIndex ].type || '' ).toLowerCase() === 'numeric' ) {
930
+ if ( hasParser && ( parsers[ cacheIndex ].type || '' ).toLowerCase() === 'numeric' ) {
917
931
  // determine column max value (ignore sign)
918
932
  colMax[ cacheIndex ] = Math.max( Math.abs( txt ) || 0, colMax[ cacheIndex ] || 0 );
919
933
  }
920
934
  // allow colSpan in tbody
921
935
  span = cell.colSpan - 1;
922
936
  if ( span > 0 ) {
937
+ index = 0;
938
+ while ( index <= span ) {
939
+ // duplicate text (or not) to spanned columns
940
+ rowData.raw[ cacheIndex + index ] = c.duplicateSpan || index === 0 ? val : '';
941
+ cols[ cacheIndex + index ] = c.duplicateSpan || index === 0 ? val : '';
942
+ index++;
943
+ }
923
944
  cacheIndex += span;
924
945
  max += span;
925
946
  }
@@ -939,7 +960,21 @@
939
960
  ts.isProcessing( table ); // remove processing icon
940
961
  }
941
962
  if ( c.debug ) {
942
- console.log( 'Building cache for ' + totalRows + ' rows' + ts.benchmark( cacheTime ) );
963
+ len = Math.min( 5, c.cache[ 0 ].normalized.length );
964
+ console[ console.group ? 'group' : 'log' ]( 'Building cache for ' + c.totalRows +
965
+ ' rows (showing ' + len + ' rows in log)' + ts.benchmark( cacheTime ) );
966
+ val = {};
967
+ for ( colIndex = 0; colIndex < c.columns; colIndex++ ) {
968
+ for ( cacheIndex = 0; cacheIndex < len; cacheIndex++ ) {
969
+ if ( !val[ 'row: ' + cacheIndex ] ) {
970
+ val[ 'row: ' + cacheIndex ] = {};
971
+ }
972
+ val[ 'row: ' + cacheIndex ][ c.$headerIndexed[ colIndex ].text() ] =
973
+ c.cache[ 0 ].normalized[ cacheIndex ][ colIndex ];
974
+ }
975
+ }
976
+ console[ console.table ? 'table' : 'log' ]( val );
977
+ if ( console.groupEnd ) { console.groupEnd(); }
943
978
  }
944
979
  if ( $.isFunction( callback ) ) {
945
980
  callback( table );
@@ -1035,7 +1070,7 @@
1035
1070
  col = parseInt( $el.attr( 'data-column' ), 10 ),
1036
1071
  end = col + c.$headers[ i ].colSpan;
1037
1072
  for ( ; col < end; col++ ) {
1038
- include = include ? ts.isValueInArray( col, c.sortList ) > -1 : false;
1073
+ include = include ? include || ts.isValueInArray( col, c.sortList ) > -1 : false;
1039
1074
  }
1040
1075
  return include;
1041
1076
  });
@@ -1140,6 +1175,14 @@
1140
1175
  col = parseInt( val[ 0 ], 10 );
1141
1176
  // prevents error if sorton array is wrong
1142
1177
  if ( col < c.columns ) {
1178
+
1179
+ // set order if not already defined - due to colspan header without associated header cell
1180
+ // adding this check prevents a javascript error
1181
+ if ( !c.sortVars[ col ].order ) {
1182
+ order = c.sortVars[ col ].order = ts.getOrder( c.sortInitialOrder ) ? [ 1, 0, 2 ] : [ 0, 1, 2 ];
1183
+ c.sortVars[ col ].count = 0;
1184
+ }
1185
+
1143
1186
  order = c.sortVars[ col ].order;
1144
1187
  dir = ( '' + val[ 1 ] ).match( /^(1|d|s|o|n)/ );
1145
1188
  dir = dir ? dir[ 0 ] : '';
@@ -1200,6 +1243,12 @@
1200
1243
  },
1201
1244
 
1202
1245
  updateCell : function( c, cell, resort, callback ) {
1246
+ if ( ts.isEmptyObject( c.cache ) ) {
1247
+ // empty table, do an update instead - fixes #1099
1248
+ ts.updateHeader( c );
1249
+ ts.commonUpdate( c, resort, callback );
1250
+ return;
1251
+ }
1203
1252
  c.table.isUpdating = true;
1204
1253
  c.$table.find( c.selectorRemove ).remove();
1205
1254
  // get position from the dom
@@ -1250,6 +1299,11 @@
1250
1299
  // problems with element focus
1251
1300
  ts.resortComplete( c, callback );
1252
1301
  }
1302
+ } else {
1303
+ if ( c.debug ) {
1304
+ console.error( 'updateCell aborted, tbody missing or not within the indicated table' );
1305
+ }
1306
+ c.table.isUpdating = false;
1253
1307
  }
1254
1308
  },
1255
1309
 
@@ -1346,7 +1400,7 @@
1346
1400
  if ( ts.isEmptyObject( cache ) ) {
1347
1401
  // run pager appender in case the table was just emptied
1348
1402
  return c.appender ? c.appender( table, rows ) :
1349
- table.isUpdating ? c.$table.trigger( 'updateComplete', table ) : ''; // Fixes #532
1403
+ table.isUpdating ? c.$table.triggerHandler( 'updateComplete', table ) : ''; // Fixes #532
1350
1404
  }
1351
1405
  if ( c.debug ) {
1352
1406
  appendTime = new Date();
@@ -1380,7 +1434,7 @@
1380
1434
  ts.applyWidget( table );
1381
1435
  }
1382
1436
  if ( table.isUpdating ) {
1383
- c.$table.trigger( 'updateComplete', table );
1437
+ c.$table.triggerHandler( 'updateComplete', table );
1384
1438
  }
1385
1439
  },
1386
1440
 
@@ -1407,6 +1461,7 @@
1407
1461
  ts.initSort( c, cell, event );
1408
1462
  }, 50 );
1409
1463
  }
1464
+
1410
1465
  var arry, indx, headerIndx, dir, temp, tmp, $header,
1411
1466
  notMultiSort = !event[ c.sortMultiSortKey ],
1412
1467
  table = c.table,
@@ -1416,7 +1471,7 @@
1416
1471
  order = c.sortVars[ col ].order;
1417
1472
 
1418
1473
  // Only call sortStart if sorting is enabled
1419
- c.$table.trigger( 'sortStart', table );
1474
+ c.$table.triggerHandler( 'sortStart', table );
1420
1475
  // get current column sort order
1421
1476
  c.sortVars[ col ].count =
1422
1477
  event[ c.sortResetKey ] ? 2 : ( c.sortVars[ col ].count + 1 ) % ( c.sortReset ? 3 : 2 );
@@ -1527,14 +1582,15 @@
1527
1582
  }
1528
1583
  }
1529
1584
  // sortBegin event triggered immediately before the sort
1530
- c.$table.trigger( 'sortBegin', table );
1585
+ c.$table.triggerHandler( 'sortBegin', table );
1531
1586
  // setTimeout needed so the processing icon shows up
1532
1587
  setTimeout( function() {
1533
1588
  // set css for headers
1534
1589
  ts.setHeadersCss( c );
1535
1590
  ts.multisort( c );
1536
1591
  ts.appendCache( c );
1537
- c.$table.trigger( 'sortEnd', table );
1592
+ c.$table.triggerHandler( 'sortBeforeEnd', table );
1593
+ c.$table.triggerHandler( 'sortEnd', table );
1538
1594
  }, 1 );
1539
1595
  },
1540
1596
 
@@ -1610,7 +1666,7 @@
1610
1666
 
1611
1667
  resortComplete : function( c, callback ) {
1612
1668
  if ( c.table.isUpdating ) {
1613
- c.$table.trigger( 'updateComplete', c.table );
1669
+ c.$table.triggerHandler( 'updateComplete', c.table );
1614
1670
  }
1615
1671
  if ( $.isFunction( callback ) ) {
1616
1672
  callback( c.table );
@@ -1642,7 +1698,7 @@
1642
1698
 
1643
1699
  sortOn : function( c, list, callback, init ) {
1644
1700
  var table = c.table;
1645
- c.$table.trigger( 'sortStart', table );
1701
+ c.$table.triggerHandler( 'sortStart', table );
1646
1702
  // update header count index
1647
1703
  ts.updateHeaderSortCount( c, list );
1648
1704
  // set css for headers
@@ -1651,11 +1707,12 @@
1651
1707
  if ( c.delayInit && ts.isEmptyObject( c.cache ) ) {
1652
1708
  ts.buildCache( c );
1653
1709
  }
1654
- c.$table.trigger( 'sortBegin', table );
1710
+ c.$table.triggerHandler( 'sortBegin', table );
1655
1711
  // sort the table and append it to the dom
1656
1712
  ts.multisort( c );
1657
1713
  ts.appendCache( c, init );
1658
- c.$table.trigger( 'sortEnd', table );
1714
+ c.$table.triggerHandler( 'sortBeforeEnd', table );
1715
+ c.$table.triggerHandler( 'sortEnd', table );
1659
1716
  ts.applyWidget( table );
1660
1717
  if ( $.isFunction( callback ) ) {
1661
1718
  callback( table );
@@ -1676,7 +1733,7 @@
1676
1733
  return ( parsers && parsers[ column ] ) ? parsers[ column ].type || '' : '';
1677
1734
  },
1678
1735
 
1679
- formatSortingOrder : function( val ) {
1736
+ getOrder : function( val ) {
1680
1737
  // look for 'd' in 'desc' order; return true
1681
1738
  return ( /^d/i.test( val ) || val === 1 );
1682
1739
  },
@@ -1836,9 +1893,54 @@
1836
1893
  }
1837
1894
  },
1838
1895
 
1896
+ applyWidgetId : function( table, id, init ) {
1897
+ var applied, time, name,
1898
+ c = table.config,
1899
+ wo = c.widgetOptions,
1900
+ widget = ts.getWidgetById( id );
1901
+ if ( widget ) {
1902
+ name = widget.id;
1903
+ applied = false;
1904
+ // add widget name to option list so it gets reapplied after sorting, filtering, etc
1905
+ if ( $.inArray( name, c.widgets ) < 0 ) {
1906
+ c.widgets.push( name );
1907
+ }
1908
+ if ( c.debug ) { time = new Date(); }
1909
+
1910
+ if ( init || !( c.widgetInit[ name ] ) ) {
1911
+ // set init flag first to prevent calling init more than once (e.g. pager)
1912
+ c.widgetInit[ name ] = true;
1913
+ if ( table.hasInitialized ) {
1914
+ // don't reapply widget options on tablesorter init
1915
+ ts.applyWidgetOptions( table );
1916
+ }
1917
+ if ( typeof widget.init === 'function' ) {
1918
+ applied = true;
1919
+ if ( c.debug ) {
1920
+ console[ console.group ? 'group' : 'log' ]( 'Initializing ' + name + ' widget' );
1921
+ }
1922
+ widget.init( table, widget, c, wo );
1923
+ }
1924
+ }
1925
+ if ( !init && typeof widget.format === 'function' ) {
1926
+ applied = true;
1927
+ if ( c.debug ) {
1928
+ console[ console.group ? 'group' : 'log' ]( 'Updating ' + name + ' widget' );
1929
+ }
1930
+ widget.format( table, c, wo, false );
1931
+ }
1932
+ if ( c.debug ) {
1933
+ if ( applied ) {
1934
+ console.log( 'Completed ' + ( init ? 'initializing ' : 'applying ' ) + name + ' widget' + ts.benchmark( time ) );
1935
+ if ( console.groupEnd ) { console.groupEnd(); }
1936
+ }
1937
+ }
1938
+ }
1939
+ },
1940
+
1839
1941
  applyWidget : function( table, init, callback ) {
1840
1942
  table = $( table )[ 0 ]; // in case this is called externally
1841
- var indx, len, names, widget, name, applied, time, time2,
1943
+ var indx, len, names, widget, time,
1842
1944
  c = table.config,
1843
1945
  widgets = [];
1844
1946
  // prevent numerous consecutive widget applications
@@ -1877,39 +1979,8 @@
1877
1979
  }
1878
1980
  for ( indx = 0; indx < len; indx++ ) {
1879
1981
  widget = widgets[ indx ];
1880
- if ( widget ) {
1881
- name = widget.id;
1882
- applied = false;
1883
- if ( c.debug ) { time2 = new Date(); }
1884
-
1885
- if ( init || !( c.widgetInit[ name ] ) ) {
1886
- // set init flag first to prevent calling init more than once (e.g. pager)
1887
- c.widgetInit[ name ] = true;
1888
- if ( table.hasInitialized ) {
1889
- // don't reapply widget options on tablesorter init
1890
- ts.applyWidgetOptions( table );
1891
- }
1892
- if ( typeof widget.init === 'function' ) {
1893
- applied = true;
1894
- if ( c.debug ) {
1895
- console[ console.group ? 'group' : 'log' ]( 'Initializing ' + name + ' widget' );
1896
- }
1897
- widget.init( table, widget, table.config, table.config.widgetOptions );
1898
- }
1899
- }
1900
- if ( !init && typeof widget.format === 'function' ) {
1901
- applied = true;
1902
- if ( c.debug ) {
1903
- console[ console.group ? 'group' : 'log' ]( 'Updating ' + name + ' widget' );
1904
- }
1905
- widget.format( table, table.config, table.config.widgetOptions, false );
1906
- }
1907
- if ( c.debug ) {
1908
- if ( applied ) {
1909
- console.log( 'Completed ' + ( init ? 'initializing ' : 'applying ' ) + name + ' widget' + ts.benchmark( time2 ) );
1910
- if ( console.groupEnd ) { console.groupEnd(); }
1911
- }
1912
- }
1982
+ if ( widget && widget.id ) {
1983
+ ts.applyWidgetId( table, widget.id, init );
1913
1984
  }
1914
1985
  }
1915
1986
  if ( c.debug && console.groupEnd ) { console.groupEnd(); }
@@ -1921,7 +1992,7 @@
1921
1992
  c.timerReady = setTimeout( function() {
1922
1993
  table.isApplyingWidgets = false;
1923
1994
  $.data( table, 'lastWidgetApplication', new Date() );
1924
- c.$table.trigger( 'tablesorter-ready' );
1995
+ c.$table.triggerHandler( 'tablesorter-ready' );
1925
1996
  }, 10 );
1926
1997
  if ( c.debug ) {
1927
1998
  widget = c.widgets.length;
@@ -1977,7 +2048,7 @@
1977
2048
  len = widgets.length,
1978
2049
  list = [],
1979
2050
  callback = function( table ) {
1980
- $( table ).trigger( 'refreshComplete' );
2051
+ $( table ).triggerHandler( 'refreshComplete' );
1981
2052
  };
1982
2053
  // remove widgets not defined in config.widgets, unless doAll is true
1983
2054
  for ( indx = 0; indx < len; indx++ ) {
@@ -2066,17 +2137,17 @@
2066
2137
  // computeTableHeaderCellIndexes from:
2067
2138
  // http://www.javascripttoolbox.com/lib/table/examples.php
2068
2139
  // http://www.javascripttoolbox.com/temp/table_cellindex.html
2069
- computeColumnIndex : function( $rows ) {
2070
- var i, j, k, l, $cell, cell, cells, rowIndex, cellId, rowSpan, colSpan, firstAvailCol,
2140
+ computeColumnIndex : function( $rows, c ) {
2141
+ var i, j, k, l, cell, cells, rowIndex, rowSpan, colSpan, firstAvailCol,
2142
+ // total columns has been calculated, use it to set the matrixrow
2143
+ columns = c && c.columns || 0,
2071
2144
  matrix = [],
2072
- matrixrow = [];
2145
+ matrixrow = new Array( columns );
2073
2146
  for ( i = 0; i < $rows.length; i++ ) {
2074
2147
  cells = $rows[ i ].cells;
2075
2148
  for ( j = 0; j < cells.length; j++ ) {
2076
2149
  cell = cells[ j ];
2077
- $cell = $( cell );
2078
2150
  rowIndex = cell.parentNode.rowIndex;
2079
- cellId = rowIndex + '-' + $cell.index();
2080
2151
  rowSpan = cell.rowSpan || 1;
2081
2152
  colSpan = cell.colSpan || 1;
2082
2153
  if ( typeof matrix[ rowIndex ] === 'undefined' ) {
@@ -2089,11 +2160,16 @@
2089
2160
  break;
2090
2161
  }
2091
2162
  }
2092
- // add data-column (setAttribute = IE8+)
2093
- if ( cell.setAttribute ) {
2163
+ // jscs:disable disallowEmptyBlocks
2164
+ if ( columns && cell.cellIndex === firstAvailCol ) {
2165
+ // don't to anything
2166
+ } else if ( cell.setAttribute ) {
2167
+ // jscs:enable disallowEmptyBlocks
2168
+ // add data-column (setAttribute = IE8+)
2094
2169
  cell.setAttribute( 'data-column', firstAvailCol );
2095
2170
  } else {
2096
- $cell.attr( 'data-column', firstAvailCol );
2171
+ // remove once we drop support for IE7 - 1/12/2016
2172
+ $( cell ).attr( 'data-column', firstAvailCol );
2097
2173
  }
2098
2174
  for ( k = rowIndex; k < rowIndex + rowSpan; k++ ) {
2099
2175
  if ( typeof matrix[ k ] === 'undefined' ) {
@@ -2302,15 +2378,16 @@
2302
2378
  $f = $t.find( 'tfoot:first > tr' ).children( 'th, td' );
2303
2379
  if ( removeClasses === false && $.inArray( 'uitheme', c.widgets ) >= 0 ) {
2304
2380
  // reapply uitheme classes, in case we want to maintain appearance
2305
- $t.trigger( 'applyWidgetId', [ 'uitheme' ] );
2306
- $t.trigger( 'applyWidgetId', [ 'zebra' ] );
2381
+ $t.triggerHandler( 'applyWidgetId', [ 'uitheme' ] );
2382
+ $t.triggerHandler( 'applyWidgetId', [ 'zebra' ] );
2307
2383
  }
2308
2384
  // remove widget added rows, just in case
2309
2385
  $h.find( 'tr' ).not( $r ).remove();
2310
- // disable tablesorter
2386
+ // disable tablesorter - not using .unbind( namespace ) because namespacing was
2387
+ // added in jQuery v1.4.3 - see http://api.jquery.com/event.namespace/
2311
2388
  events = 'sortReset update updateRows updateAll updateHeaders updateCell addRows updateComplete sorton ' +
2312
- 'appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress ' +
2313
- 'sortBegin sortEnd resetToLoadState '.split( ' ' )
2389
+ 'appendCache updateCache applyWidgetId applyWidgets refreshWidgets removeWidget destroy mouseup mouseleave ' +
2390
+ 'keypress sortBegin sortEnd resetToLoadState '.split( ' ' )
2314
2391
  .join( c.namespace + ' ' );
2315
2392
  $t
2316
2393
  .removeData( 'tablesorter' )