/*! Tablesaw - v0.1.4 - 2014-06-26
* https://github.com/filamentgroup/tablesaw
* Copyright (c) 2014 Filament Group; Licensed MIT */
;(function( $ ) {
var div = document.createElement('div'),
all = div.getElementsByTagName('i'),
$doc = $( document.documentElement );
div.innerHTML = '';
if( all[ 0 ] ) {
$doc.addClass( 'ie-lte8' );
}
// Cut the mustard
if( !( 'querySelector' in document ) || ( window.blackberry && !window.WebKitPoint ) || window.operamini ) {
return;
} else {
$doc.addClass( 'tablesaw-enhanced' );
// DOM-ready auto-init of plugins.
// Many plugins bind to an "enhance" event to init themselves on dom ready, or when new markup is inserted into the DOM
$( function(){
$( document ).trigger( "enhance.tablesaw" );
});
}
})( jQuery );
;(function( $ ) {
var pluginName = "table",
classes = {
toolbar: "tablesaw-bar"
},
events = {
create: "tablesawcreate",
destroy: "tablesawdestroy"
},
defaultMode = "stack",
initSelector = "table[data-mode],table[data-sortable]";
var Table = function( element ) {
if( !element ) {
throw new Error( "Tablesaw requires an element." );
}
this.table = element;
this.$table = $( element );
this.mode = this.$table.attr( "data-mode" ) || defaultMode;
this.init();
};
Table.prototype.init = function() {
// assign an id if there is none
if ( !this.$table.attr( "id" ) ) {
this.$table.attr( "id", pluginName + "-" + Math.round( Math.random() * 10000 ) );
}
this.createToolbar();
// Add header cells
var colstart,
thrs = this.table.querySelectorAll( "thead tr" ),
self = this;
$( thrs ).each( function(){
var coltally = 0;
$( this ).children().each( function(){
var span = parseInt( this.getAttribute( "colspan" ), 10 ),
sel = ":nth-child(" + ( coltally + 1 ) + ")";
colstart = coltally + 1;
if( span ){
for( var k = 0; k < span - 1; k++ ){
coltally++;
sel += ", :nth-child(" + ( coltally + 1 ) + ")";
}
}
// Store "cells" data on header as a reference to all cells in the same column as this TH
this.cells = self.$table.find("tr").not( $( thrs ).eq( 0 ) ).not( this ).children( sel );
coltally++;
});
});
this.$table.trigger( events.create, [ this.mode, colstart ] );
};
Table.prototype.createToolbar = function() {
// Insert the toolbar
// TODO move this into a separate component
var $toolbar = this.$table.prev( '.' + classes.toolbar );
if( !$toolbar.length ) {
$toolbar = $( '
' )
.addClass( classes.toolbar )
.insertBefore( this.$table );
}
this.$toolbar = $toolbar;
if( this.mode ) {
this.$toolbar.addClass( 'mode-' + this.mode );
}
};
Table.prototype.destroy = function() {
// Don’t remove the toolbar. Some of the table features are not yet destroy-friendly.
this.$table.prev( '.' + classes.toolbar ).each(function() {
this.className = this.className.replace( /\bmode\-\w*\b/gi, '' );
});
$( window ).off( 'resize.' + this.$table.attr( 'id' ) );
// other plugins
this.$table.trigger( events.destroy, [ this.mode ] );
this.$table.removeAttr( 'data-mode' );
this.$table.removeData( pluginName );
};
// Collection method.
$.fn[ pluginName ] = function() {
return this.each( function() {
var $t = $( this );
if( $t.data( pluginName ) ){
return;
}
var table = new Table( this );
$t.data( pluginName, table );
});
};
$( document ).on( "enhance.tablesaw", function( e ) {
$( e.target ).find( initSelector )[ pluginName ]();
});
}( jQuery ));
;(function( win, $, undefined ){
var classes = {
stackTable: 'tablesaw-stack',
cellLabels: 'tablesaw-cell-label'
};
var data = {
obj: 'tablesaw-stack'
};
var attrs = {
labelless: 'data-no-labels'
};
var Stack = function( element ) {
this.$table = $( element );
this.labelless = this.$table.is( '[' + attrs.labelless + ']' );
if( !this.labelless ) {
// allHeaders references headers, plus all THs in the thead, which may include several rows, or not
this.allHeaders = this.$table.find( "th" );
}
this.$table.data( data.obj, this );
};
Stack.prototype.init = function( colstart ) {
this.$table.addClass( classes.stackTable );
if( this.labelless ) {
return;
}
// get headers in reverse order so that top-level headers are appended last
var reverseHeaders = $( this.allHeaders );
// create the hide/show toggles
reverseHeaders.each(function(){
var $cells = $( this.cells ),
hierarchyClass = $cells.not( this ).filter( "thead th" ).length && " tablesaw-cell-label-top",
text = $(this).text();
if( text !== "" ){
if( hierarchyClass ){
var iteration = parseInt( $( this ).attr( "colspan" ), 10 ),
filter = "";
if( iteration ){
filter = "td:nth-child("+ iteration +"n + " + ( colstart ) +")";
}
$cells.filter( filter ).prepend( "
" + text + "" );
} else {
$cells.prepend( "
" + text + "" );
}
}
});
};
Stack.prototype.destroy = function() {
this.$table.removeClass( classes.stackTable );
this.$table.find( '.' + classes.cellLabels ).remove();
};
// on tablecreate, init
$( document ).on( "tablesawcreate", "table", function( e, mode, colstart ){
if( mode === 'stack' ){
var table = new Stack( this );
table.init( colstart );
}
} );
$( document ).on( "tablesawdestroy", "table", function( e, mode ){
if( mode === 'stack' ){
$( this ).data( data.obj ).destroy();
}
} );
}( this, jQuery ));
;(function( $ ) {
var pluginName = "tablesawbtn",
initSelector = ".btn",
activeClass = "btn-selected",
methods = {
_create: function(){
return $( this ).each(function() {
$( this )
.trigger( "beforecreate." + pluginName )
[ pluginName ]( "_init" )
.trigger( "create." + pluginName );
});
},
_init: function(){
var oEl = $( this ),
disabled = this.disabled !== undefined && this.disabled !== false,
input = this.getElementsByTagName( "input" )[ 0 ],
sel = this.getElementsByTagName( "select" )[ 0 ];
if( input ) {
$( this )
.addClass( "btn-" + input.type )
[ pluginName ]( "_formbtn", input );
}
if( sel ) {
$( this )
.addClass( "btn-select" )
[ pluginName ]( "_select", sel );
}
if( disabled ) {
oEl.addClass( "ui-disabled" );
}
return oEl;
},
_formbtn: function( input ) {
var active = function( el, input ) {
if( input.type === "radio" && input.checked ) {
var group = input.getAttribute( "name" );
$( "[name='" + group + "']" ).each(function() {
$( this ).parent().removeClass( activeClass );
});
el[ input.checked ? "addClass" : "removeClass" ]( activeClass );
} else if ( input.type === "checkbox" ) {
el[ input.checked ? "addClass" : "removeClass" ]( activeClass );
}
};
active( $( this ), input );
$( this ).bind("click", function() {
active( $( this ), input );
});
},
_select: function( sel ) {
var update = function( oEl, sel ) {
var opts = $( sel ).find( "option" ),
label, el, children;
opts.each(function() {
var opt = this;
if( opt.selected ) {
label = document.createTextNode( opt.text );
}
});
children = oEl.childNodes;
if( opts.length > 0 ){
for( var i = 0, l = children.length; i < l; i++ ) {
el = children[ i ];
if( el && el.nodeType === 3 ) {
oEl.replaceChild( label, el );
}
}
}
};
update( this, sel );
$( this ).bind( "change refresh", function() {
update( this, sel );
});
}
};
// Collection method.
$.fn[ pluginName ] = function( arrg, a, b, c ) {
return this.each(function() {
// if it's a method
if( arrg && typeof( arrg ) === "string" ){
return $.fn[ pluginName ].prototype[ arrg ].call( this, a, b, c );
}
// don't re-init
if( $( this ).data( pluginName + "active" ) ){
return $( this );
}
// otherwise, init
$( this ).data( pluginName + "active", true );
$.fn[ pluginName ].prototype._create.call( this );
});
};
// add methods
$.extend( $.fn[ pluginName ].prototype, methods );
$( document ).on( "enhance", function( e ) {
$( initSelector, e.target )[ pluginName ]();
});
}( jQuery ));
;(function( win, $, undefined ){
var ColumnToggle = function( element ) {
this.$table = $( element );
this.classes = {
columnToggleTable: 'tablesaw-columntoggle',
columnBtnContain: 'tablesaw-columntoggle-btnwrap tablesaw-advance',
dialogClass: this.$table.attr( 'data-dialog-class' ) || '',
columnBtn: 'tablesaw-columntoggle-btn tablesaw-nav-btn',
columnBtnSide: this.$table.attr( 'data-column-btn-side' ) || 'right',
popup: 'tablesaw-columntoggle-popup',
priorityPrefix: 'tablesaw-priority-',
// TODO duplicate class, also in tables.js
toolbar: 'tablesaw-bar'
};
this.i18n = {
columnBtnText: 'Columns',
columnsDialogError: 'No eligible columns.'
};
// Expose headers and allHeaders properties on the widget
// headers references the THs within the first TR in the table
this.headers = this.$table.find( 'tr:first > th' );
this.$table.data( 'tablesaw-coltoggle', this );
};
ColumnToggle.prototype.init = function() {
var tableId,
id,
$menuButton,
$popup,
$menu,
$btnContain,
self = this;
this.$table.addClass( this.classes.columnToggleTable );
tableId = this.$table.attr( "id" );
id = tableId + "-popup";
$btnContain = $( "
" );
$menuButton = $( "
" +
"" + this.i18n.columnBtnText + "" );
$popup = $( "" );
$menu = $( "
" );
var hasNonPersistentHeaders = false;
$( this.headers ).not( "td" ).each( function() {
var $this = $( this ),
priority = $this.attr("data-priority"),
$cells = $this.add( this.cells );
if( priority && priority !== "persist" ) {
$cells.addClass( self.classes.priorityPrefix + priority );
$("
" )
.appendTo( $menu )
.trigger('enhance')
.children( 0 )
.data( "cells", $cells );
hasNonPersistentHeaders = true;
}
});
if( !hasNonPersistentHeaders ) {
$menu.append( '
' );
}
$menu.find( '.btn' ).tablesawbtn();
$menu.appendTo( $popup );
// bind change event listeners to inputs - TODO: move to a private method?
$menu.on( "change", function(e) {
var checked = e.target.checked;
$( e.target ).data( "cells" )
.toggleClass( "tablesaw-cell-hidden", !checked )
.toggleClass( "tablesaw-cell-visible", checked );
self.$table.trigger( 'tablesawcolumns' );
});
$menuButton.appendTo( $btnContain );
$btnContain.appendTo( this.$table.prev( '.' + this.classes.toolbar ) );
$popup
.appendTo( $btnContain )
.dialog( true );
this.$menu = $menu;
$(window).on( "resize." + tableId, function(){
self.refreshToggle();
} );
this.refreshToggle();
};
ColumnToggle.prototype.refreshToggle = function() {
this.$menu.find( "input" ).each( function() {
var $this = $( this );
this.checked = $this.data( "cells" ).eq( 0 ).css( "display" ) === "table-cell";
$this.parent()[ this.checked ? "addClass" : "removeClass" ]( "btn-selected" );
});
};
ColumnToggle.prototype.refreshPriority = function(){
var self = this;
$(this.headers).not( "td" ).each( function() {
var $this = $( this ),
priority = $this.attr("data-priority"),
$cells = $this.add( this.cells );
if( priority && priority !== "persist" ) {
$cells.addClass( self.classes.priorityPrefix + priority );
} else {
$cells.each(function() {
// remove all priority classes.
this.className = this.className.replace( /\bui\-table\-priority\-\d\b/g, '' );
});
}
});
};
ColumnToggle.prototype.destroy = function() {
this.$table.removeClass( this.classes.columnToggleTable );
this.$table.find( 'th, td' ).each(function() {
var $cell = $( this );
$cell.removeClass( 'tablesaw-cell-hidden' )
.removeClass( 'tablesaw-cell-visible' );
this.className = this.className.replace( /\bui\-table\-priority\-\d\b/g, '' );
});
};
// on tablecreate, init
$( document ).on( "tablesawcreate", "table", function( e, mode ){
if( mode === 'columntoggle' ){
var table = new ColumnToggle( this );
table.init();
}
} );
$( document ).on( "tablesawdestroy", "table", function( e, mode ){
if( mode === 'columntoggle' ){
$( this ).data( 'tablesaw-coltoggle' ).destroy();
}
} );
}( this, jQuery ));
;(function( win, $, undefined ){
function createSwipeTable( $table ){
var $btns = $( "
" ),
$prevBtn = $( "
" ).appendTo( $btns ),
$nextBtn = $( "
" ).appendTo( $btns ),
hideBtn = 'disabled',
persistWidths = 'tablesaw-fix-persist',
$headerCells = $table.find( "thead th" ),
$headerCellsNoPersist = $headerCells.not( '[data-priority="persist"]' ),
headerWidths = [],
$head = $( document.head || 'head' ),
tableId = $table.attr( 'id' );
// Calculate initial widths
$table.css('width', 'auto');
$headerCells.each(function() {
headerWidths.push( $( this ).outerWidth() );
});
$table.css( 'width', '' );
$btns.appendTo( $table.prev( '.tablesaw-bar' ) );
$table.addClass( "tablesaw-swipe" );
if( !tableId ) {
tableId = 'tableswipe-' + Math.round( Math.random() * 10000 );
$table.attr( 'id', tableId );
}
function $getCells( headerCell ) {
return $( headerCell.cells ).add( headerCell );
}
function showColumn( headerCell ) {
$getCells( headerCell ).removeClass( 'tablesaw-cell-hidden' );
}
function hideColumn( headerCell ) {
$getCells( headerCell ).addClass( 'tablesaw-cell-hidden' );
}
function persistColumn( headerCell ) {
$getCells( headerCell ).addClass( 'tablesaw-cell-persist' );
}
function isPersistent( headerCell ) {
return $( headerCell ).is( '[data-priority="persist"]' );
}
function unmaintainWidths() {
$table.removeClass( persistWidths );
$( '#' + tableId + '-persist' ).remove();
}
function maintainWidths() {
var prefix = '#' + tableId + ' ',
styles = [],
tableWidth = $table.width();
$headerCells.each(function( index ) {
var width;
if( isPersistent( this ) ) {
width = $( this ).outerWidth();
// Only save width on non-greedy columns (take up less than 75% of table width)
if( width < tableWidth * 0.75 ) {
styles.push( prefix + ' .tablesaw-cell-persist:nth-child(' + ( index + 1 ) + ') { width: ' + width + 'px; }' );
}
}
});
unmaintainWidths();
$table.addClass( persistWidths );
$head.append( $( '