app/assets/javascripts/dataTables/extras/dataTables.scroller.js in jquery-datatables-rails-3.3.0 vs app/assets/javascripts/dataTables/extras/dataTables.scroller.js in jquery-datatables-rails-3.4.0

- old
+ new

@@ -1,17 +1,17 @@ -/*! Scroller 1.2.2 - * ©2011-2014 SpryMedia Ltd - datatables.net/license +/*! Scroller 1.4.0 + * ©2011-2015 SpryMedia Ltd - datatables.net/license */ /** * @summary Scroller * @description Virtual rendering for DataTables - * @version 1.2.2 + * @version 1.4.0 * @file dataTables.scroller.js * @author SpryMedia Ltd (www.sprymedia.co.uk) * @contact www.sprymedia.co.uk/contact - * @copyright Copyright 2011-2014 SpryMedia Ltd. + * @copyright Copyright 2011-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 @@ -19,16 +19,40 @@ * 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){ +(function( factory ){ + if ( typeof define === 'function' && define.amd ) { + // AMD + define( ['jquery', 'datatables.net'], function ( $ ) { + return factory( $, window, document ); + } ); + } + else if ( typeof exports === 'object' ) { + // CommonJS + module.exports = function (root, $) { + if ( ! root ) { + root = window; + } + if ( ! $ || ! $.fn.dataTable ) { + $ = require('datatables.net')(root, $).$; + } -var factory = function( $, DataTable ) { -"use strict"; + return factory( $, root, root.document ); + }; + } + else { + // Browser + factory( jQuery, window, document ); + } +}(function( $, window, document, undefined ) { +'use strict'; +var DataTable = $.fn.dataTable; + /** * Scroller is a virtual rendering plug-in for DataTables which allows large * datasets to be drawn on screen every quickly. What the virtual rendering means * is that only the visible portion of the table (and a bit to either side to make * the scrolling smooth) is drawn, while the scrolling container gives the @@ -46,47 +70,45 @@ * AFTER the 't' parameter in `dom`. * * Key features include: * <ul class="limit_length"> * <li>Speed! The aim of Scroller for DataTables is to make rendering large data sets fast</li> - * <li>Full compatibility with deferred rendering in DataTables 1.9 for maximum speed</li> + * <li>Full compatibility with deferred rendering in DataTables for maximum speed</li> * <li>Display millions of rows</li> * <li>Integration with state saving in DataTables (scrolling position is saved)</li> * <li>Easy to use</li> * </ul> * * @class * @constructor * @global - * @param {object} oDT DataTables settings object - * @param {object} [oOpts={}] Configuration object for FixedColumns. Options + * @param {object} dt DataTables settings object or API instance + * @param {object} [opts={}] Configuration object for FixedColumns. Options * are defined by {@link Scroller.defaults} * * @requires jQuery 1.7+ - * @requires DataTables 1.9.0+ + * @requires DataTables 1.10.0+ * * @example * $(document).ready(function() { - * $('#example').dataTable( { - * "sScrollY": "200px", - * "sAjaxSource": "media/dataset/large.txt", - * "sDom": "frtiS", - * "bDeferRender": true + * $('#example').DataTable( { + * "scrollY": "200px", + * "ajax": "media/dataset/large.txt", + * "dom": "frtiS", + * "deferRender": true * } ); * } ); */ -var Scroller = function ( oDTSettings, oOpts ) { +var Scroller = function ( dt, opts ) { /* Sanity check - you just know it will happen */ - if ( ! this instanceof Scroller ) - { + if ( ! (this instanceof Scroller) ) { alert( "Scroller warning: Scroller must be initialised with the 'new' keyword." ); return; } - if ( typeof oOpts == 'undefined' ) - { - oOpts = {}; + if ( opts === undefined ) { + opts = {}; } /** * Settings object which contains customisable information for the Scroller instance * @namespace @@ -97,11 +119,11 @@ /** * DataTables settings object * @type object * @default Passed in as first parameter to constructor */ - "dt": oDTSettings, + "dt": $.fn.dataTable.Api( dt ).settings()[0], /** * Pixel location of the top of the drawn table in the viewport * @type int * @default 0 @@ -191,11 +213,11 @@ loaderVisible: false }; // @todo The defaults should extend a `c` property and the internal settings // only held in the `s` property. At the moment they are mixed - this.s = $.extend( this.s, Scroller.oDefaults, oOpts ); + this.s = $.extend( this.s, Scroller.oDefaults, opts ); // Workaround for row height being read from height object (see above comment) this.s.heights.row = this.s.rowHeight; /** @@ -209,20 +231,25 @@ "scroller": null, "table": null, "loader": null }; - /* Attach the instance to the DataTables instance so it can be accessed */ + // Attach the instance to the DataTables instance so it can be accessed in + // future. Don't initialise Scroller twice on the same table + if ( this.s.dt.oScroller ) { + return; + } + this.s.dt.oScroller = this; /* Let's do it */ this._fnConstruct(); }; -Scroller.prototype = /** @lends Scroller.prototype */{ +$.extend( Scroller.prototype, { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Public methods * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @@ -408,11 +435,11 @@ this.s.viewportRows = parseInt( heights.viewport / heights.row, 10 )+1; this.s.dt._iDisplayLength = this.s.viewportRows * this.s.displayBuffer; if ( bRedraw === undefined || bRedraw ) { - this.s.dt.oInstance.fnDraw(); + this.s.dt.oInstance.fnDraw( false ); } }, @@ -436,11 +463,11 @@ } /* Insert a div element that we can use to force the DT scrolling container to * the height that would be required if the whole table was being displayed */ - this.dom.force.style.position = "absolute"; + this.dom.force.style.position = "relative"; this.dom.force.style.top = "0px"; this.dom.force.style.left = "0px"; this.dom.force.style.width = "1px"; this.dom.scroller = $('div.'+this.s.dt.oClasses.sScrollBody, this.s.dt.nTableWrapper)[0]; @@ -456,11 +483,11 @@ $(this.s.dt.nTableWrapper).addClass('DTS'); // Add a 'loading' indicator if ( this.s.loadingIndicator ) { - this.dom.loader = $('<div class="DTS_Loading">'+this.s.dt.oLanguage.sLoadingRecords+'</div>') + this.dom.loader = $('<div class="dataTables_processing DTS_Loading">'+this.s.dt.oLanguage.sLoadingRecords+'</div>') .css('display', 'none'); $(this.dom.scroller.parentNode) .css('position', 'relative') .append( this.dom.loader ); @@ -527,18 +554,23 @@ if ( this.s.dt.oLoadedState ) { this.s.topRowFloat = this.s.dt.oLoadedState.iScrollerTopRow || 0; } + $(this.s.dt.nTable).on( 'init.dt', function () { + that.fnMeasure(); + } ); + /* Destructor */ this.s.dt.aoDestroyCallback.push( { "sName": "Scroller", "fn": function () { $(window).off( 'resize.DTS' ); $(that.dom.scroller).off('touchstart.DTS scroll.DTS'); $(that.s.dt.nTableWrapper).removeClass('DTS'); $('div.DTS_Loading', that.dom.scroller.parentNode).remove(); + $(that.s.dt.nTable).off( 'init.dt' ); that.dom.table.style.position = ""; that.dom.table.style.top = ""; that.dom.table.style.left = ""; } @@ -633,13 +665,10 @@ if ( that.s.scrollDrawReq === null ) { that.s.scrollDrawReq = iScrollTop; } that.s.dt._iDisplayStart = iTopRow; - if ( that.s.dt.oApi._fnCalculateEnd ) { // Removed in 1.10 - that.s.dt.oApi._fnCalculateEnd( that.s.dt ); - } that.s.dt.oApi._fnDraw( that.s.dt ); }; /* Do the DataTables redraw based on the calculated start point - note that when * using server-side processing we introduce a small delay to not DoS the server... @@ -680,18 +709,11 @@ var coeff; // If the virtual and physical height match, then we use a linear // transform between the two, allowing the scrollbar to be linear if ( heights.virtual === heights.scroll ) { - coeff = (heights.virtual-heights.viewport) / (heights.scroll-heights.viewport); - - if ( dir === 'virtualToPhysical' ) { - return val / coeff; - } - else if ( dir === 'physicalToVirtual' ) { - return val * coeff; - } + return val; } // Otherwise, we want a non-linear scrollbar to take account of the // redrawing regions at the start and end of the table, otherwise these // can stutter badly - on large tables 30px (for example) scroll might @@ -866,11 +888,15 @@ if ( heights.scroll > max ) { heights.scroll = max; } - this.dom.force.style.height = heights.scroll+"px"; + // Minimum height so there is always a row visible (the 'no rows found' + // if reduced to zero filtering) + this.dom.force.style.height = heights.scroll > this.s.heights.row ? + heights.scroll+'px' : + this.s.heights.row+'px'; }, /** * Automatic calculation of table row height. This is just a little tricky here as using @@ -901,22 +927,14 @@ tbody.append( '<tr><td>&nbsp;</td></tr>' ); } $('div.'+dt.oClasses.sScrollBody, container).append( nTable ); - var appendTo; - if (dt._bInitComplete) { - appendTo = origTable.parentNode; - } else { - if (!this.s.dt.nHolding) { - this.s.dt.nHolding = $( '<div></div>' ).insertBefore( this.s.dt.nTable ); - } - appendTo = this.s.dt.nHolding; - } - - container.appendTo( appendTo ); + // If initialised using `dom`, use the holding element as the insert point + container.appendTo( this.s.dt.nHolding || origTable.parentNode ); this.s.heights.row = $('tr', tbody).eq(1).outerHeight(); + container.remove(); }, /** @@ -1000,11 +1018,11 @@ { $(n[i]).html( sOut ); } } } -}; +} ); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Statics @@ -1153,110 +1171,127 @@ * @type String * @default See code * @name Scroller.version * @static */ -Scroller.version = "1.2.2"; +Scroller.version = "1.4.0"; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Initialisation * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* - * Register a new feature with DataTables - */ +// Legacy `dom` parameter initialisation support if ( typeof $.fn.dataTable == "function" && typeof $.fn.dataTableExt.fnVersionCheck == "function" && - $.fn.dataTableExt.fnVersionCheck('1.9.0') ) + $.fn.dataTableExt.fnVersionCheck('1.10.0') ) { $.fn.dataTableExt.aoFeatures.push( { "fnInit": function( oDTSettings ) { var init = oDTSettings.oInit; var opts = init.scroller || init.oScroller || {}; - var oScroller = new Scroller( oDTSettings, opts ); - return oScroller.dom.wrapper; + + new Scroller( oDTSettings, opts ); }, "cFeature": "S", "sFeature": "Scroller" } ); } else { - alert( "Warning: Scroller requires DataTables 1.9.0 or greater - www.datatables.net/download"); + alert( "Warning: Scroller requires DataTables 1.10.0 or greater - www.datatables.net/download"); } +// Attach a listener to the document which listens for DataTables initialisation +// events so we can automatically initialise +$(document).on( 'preInit.dt.dtscroller', function (e, settings) { + if ( e.namespace !== 'dt' ) { + return; + } + var init = settings.oInit.scroller; + var defaults = DataTable.defaults.scroller; + + if ( init || defaults ) { + var opts = $.extend( {}, init, defaults ); + + if ( init !== false ) { + new Scroller( settings, opts ); + } + } +} ); + + // Attach Scroller to DataTables so it can be accessed as an 'extra' $.fn.dataTable.Scroller = Scroller; $.fn.DataTable.Scroller = Scroller; // DataTables 1.10 API method aliases -if ( $.fn.dataTable.Api ) { - var Api = $.fn.dataTable.Api; +var Api = $.fn.dataTable.Api; - Api.register( 'scroller()', function () { - return this; - } ); +Api.register( 'scroller()', function () { + return this; +} ); - Api.register( 'scroller().rowToPixels()', function ( rowIdx, intParse, virtual ) { - var ctx = this.context; +// Undocumented and deprecated - is it actually useful at all? +Api.register( 'scroller().rowToPixels()', function ( rowIdx, intParse, virtual ) { + var ctx = this.context; - if ( ctx.length && ctx[0].oScroller ) { - return ctx[0].oScroller.fnRowToPixels( rowIdx, intParse, virtual ); - } - // undefined - } ); + if ( ctx.length && ctx[0].oScroller ) { + return ctx[0].oScroller.fnRowToPixels( rowIdx, intParse, virtual ); + } + // undefined +} ); - Api.register( 'scroller().pixelsToRow()', function ( pixels, intParse, virtual ) { - var ctx = this.context; +// Undocumented and deprecated - is it actually useful at all? +Api.register( 'scroller().pixelsToRow()', function ( pixels, intParse, virtual ) { + var ctx = this.context; - if ( ctx.length && ctx[0].oScroller ) { - return ctx[0].oScroller.fnPixelsToRow( pixels, intParse, virtual ); + if ( ctx.length && ctx[0].oScroller ) { + return ctx[0].oScroller.fnPixelsToRow( pixels, intParse, virtual ); + } + // undefined +} ); + +// Undocumented and deprecated - use `row().scrollTo()` instead +Api.register( 'scroller().scrollToRow()', function ( row, ani ) { + this.iterator( 'table', function ( ctx ) { + if ( ctx.oScroller ) { + ctx.oScroller.fnScrollToRow( row, ani ); } - // undefined } ); - Api.register( 'scroller().scrollToRow()', function ( row, ani ) { - this.iterator( 'table', function ( ctx ) { - if ( ctx.oScroller ) { - ctx.oScroller.fnScrollToRow( row, ani ); - } - } ); + return this; +} ); - return this; - } ); +Api.register( 'row().scrollTo()', function ( ani ) { + var that = this; - Api.register( 'scroller().measure()', function ( redraw ) { - this.iterator( 'table', function ( ctx ) { - if ( ctx.oScroller ) { - ctx.oScroller.fnMeasure( redraw ); - } - } ); + this.iterator( 'row', function ( ctx, rowIdx ) { + if ( ctx.oScroller ) { + var displayIdx = that + .rows( { order: 'applied', search: 'applied' } ) + .indexes() + .indexOf( rowIdx ); - return this; + ctx.oScroller.fnScrollToRow( displayIdx, ani ); + } } ); -} + return this; +} ); -return Scroller; -}; // /factory +Api.register( 'scroller.measure()', function ( redraw ) { + this.iterator( 'table', function ( ctx ) { + if ( ctx.oScroller ) { + ctx.oScroller.fnMeasure( redraw ); + } + } ); + return this; +} ); -// Define as an AMD module if possible -if ( typeof define === 'function' && define.amd ) { - define( ['jquery', 'datatables'], factory ); -} -else if ( typeof exports === 'object' ) { - // Node/CommonJS - factory( require('jquery'), require('datatables') ); -} -else if ( jQuery && !jQuery.fn.dataTable.Scroller ) { - // Otherwise simply initialise as normal, stopping multiple evaluation - factory( jQuery, jQuery.fn.dataTable ); -} - -})(window, document); - +return Scroller; +}));