1 /*! PageResize for DataTables v1.0.0
2 * 2015 SpryMedia Ltd - datatables.net/license
7 * @description Automatically alter the DataTables page length to fit the table
10 * @file dataTables.pageResize.js
11 * @author SpryMedia Ltd (www.sprymedia.co.uk)
12 * @contact www.sprymedia.co.uk/contact
13 * @copyright Copyright 2015 SpryMedia Ltd.
15 * License MIT - http://datatables.net/license/mit
17 * This feature plug-in for DataTables will automatically change the DataTables
18 * page length in order to fit inside its container. This can be particularly
19 * useful for control panels and other interfaces which resize dynamically with
20 * the user's browser window instead of scrolling.
22 * Page resizing in DataTables can be enabled by using any one of the following
25 * * Adding the class `pageResize` to the HTML table
26 * * Setting the `pageResize` parameter in the DataTables initialisation to
27 * be true - i.e. `pageResize: true`
28 * * Setting the `pageResize` parameter to be true in the DataTables
29 * defaults (thus causing all tables to have this feature) - i.e.
30 * `$.fn.dataTable.defaults.pageResize = true`.
31 * * Creating a new instance: `new $.fn.dataTable.PageResize( table );` where
32 * `table` is a DataTable's API instance.
34 * For more detailed information please see:
35 * http://datatables.net/blog/2015-04-10
38 if ( typeof define === 'function' && define.amd ) {
40 define( ['jquery', 'datatables.net'], function ( $ ) {
41 return factory( $, window, document );
44 else if ( typeof exports === 'object' ) {
46 module.exports = function (root, $) {
51 if ( ! $ || ! $.fn.dataTable ) {
52 $ = require('datatables.net')(root, $).$;
55 return factory( $, root, root.document );
60 factory( jQuery, window, document );
62 }(function( $, window, document, undefined ) {
66 var PageResize = function ( dt, pageResizeManualDelta )
68 var table = dt.table();
72 host: $(table.container()).parent(),
73 header: $(table.header()),
74 footer: $(table.footer()),
75 body: $(table.body()),
76 container: $(table.container()),
77 table: $(table.node()),
78 delta: pageResizeManualDelta
82 offsetTop: this._getOffsetTop(),
83 tableHeight: this._getTableHeight(),
84 containerHeight: this._getContainerHeight(),
85 headerHeight: this._getHeaderHeight(),
86 footerHeight: this._getFooterHeight()
89 var host = this.s.host;
90 if ( host.css('position') === 'static' ) {
91 host.css( 'position', 'relative' );
94 var onDestroy = function () {
95 dt.off('.pageResize', onDestroy);
96 this.s.obj && this.s.obj.remove();
98 dt.on('destroy.pageResize', onDestroy);
102 // Delay the initial sizing until the table is fully initialized
103 // such that the pagination element is also added and can be taken
105 var initEvent = 'init.pageResize';
106 dt.on(initEvent, function () {
113 PageResize.prototype = {
116 var settings = this.s;
117 var dt = settings.dt;
119 var rows = $( 'tr', settings.body );
120 var rowHeight = rows.eq( rows.length > 1 ? 1 : 0 ).height(); // Attempt to use the second row if poss, for top and bottom border
121 var availableHeight = settings.host.height();
122 var scrolling = t.header().parentNode !== t.body().parentNode;
123 var delta = settings.delta;
125 var offsetTop = this.sizes.offsetTop = this._getOffsetTop();
126 var tableHeight = this.sizes.tableHeight = this._getTableHeight();
127 var containerHeight = this.sizes.containerHeight = this._getContainerHeight();
128 var headerHeight = this.sizes.headerHeight = this._getHeaderHeight();
129 var footerHeight = this.sizes.footerHeight = this._getFooterHeight();
131 // Subtract the height of the header, footer and the elements
132 // surrounding the table
135 availableHeight -= headerHeight;
138 availableHeight -= footerHeight;
141 availableHeight -= offsetTop;
142 availableHeight -= containerHeight - ( offsetTop + tableHeight );
144 if ( !isNaN( parseFloat( delta ) ) && isFinite( delta ) ) {
145 availableHeight -= delta;
148 var drawRows = Math.floor( availableHeight / rowHeight );
150 if ( drawRows !== Infinity && drawRows !== -Infinity &&
151 ! isNaN( drawRows ) && drawRows > 0 &&
152 drawRows !== dt.page.len()
154 dt.page.len( drawRows ).draw();
158 _attach: function () {
159 // There is no `resize` event for elements, so to trigger this effect,
160 // create an empty HTML document using an <object> which will issue a
161 // resize event inside itself when the document resizes. Since it is
162 // 100% x 100% that will occur whenever the host element is resized.
164 var obj = $('<object/>')
166 position: 'absolute',
173 .attr( 'type', 'text/html' );
175 obj[0].onload = function () {
176 var body = this.contentDocument.body;
177 var height = body.offsetHeight;
179 this.contentDocument.defaultView.onresize = function () {
181 var newHeight = body.clientHeight || body.offsetHeight;
182 if (newHeight !== height) {
188 // Width changes might lead to layout changes, which might require
189 // resizing the table
190 if (that.sizes.offsetTop !== that._getOffsetTop()
191 || that.sizes.containerHeight !== that._getContainerHeight()
192 || that.sizes.tableHeight !== that._getTableHeight()
193 || that.sizes.headerHeight !== that._getHeaderHeight()
194 || that.sizes.footerHeight !== that._getFooterHeight()) {
203 .appendTo( this.s.host )
204 .attr( 'data', 'about:blank' );
209 _getOffsetTop: function () { return $(this.s.table).offset().top; },
210 _getTableHeight: function () { return this.s.table.height(); },
211 _getContainerHeight: function () { return this.s.container.height(); },
212 _getHeaderHeight: function () { return this.s.dt.table().header() ? this.s.header.height() : 0; },
213 _getFooterHeight: function () { return this.s.dt.table().footer() ? this.s.footer.height() : 0; }
218 $.fn.dataTable.PageResize = PageResize;
219 $.fn.DataTable.PageResize = PageResize;
221 // Automatic initialisation listener
222 $(document).on( 'preInit.dt', function ( e, settings ) {
223 if ( e.namespace !== 'dt' ) {
227 var api = new $.fn.dataTable.Api( settings );
229 if ( $( api.table().node() ).hasClass( 'pageResize' ) ||
230 settings.oInit.pageResize ||
231 $.fn.dataTable.defaults.pageResize )
233 new PageResize( api, settings.oInit.pageResizeManualDelta );