/*! Responsive 1.0.6 * 2014-2015 SpryMedia Ltd - datatables.net/license */ /** * @summary Responsive * @description Responsive tables plug-in for DataTables * @version 1.0.6 * @file dataTables.responsive.js * @author SpryMedia Ltd (www.sprymedia.co.uk) * @contact www.sprymedia.co.uk/contact * @copyright Copyright 2014-2015 SpryMedia Ltd. * * This source file is free software, available under the following license: * MIT license - http://datatables.net/license/mit * * This source file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. * * For details please refer to: http://www.datatables.net */ (function(window, document, undefined) { var factory = function( $, DataTable ) { "use strict"; /** * Responsive is a plug-in for the DataTables library that makes use of * DataTables' ability to change the visibility of columns, changing the * visibility of columns so the displayed columns fit into the table container. * The end result is that complex tables will be dynamically adjusted to fit * into the viewport, be it on a desktop, tablet or mobile browser. * * Responsive for DataTables has two modes of operation, which can used * individually or combined: * * * Class name based control - columns assigned class names that match the * breakpoint logic can be shown / hidden as required for each breakpoint. * * Automatic control - columns are automatically hidden when there is no * room left to display them. Columns removed from the right. * * In additional to column visibility control, Responsive also has built into * options to use DataTables' child row display to show / hide the information * from the table that has been hidden. There are also two modes of operation * for this child row display: * * * Inline - when the control element that the user can use to show / hide * child rows is displayed inside the first column of the table. * * Column - where a whole column is dedicated to be the show / hide control. * * Initialisation of Responsive is performed by: * * * Adding the class `responsive` or `dt-responsive` to the table. In this case * Responsive will automatically be initialised with the default configuration * options when the DataTable is created. * * Using the `responsive` option in the DataTables configuration options. This * can also be used to specify the configuration options, or simply set to * `true` to use the defaults. * * @class * @param {object} settings DataTables settings object for the host table * @param {object} [opts] Configuration options * @requires jQuery 1.7+ * @requires DataTables 1.10.1+ * * @example * $('#example').DataTable( { * responsive: true * } ); * } ); */ var Responsive = function ( settings, opts ) { // Sanity check that we are using DataTables 1.10 or newer if ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.1' ) ) { throw 'DataTables Responsive requires DataTables 1.10.1 or newer'; } this.s = { dt: new DataTable.Api( settings ), columns: [] }; // Check if responsive has already been initialised on this table if ( this.s.dt.settings()[0].responsive ) { return; } // details is an object, but for simplicity the user can give it as a string if ( opts && typeof opts.details === 'string' ) { opts.details = { type: opts.details }; } this.c = $.extend( true, {}, Responsive.defaults, DataTable.defaults.responsive, opts ); settings.responsive = this; this._constructor(); }; Responsive.prototype = { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constructor */ /** * Initialise the Responsive instance * * @private */ _constructor: function () { var that = this; var dt = this.s.dt; dt.settings()[0]._responsive = this; // Use DataTables' private throttle function to avoid processor thrashing $(window).on( 'resize.dtr orientationchange.dtr', dt.settings()[0].oApi._fnThrottle( function () { that._resize(); } ) ); // Destroy event handler dt.on( 'destroy.dtr', function () { $(window).off( 'resize.dtr orientationchange.dtr draw.dtr' ); } ); // Reorder the breakpoints array here in case they have been added out // of order this.c.breakpoints.sort( function (a, b) { return a.width < b.width ? 1 : a.width > b.width ? -1 : 0; } ); // Determine which columns are already hidden, and should therefore // remain hidden. todo - should this be done? See thread 22677 // // this.s.alwaysHidden = dt.columns(':hidden').indexes(); this._classLogic(); this._resizeAuto(); // Details handler var details = this.c.details; if ( details.type ) { that._detailsInit(); this._detailsVis(); dt.on( 'column-visibility.dtr', function () { that._detailsVis(); } ); // Redraw the details box on each draw. This is used until // DataTables implements a native `updated` event for rows dt.on( 'draw.dtr', function () { dt.rows( {page: 'current'} ).iterator( 'row', function ( settings, idx ) { var row = dt.row( idx ); if ( row.child.isShown() ) { var info = that.c.details.renderer( dt, idx ); row.child( info, 'child' ).show(); } } ); } ); $(dt.table().node()).addClass( 'dtr-'+details.type ); } // First pass - draw the table for the current viewport size this._resize(); }, /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Private methods */ /** * Calculate the visibility for the columns in a table for a given * breakpoint. The result is pre-determined based on the class logic if * class names are used to control all columns, but the width of the table * is also used if there are columns which are to be automatically shown * and hidden. * * @param {string} breakpoint Breakpoint name to use for the calculation * @return {array} Array of boolean values initiating the visibility of each * column. * @private */ _columnsVisiblity: function ( breakpoint ) { var dt = this.s.dt; var columns = this.s.columns; var i, ien; // Class logic - determine which columns are in this breakpoint based // on the classes. If no class control (i.e. `auto`) then `-` is used // to indicate this to the rest of the function var display = $.map( columns, function ( col ) { return col.auto && col.minWidth === null ? false : col.auto === true ? '-' : $.inArray( breakpoint, col.includeIn ) !== -1; } ); // Auto column control - first pass: how much width is taken by the // ones that must be included from the non-auto columns var requiredWidth = 0; for ( i=0, ien=display.length ; i