tables.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*global Tablesaw:true */
  2. /*
  3. * tablesaw: A set of plugins for responsive tables
  4. * Stack and Column Toggle tables
  5. * Copyright (c) 2013 Filament Group, Inc.
  6. * MIT License
  7. */
  8. if( typeof Tablesaw === "undefined" ) {
  9. Tablesaw = {
  10. i18n: {
  11. modes: [ 'Stack', 'Swipe', 'Toggle' ],
  12. columns: 'Col<span class=\"a11y-sm\">umn</span>s',
  13. columnBtnText: 'Columns',
  14. columnsDialogError: 'No eligible columns.',
  15. sort: 'Sort'
  16. },
  17. // cut the mustard
  18. mustard: 'querySelector' in document &&
  19. ( !window.blackberry || window.WebKitPoint ) &&
  20. !window.operamini
  21. };
  22. }
  23. if( !Tablesaw.config ) {
  24. Tablesaw.config = {};
  25. }
  26. if( Tablesaw.mustard ) {
  27. jQuery( document.documentElement ).addClass( 'tablesaw-enhanced' );
  28. }
  29. ;(function( $ ) {
  30. var pluginName = "table",
  31. classes = {
  32. toolbar: "tablesaw-bar"
  33. },
  34. events = {
  35. create: "tablesawcreate",
  36. destroy: "tablesawdestroy",
  37. refresh: "tablesawrefresh"
  38. },
  39. defaultMode = "stack",
  40. initSelector = "table[data-tablesaw-mode],table[data-tablesaw-sortable]";
  41. var Table = function( element ) {
  42. if( !element ) {
  43. throw new Error( "Tablesaw requires an element." );
  44. }
  45. this.table = element;
  46. this.$table = $( element );
  47. this.mode = this.$table.attr( "data-tablesaw-mode" ) || defaultMode;
  48. this.init();
  49. };
  50. Table.prototype.init = function() {
  51. // assign an id if there is none
  52. if ( !this.$table.attr( "id" ) ) {
  53. this.$table.attr( "id", pluginName + "-" + Math.round( Math.random() * 10000 ) );
  54. }
  55. this.createToolbar();
  56. var colstart = this._initCells();
  57. this.$table.trigger( events.create, [ this, colstart ] );
  58. };
  59. Table.prototype._initCells = function() {
  60. var colstart,
  61. thrs = this.table.querySelectorAll( "thead tr" ),
  62. self = this;
  63. $( thrs ).each( function(){
  64. var coltally = 0;
  65. $( this ).children().each( function(){
  66. var span = parseInt( this.getAttribute( "colspan" ), 10 ),
  67. sel = ":nth-child(" + ( coltally + 1 ) + ")";
  68. colstart = coltally + 1;
  69. if( span ){
  70. for( var k = 0; k < span - 1; k++ ){
  71. coltally++;
  72. sel += ", :nth-child(" + ( coltally + 1 ) + ")";
  73. }
  74. }
  75. // Store "cells" data on header as a reference to all cells in the same column as this TH
  76. this.cells = self.$table.find("tr").not( thrs[0] ).not( this ).children().filter( sel );
  77. coltally++;
  78. });
  79. });
  80. return colstart;
  81. };
  82. Table.prototype.refresh = function() {
  83. this._initCells();
  84. this.$table.trigger( events.refresh );
  85. };
  86. Table.prototype.createToolbar = function() {
  87. // Insert the toolbar
  88. // TODO move this into a separate component
  89. var $toolbar = this.$table.prev().filter( '.' + classes.toolbar );
  90. if( !$toolbar.length ) {
  91. $toolbar = $( '<div>' )
  92. .addClass( classes.toolbar )
  93. .insertBefore( this.$table );
  94. }
  95. this.$toolbar = $toolbar;
  96. if( this.mode ) {
  97. this.$toolbar.addClass( 'mode-' + this.mode );
  98. }
  99. };
  100. Table.prototype.destroy = function() {
  101. // Don’t remove the toolbar. Some of the table features are not yet destroy-friendly.
  102. this.$table.prev().filter( '.' + classes.toolbar ).each(function() {
  103. this.className = this.className.replace( /\bmode\-\w*\b/gi, '' );
  104. });
  105. var tableId = this.$table.attr( 'id' );
  106. $( document ).unbind( "." + tableId );
  107. $( window ).unbind( "." + tableId );
  108. // other plugins
  109. this.$table.trigger( events.destroy, [ this ] );
  110. this.$table.removeData( pluginName );
  111. };
  112. // Collection method.
  113. $.fn[ pluginName ] = function() {
  114. return this.each( function() {
  115. var $t = $( this );
  116. if( $t.data( pluginName ) ){
  117. return;
  118. }
  119. var table = new Table( this );
  120. $t.data( pluginName, table );
  121. });
  122. };
  123. $( document ).on( "enhance.tablesaw", function( e ) {
  124. // Cut the mustard
  125. if( Tablesaw.mustard ) {
  126. $( e.target ).find( initSelector )[ pluginName ]();
  127. }
  128. });
  129. }( jQuery ));