/*! Tablesaw - v3.0.1-beta.7 - 2017-03-10 * https://github.com/filamentgroup/tablesaw * Copyright (c) 2017 Filament Group; Licensed MIT */ // UMD module definition // From: https://github.com/umdjs/umd/blob/master/templates/jqueryPlugin.js (function (factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else if (typeof module === 'object' && module.exports) { // Node/CommonJS module.exports = function( root, jQuery ) { if ( jQuery === undefined ) { // require('jQuery') returns a factory that requires window to // build a jQuery instance, we normalize how we use modules // that require this pattern but the window provided is a noop // if it's defined (how jquery works) if ( typeof window !== 'undefined' ) { jQuery = require('jquery'); } else { jQuery = require('jquery')(root); } } factory(jQuery); return jQuery; }; } else { // Browser globals factory(jQuery); } }(function ($) { "use strict"; var win = typeof window !== "undefined" ? window : this; var Tablesaw = { i18n: { modes: [ 'Stack', 'Swipe', 'Toggle' ], columns: 'Columns', columnBtnText: 'Columns', columnsDialogError: 'No eligible columns.', sort: 'Sort' }, // cut the mustard mustard: ( 'head' in document ) && // IE9+, Firefox 4+, Safari 5.1+, Mobile Safari 4.1+, Opera 11.5+, Android 2.3+ ( !window.blackberry || window.WebKitPoint ) && // only WebKit Blackberry (OS 6+) !window.operamini }; if( Tablesaw.mustard ) { $( document.documentElement ).addClass( 'tablesaw-enhanced' ); } (function() { var pluginName = "tablesaw"; var classes = { toolbar: "tablesaw-bar" }; var events = { create: "tablesawcreate", destroy: "tablesawdestroy", refresh: "tablesawrefresh", resize: "tablesawresize" }; var defaultMode = "stack"; var initSelector = "table"; var initFilterSelector = "[data-tablesaw],[data-tablesaw-mode],[data-tablesaw-sortable]"; var defaultConfig = {}; Tablesaw.events = events; var Table = function( element ) { if( !element ) { throw new Error( "Tablesaw requires an element." ); } this.table = element; this.$table = $( element ); // only one and
are allowed, per the specification this.$thead = this.$table.children().filter( "thead" ).eq( 0 ); // multiple are allowed, per the specification this.$tbody = this.$table.children().filter( "tbody" ); this.mode = this.$table.attr( "data-tablesaw-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(); this._initCells(); this.$table.data( pluginName, this ); this.$table.trigger( events.create, [ this ] ); }; Table.prototype.getConfig = function( pluginSpecificConfig ) { // shoestring extend doesn’t support arbitrary args var configs = $.extend( defaultConfig, pluginSpecificConfig || {} ); return $.extend( configs, typeof TablesawConfig !== "undefined" ? TablesawConfig : {} ); }; Table.prototype._getPrimaryHeaderRow = function() { return this.$thead.children().filter( "tr" ).filter(function() { return !$( this ).is( "[data-tablesaw-ignorerow]" ); }).eq( 0 ); }; Table.prototype._getPrimaryHeaderRowIndex = function( $row ) { return ( $row || this._getPrimaryHeaderRow() ).prevAll().length; }; Table.prototype._getPrimaryHeaderCells = function( $row ) { return ( $row || this._getPrimaryHeaderRow() ).find( "th" ); }; Table.prototype._findPrimaryHeadersForCell = function( cell ) { var $headerRow = this._getPrimaryHeaderRow(); var $headers = this._getPrimaryHeaderCells( $headerRow ); var headerRowIndex = this._getPrimaryHeaderRowIndex( $headerRow ); var results = []; for( var rowNumber = 0; rowNumber < this.headerMapping.length; rowNumber++ ) { if( rowNumber === headerRowIndex ) { continue; } for( var colNumber = 0; colNumber < this.headerMapping[ rowNumber ].length; colNumber++ ) { if( this.headerMapping[ rowNumber ][ colNumber ] === cell ) { results.push( $headers[ colNumber ] ); } } } return results; }; // used by init cells Table.prototype.getRows = function() { var self = this; return this.$table.find( "tr" ).filter(function() { return $( this ).closest( "table" ).is( self.$table ); }); }; // used by sortable Table.prototype.getBodyRows = function( tbody ) { return ( tbody ? $( tbody ) : this.$tbody ).children().filter( "tr" ); }; Table.prototype.getHeaderCellIndex = function( cell ) { var lookup = this.headerMapping[ 0 ]; for( var colIndex = 0; colIndex < lookup.length; colIndex++ ) { if( lookup[ colIndex ] === cell ) { return colIndex; } } return -1; }; Table.prototype._initCells = function() { var $rows = this.getRows(); var columnLookup = []; $rows.each(function( rowNumber ) { columnLookup[ rowNumber ] = []; }); $rows.each(function( rowNumber ) { var coltally = 0; var $t = $( this ); var children = $t.children(); children.each(function() { var colspan = parseInt( this.getAttribute( "colspan" ), 10 ); var rowspan = parseInt( this.getAttribute( "rowspan" ), 10 ); // set in a previous rowspan while( columnLookup[ rowNumber ][ coltally ] ) { coltally++; } columnLookup[ rowNumber ][ coltally ] = this; // TODO? both colspan and rowspan if( colspan ) { for( var k = 0; k < colspan - 1; k++ ){ coltally++; columnLookup[ rowNumber ][ coltally ] = this; } } if( rowspan ) { for( var j = 1; j < rowspan; j++ ){ columnLookup[ rowNumber + j ][ coltally ] = this; } } coltally++; }); }); var primaryHeaderRowIndex = this._getPrimaryHeaderRowIndex(); for( var colNumber = 0; colNumber < columnLookup[ 0 ].length; colNumber++ ) { var headerCol = columnLookup[ primaryHeaderRowIndex ][ colNumber ]; var rowNumber = 0; var rowCell; if( !headerCol.cells ) { headerCol.cells = []; } while( rowNumber < columnLookup.length ) { rowCell = columnLookup[ rowNumber ][ colNumber ]; if( headerCol !== rowCell ) { headerCol.cells.push( rowCell ); rowCell.headerCell = headerCol; } rowNumber++; } } this.headerMapping = columnLookup; }; Table.prototype.refresh = function() { this._initCells(); this.$table.trigger( events.refresh, [ this ] ); }; Table.prototype.createToolbar = function() { // Insert the toolbar // TODO move this into a separate component var $toolbar = this.$table.prev().filter( '.' + classes.toolbar ); if( !$toolbar.length ) { $toolbar = $( '