tables.stack.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * tablesaw: A set of plugins for responsive tables
  3. * Stack: switches from column layout to rows with inline labels
  4. * Copyright (c) 2013 Filament Group, Inc.
  5. * MIT License
  6. */
  7. ;(function( win, $, undefined ){
  8. var classes = {
  9. stackTable: 'tablesaw-stack',
  10. cellLabels: 'tablesaw-cell-label',
  11. cellContentLabels: 'tablesaw-cell-content'
  12. };
  13. var data = {
  14. obj: 'tablesaw-stack'
  15. };
  16. var attrs = {
  17. labelless: 'data-tablesaw-no-labels',
  18. hideempty: 'data-tablesaw-hide-empty'
  19. };
  20. var Stack = function( element ) {
  21. this.$table = $( element );
  22. this.labelless = this.$table.is( '[' + attrs.labelless + ']' );
  23. this.hideempty = this.$table.is( '[' + attrs.hideempty + ']' );
  24. if( !this.labelless ) {
  25. // allHeaders references headers, plus all THs in the thead, which may include several rows, or not
  26. this.allHeaders = this.$table.find( "th" );
  27. }
  28. this.$table.data( data.obj, this );
  29. };
  30. Stack.prototype.init = function( colstart ) {
  31. this.$table.addClass( classes.stackTable );
  32. if( this.labelless ) {
  33. return;
  34. }
  35. // get headers in reverse order so that top-level headers are appended last
  36. var reverseHeaders = $( this.allHeaders );
  37. var hideempty = this.hideempty;
  38. // create the hide/show toggles
  39. reverseHeaders.each(function(){
  40. var $t = $( this ),
  41. $cells = $( this.cells ).filter(function() {
  42. return !$( this ).parent().is( "[" + attrs.labelless + "]" ) && ( !hideempty || !$( this ).is( ":empty" ) );
  43. }),
  44. hierarchyClass = $cells.not( this ).filter( "thead th" ).length && " tablesaw-cell-label-top",
  45. // TODO reduce coupling with sortable
  46. $sortableButton = $t.find( ".tablesaw-sortable-btn" ),
  47. html = $sortableButton.length ? $sortableButton.html() : $t.html();
  48. if( html !== "" ){
  49. if( hierarchyClass ){
  50. var iteration = parseInt( $( this ).attr( "colspan" ), 10 ),
  51. filter = "";
  52. if( iteration ){
  53. filter = "td:nth-child("+ iteration +"n + " + ( colstart ) +")";
  54. }
  55. $cells.filter( filter ).prepend( "<b class='" + classes.cellLabels + hierarchyClass + "'>" + html + "</b>" );
  56. } else {
  57. $cells.wrapInner( "<span class='" + classes.cellContentLabels + "'></span>" );
  58. $cells.prepend( "<b class='" + classes.cellLabels + "'>" + html + "</b>" );
  59. }
  60. }
  61. });
  62. };
  63. Stack.prototype.destroy = function() {
  64. this.$table.removeClass( classes.stackTable );
  65. this.$table.find( '.' + classes.cellLabels ).remove();
  66. this.$table.find( '.' + classes.cellContentLabels ).each(function() {
  67. $( this ).replaceWith( this.childNodes );
  68. });
  69. };
  70. // on tablecreate, init
  71. $( document ).on( "tablesawcreate", function( e, Tablesaw, colstart ){
  72. if( Tablesaw.mode === 'stack' ){
  73. var table = new Stack( Tablesaw.table );
  74. table.init( colstart );
  75. }
  76. } );
  77. $( document ).on( "tablesawdestroy", function( e, Tablesaw ){
  78. if( Tablesaw.mode === 'stack' ){
  79. $( Tablesaw.table ).data( data.obj ).destroy();
  80. }
  81. } );
  82. }( this, jQuery ));