View | Details | Raw Unified | Return to bug 36291
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/lib/datatables/datatables.css (-17 / +6 lines)
Lines 1235-1252 html.dark div.dt-button-collection { Link Here
1235
  box-shadow: 3px 4px 10px 1px rgba(0, 0, 0, 0.8);
1235
  box-shadow: 3px 4px 10px 1px rgba(0, 0, 0, 0.8);
1236
}
1236
}
1237
1237
1238
1238
/* fixedHeader 4.0.1 */
1239
table.fixedHeader-floating {
1239
table.fixedHeader-floating,
1240
  background-color: white;
1241
}
1242
1243
table.fixedHeader-floating.no-footer {
1244
  border-bottom-width: 0;
1245
}
1246
1247
table.fixedHeader-locked {
1240
table.fixedHeader-locked {
1248
  position: absolute !important;
1241
  position: relative !important;
1249
  background-color: white;
1242
  background-color: var(--dt-html-background);
1243
  background-color: var(--dt-html-background);
1250
}
1244
}
1251
1245
1252
@media print {
1246
@media print {
Lines 1254-1266 table.fixedHeader-locked { Link Here
1254
    display: none;
1248
    display: none;
1255
  }
1249
  }
1256
}
1250
}
1257
html.dark table.fixedHeader-floating {
1258
  background-color: var(--dt-html-background);
1259
}
1260
html.dark table.fixedHeader-locked {
1261
  background-color: var(--dt-html-background);
1262
}
1263
1251
1252
/* End of fixedHeader 4.0.1 */
1264
1253
1265
table.dataTable.dtr-inline.collapsed > tbody > tr > td.child,
1254
table.dataTable.dtr-inline.collapsed > tbody > tr > td.child,
1266
table.dataTable.dtr-inline.collapsed > tbody > tr > th.child,
1255
table.dataTable.dtr-inline.collapsed > tbody > tr > th.child,
(-)a/koha-tmpl/intranet-tmpl/lib/datatables/datatables.js (-146 / +298 lines)
Lines 105931-105937 return DataTable; Link Here
105931
}));
105931
}));
105932
105932
105933
105933
105934
/*! FixedHeader 3.4.0
105934
/*! FixedHeader 4.0.1
105935
 * © SpryMedia Ltd - datatables.net/license
105935
 * © SpryMedia Ltd - datatables.net/license
105936
 */
105936
 */
105937
105937
Lines 105976-105982 return DataTable; Link Here
105976
		// Browser
105976
		// Browser
105977
		factory( jQuery, window, document );
105977
		factory( jQuery, window, document );
105978
	}
105978
	}
105979
}(function( $, window, document, undefined ) {
105979
}(function( $, window, document ) {
105980
'use strict';
105980
'use strict';
105981
var DataTable = $.fn.dataTable;
105981
var DataTable = $.fn.dataTable;
105982
105982
Lines 105986-105995 var DataTable = $.fn.dataTable; Link Here
105986
 * @summary     FixedHeader
105986
 * @summary     FixedHeader
105987
 * @description Fix a table's header or footer, so it is always visible while
105987
 * @description Fix a table's header or footer, so it is always visible while
105988
 *              scrolling
105988
 *              scrolling
105989
 * @version     3.4.0
105989
 * @version     4.0.1
105990
 * @author      SpryMedia Ltd (www.sprymedia.co.uk)
105990
 * @author      SpryMedia Ltd
105991
 * @contact     www.sprymedia.co.uk
105991
 * @contact     datatables.net
105992
 * @copyright   SpryMedia Ltd.
105993
 *
105992
 *
105994
 * This source file is free software, available under the following license:
105993
 * This source file is free software, available under the following license:
105995
 *   MIT license - http://datatables.net/license/mit
105994
 *   MIT license - http://datatables.net/license/mit
Lines 106004-106009 var DataTable = $.fn.dataTable; Link Here
106004
var _instCounter = 0;
106003
var _instCounter = 0;
106005
106004
106006
var FixedHeader = function (dt, config) {
106005
var FixedHeader = function (dt, config) {
106006
	if (!DataTable.versionCheck('2')) {
106007
		throw 'Warning: FixedHeader requires DataTables 2 or newer';
106008
	}
106009
106007
	// Sanity check - you just know it will happen
106010
	// Sanity check - you just know it will happen
106008
	if (!(this instanceof FixedHeader)) {
106011
	if (!(this instanceof FixedHeader)) {
106009
		throw "FixedHeader must be initialised with the 'new' keyword.";
106012
		throw "FixedHeader must be initialised with the 'new' keyword.";
Lines 106052-106064 var FixedHeader = function (dt, config) { Link Here
106052
		header: {
106055
		header: {
106053
			host: null,
106056
			host: null,
106054
			floating: null,
106057
			floating: null,
106055
			floatingParent: $('<div class="dtfh-floatingparent">'),
106058
			floatingParent: $('<div class="dtfh-floatingparent"><div></div></div>'),
106056
			placeholder: null
106059
			placeholder: null
106057
		},
106060
		},
106058
		footer: {
106061
		footer: {
106059
			host: null,
106062
			host: null,
106060
			floating: null,
106063
			floating: null,
106061
			floatingParent: $('<div class="dtfh-floatingparent">'),
106064
			floatingParent: $('<div class="dtfh-floatingparent"><div></div></div>'),
106062
			placeholder: null
106065
			placeholder: null
106063
		}
106066
		}
106064
	};
106067
	};
Lines 106068-106074 var FixedHeader = function (dt, config) { Link Here
106068
106071
106069
	var dtSettings = dt.settings()[0];
106072
	var dtSettings = dt.settings()[0];
106070
	if (dtSettings._fixedHeader) {
106073
	if (dtSettings._fixedHeader) {
106071
		throw 'FixedHeader already initialised on table ' + dtSettings.nTable.id;
106074
		throw (
106075
			'FixedHeader already initialised on table ' + dtSettings.nTable.id
106076
		);
106072
	}
106077
	}
106073
106078
106074
	dtSettings._fixedHeader = this;
106079
	dtSettings._fixedHeader = this;
Lines 106197-106202 $.extend(FixedHeader.prototype, { Link Here
106197
106202
106198
		this._positions();
106203
		this._positions();
106199
		this._scroll(force !== undefined ? force : true);
106204
		this._scroll(force !== undefined ? force : true);
106205
		this._widths(this.dom.header);
106206
		this._widths(this.dom.footer);
106200
	},
106207
	},
106201
106208
106202
	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
106209
	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Lines 106281-106294 $.extend(FixedHeader.prototype, { Link Here
106281
106288
106282
		if (!force && itemDom.floating) {
106289
		if (!force && itemDom.floating) {
106283
			// existing floating element - reuse it
106290
			// existing floating element - reuse it
106284
			itemDom.floating.removeClass('fixedHeader-floating fixedHeader-locked');
106291
			itemDom.floating.removeClass(
106292
				'fixedHeader-floating fixedHeader-locked'
106293
			);
106285
		}
106294
		}
106286
		else {
106295
		else {
106287
			if (itemDom.floating) {
106296
			if (itemDom.floating) {
106288
				if (itemDom.placeholder !== null) {
106297
				if (itemDom.placeholder !== null) {
106289
					itemDom.placeholder.remove();
106298
					itemDom.placeholder.remove();
106290
				}
106299
				}
106291
				this._unsize(item);
106300
106292
				itemDom.floating.children().detach();
106301
				itemDom.floating.children().detach();
106293
				itemDom.floating.remove();
106302
				itemDom.floating.remove();
106294
			}
106303
			}
Lines 106300-106334 $.extend(FixedHeader.prototype, { Link Here
106300
			itemDom.floating = $(dt.table().node().cloneNode(false))
106309
			itemDom.floating = $(dt.table().node().cloneNode(false))
106301
				.attr('aria-hidden', 'true')
106310
				.attr('aria-hidden', 'true')
106302
				.css({
106311
				.css({
106303
					'table-layout': 'fixed',
106304
					top: 0,
106312
					top: 0,
106305
					left: 0
106313
					left: 0
106306
				})
106314
				})
106307
				.removeAttr('id')
106315
				.removeAttr('id');
106308
				.append(itemElement);
106309
106316
106310
			itemDom.floatingParent
106317
			itemDom.floatingParent
106311
				.css({
106318
				.css({
106312
					width: scrollBody.width(),
106319
					width: scrollBody[0].offsetWidth,
106313
					overflow: 'hidden',
106320
					overflow: 'hidden',
106314
					height: 'fit-content',
106321
					height: 'fit-content',
106315
					position: 'fixed',
106322
					position: 'fixed',
106316
					left: scrollEnabled ? tableNode.offset().left + scrollBody.scrollLeft() : 0
106323
					left: scrollEnabled
106324
						? tableNode.offset().left + scrollBody.scrollLeft()
106325
						: 0
106317
				})
106326
				})
106318
				.css(
106327
				.css(
106319
					item === 'header'
106328
					item === 'header'
106320
						? {
106329
						? {
106321
								top: this.c.headerOffset,
106330
								top: this.c.headerOffset,
106322
								bottom: ''
106331
								bottom: ''
106323
						  }
106332
						}
106324
						: {
106333
						: {
106325
								top: '',
106334
								top: '',
106326
								bottom: this.c.footerOffset
106335
								bottom: this.c.footerOffset
106327
						  }
106336
						}
106337
				)
106338
				.addClass(
106339
					item === 'footer'
106340
						? 'dtfh-floatingparent-foot'
106341
						: 'dtfh-floatingparent-head'
106328
				)
106342
				)
106329
				.addClass(item === 'footer' ? 'dtfh-floatingparentfoot' : 'dtfh-floatingparenthead')
106343
				.appendTo('body')
106330
				.append(itemDom.floating)
106344
				.children()
106331
				.appendTo('body');
106345
				.eq(0)
106346
				.append(itemDom.floating);
106332
106347
106333
			this._stickyPosition(itemDom.floating, '-');
106348
			this._stickyPosition(itemDom.floating, '-');
106334
106349
Lines 106341-106354 $.extend(FixedHeader.prototype, { Link Here
106341
			scrollLeftUpdate();
106356
			scrollLeftUpdate();
106342
			scrollBody.off('scroll.dtfh').on('scroll.dtfh', scrollLeftUpdate);
106357
			scrollBody.off('scroll.dtfh').on('scroll.dtfh', scrollLeftUpdate);
106343
106358
106359
			// Need padding on the header's container to allow for a scrollbar,
106360
			// just like how DataTables handles it
106361
			itemDom.floatingParent.children().css({
106362
				width: 'fit-content',
106363
				paddingRight: that.s.dt.settings()[0].oBrowser.barWidth
106364
			});
106365
106366
			// Blocker to hide the table behind the scrollbar - this needs to use
106367
			// fixed positioning in the container since we don't have an outer wrapper
106368
			let blocker = $(
106369
				item === 'footer'
106370
					? 'div.dtfc-bottom-blocker'
106371
					: 'div.dtfc-top-blocker',
106372
				dt.table().container()
106373
			);
106374
106375
			if (blocker.length) {
106376
				blocker
106377
					.clone()
106378
					.appendTo(itemDom.floatingParent)
106379
					.css({
106380
						position: 'fixed',
106381
						right: blocker.width()
106382
					});
106383
			}
106384
106344
			// Insert a fake thead/tfoot into the DataTable to stop it jumping around
106385
			// Insert a fake thead/tfoot into the DataTable to stop it jumping around
106345
			itemDom.placeholder = itemElement.clone(false);
106386
			itemDom.placeholder = itemElement.clone(false);
106346
			itemDom.placeholder.find('*[id]').removeAttr('id');
106387
			itemDom.placeholder.find('*[id]').removeAttr('id');
106347
106388
106389
			// Move the thead / tfoot elements around - original into the floating
106390
			// element and clone into the original table
106348
			itemDom.host.prepend(itemDom.placeholder);
106391
			itemDom.host.prepend(itemDom.placeholder);
106392
			itemDom.floating.append(itemElement);
106349
106393
106350
			// Clone widths
106394
			this._widths(itemDom);
106351
			this._matchWidths(itemDom.placeholder, itemDom.floating);
106352
		}
106395
		}
106353
	},
106396
	},
106354
106397
Lines 106367-106383 $.extend(FixedHeader.prototype, { Link Here
106367
				if ($(this).css('position') === 'sticky') {
106410
				if ($(this).css('position') === 'sticky') {
106368
					var right = $(this).css('right');
106411
					var right = $(this).css('right');
106369
					var left = $(this).css('left');
106412
					var left = $(this).css('left');
106413
					var potential;
106414
106370
					if (right !== 'auto' && !rtl) {
106415
					if (right !== 'auto' && !rtl) {
106371
						// New position either adds or dismisses the barWidth
106416
						potential = +right.replace(/px/g, '')
106372
						var potential =
106417
106373
							+right.replace(/px/g, '') +
106374
							(sign === '-' ? -1 : 1) * that.s.dt.settings()[0].oBrowser.barWidth;
106375
						$(this).css('right', potential > 0 ? potential : 0);
106418
						$(this).css('right', potential > 0 ? potential : 0);
106376
					}
106419
					}
106377
					else if (left !== 'auto' && rtl) {
106420
					else if (left !== 'auto' && rtl) {
106378
						var potential =
106421
						potential = +left.replace(/px/g, '');
106379
							+left.replace(/px/g, '') +
106422
106380
							(sign === '-' ? -1 : 1) * that.s.dt.settings()[0].oBrowser.barWidth;
106381
						$(this).css('left', potential > 0 ? potential : 0);
106423
						$(this).css('left', potential > 0 ? potential : 0);
106382
					}
106424
					}
106383
				}
106425
				}
Lines 106385-106453 $.extend(FixedHeader.prototype, { Link Here
106385
		}
106427
		}
106386
	},
106428
	},
106387
106429
106388
	/**
106389
	 * Copy widths from the cells in one element to another. This is required
106390
	 * for the footer as the footer in the main table takes its sizes from the
106391
	 * header columns. That isn't present in the footer so to have it still
106392
	 * align correctly, the sizes need to be copied over. It is also required
106393
	 * for the header when auto width is not enabled
106394
	 *
106395
	 * @param  {jQuery} from Copy widths from
106396
	 * @param  {jQuery} to   Copy widths to
106397
	 * @private
106398
	 */
106399
	_matchWidths: function (from, to) {
106400
		var get = function (name) {
106401
			return $(name, from)
106402
				.map(function () {
106403
					return (
106404
						$(this)
106405
							.css('width')
106406
							.replace(/[^\d\.]/g, '') * 1
106407
					);
106408
				})
106409
				.toArray();
106410
		};
106411
106412
		var set = function (name, toWidths) {
106413
			$(name, to).each(function (i) {
106414
				$(this).css({
106415
					width: toWidths[i],
106416
					minWidth: toWidths[i]
106417
				});
106418
			});
106419
		};
106420
106421
		var thWidths = get('th');
106422
		var tdWidths = get('td');
106423
106424
		set('th', thWidths);
106425
		set('td', tdWidths);
106426
	},
106427
106428
	/**
106429
	 * Remove assigned widths from the cells in an element. This is required
106430
	 * when inserting the footer back into the main table so the size is defined
106431
	 * by the header columns and also when auto width is disabled in the
106432
	 * DataTable.
106433
	 *
106434
	 * @param  {string} item The `header` or `footer`
106435
	 * @private
106436
	 */
106437
	_unsize: function (item) {
106438
		var el = this.dom[item].floating;
106439
106440
		if (el && (item === 'footer' || (item === 'header' && !this.s.autoWidth))) {
106441
			$('th, td', el).css({
106442
				width: '',
106443
				minWidth: ''
106444
			});
106445
		}
106446
		else if (el && item === 'header') {
106447
			$('th, td', el).css('min-width', '');
106448
		}
106449
	},
106450
106451
	/**
106430
	/**
106452
	 * Reposition the floating elements to take account of horizontal page
106431
	 * Reposition the floating elements to take account of horizontal page
106453
	 * scroll
106432
	 * scroll
Lines 106458-106470 $.extend(FixedHeader.prototype, { Link Here
106458
	 */
106437
	 */
106459
	_horizontal: function (item, scrollLeft) {
106438
	_horizontal: function (item, scrollLeft) {
106460
		var itemDom = this.dom[item];
106439
		var itemDom = this.dom[item];
106461
		var position = this.s.position;
106462
		var lastScrollLeft = this.s.scrollLeft;
106440
		var lastScrollLeft = this.s.scrollLeft;
106463
106441
106464
		if (itemDom.floating && lastScrollLeft[item] !== scrollLeft) {
106442
		if (itemDom.floating && lastScrollLeft[item] !== scrollLeft) {
106465
			// If scrolling is enabled we need to match the floating header to the body
106443
			// If scrolling is enabled we need to match the floating header to the body
106466
			if (this._scrollEnabled()) {
106444
			if (this._scrollEnabled()) {
106467
				var newScrollLeft = $($(this.s.dt.table().node()).parent()).scrollLeft();
106445
				var newScrollLeft = $(
106446
					$(this.s.dt.table().node()).parent()
106447
				).scrollLeft();
106468
				itemDom.floating.scrollLeft(newScrollLeft);
106448
				itemDom.floating.scrollLeft(newScrollLeft);
106469
				itemDom.floatingParent.scrollLeft(newScrollLeft);
106449
				itemDom.floatingParent.scrollLeft(newScrollLeft);
106470
			}
106450
			}
Lines 106489-106495 $.extend(FixedHeader.prototype, { Link Here
106489
	 * @private
106469
	 * @private
106490
	 */
106470
	 */
106491
	_modeChange: function (mode, item, forceChange) {
106471
	_modeChange: function (mode, item, forceChange) {
106492
		var dt = this.s.dt;
106493
		var itemDom = this.dom[item];
106472
		var itemDom = this.dom[item];
106494
		var position = this.s.position;
106473
		var position = this.s.position;
106495
106474
Lines 106504-106518 $.extend(FixedHeader.prototype, { Link Here
106504
106483
106505
		// It isn't trivial to add a !important css attribute...
106484
		// It isn't trivial to add a !important css attribute...
106506
		var importantWidth = function (w) {
106485
		var importantWidth = function (w) {
106507
			itemDom.floating.attr('style', function (i, s) {
106486
			itemDom.floating[0].style.setProperty('width', w + 'px', 'important');
106508
				return (s || '') + 'width: ' + w + 'px !important;';
106509
			});
106510
106487
106511
			// If not scrolling also have to update the floatingParent
106488
			// If not scrolling also have to update the floatingParent
106512
			if (!scrollEnabled) {
106489
			if (!scrollEnabled) {
106513
				itemDom.floatingParent.attr('style', function (i, s) {
106490
				itemDom.floatingParent[0].style.setProperty('width', w + 'px', 'important');
106514
					return (s || '') + 'width: ' + w + 'px !important;';
106515
				});
106516
			}
106491
			}
106517
		};
106492
		};
106518
106493
Lines 106531-106538 $.extend(FixedHeader.prototype, { Link Here
106531
				itemDom.placeholder = null;
106506
				itemDom.placeholder = null;
106532
			}
106507
			}
106533
106508
106534
			this._unsize(item);
106535
106536
			if (item === 'header') {
106509
			if (item === 'header') {
106537
				itemDom.host.prepend(tablePart);
106510
				itemDom.host.prepend(tablePart);
106538
			}
106511
			}
Lines 106547-106559 $.extend(FixedHeader.prototype, { Link Here
106547
			}
106520
			}
106548
106521
106549
			if (itemDom.floatingParent) {
106522
			if (itemDom.floatingParent) {
106523
				itemDom.floatingParent.find('div.dtfc-top-blocker').remove();
106550
				itemDom.floatingParent.remove();
106524
				itemDom.floatingParent.remove();
106551
			}
106525
			}
106552
106526
106553
			$($(itemDom.host.parent()).parent()).scrollLeft(scrollBody.scrollLeft());
106527
			$($(itemDom.host.parent()).parent()).scrollLeft(
106528
				scrollBody.scrollLeft()
106529
			);
106554
		}
106530
		}
106555
		else if (mode === 'in') {
106531
		else if (mode === 'in') {
106556
			// Remove the header from the read header and insert into a fixed
106532
			// Remove the header from the real table and insert into a fixed
106557
			// positioned floating table clone
106533
			// positioned floating table clone
106558
			this._clone(item, forceChange);
106534
			this._clone(item, forceChange);
106559
106535
Lines 106568-106584 $.extend(FixedHeader.prototype, { Link Here
106568
				: position.tfootTop;
106544
				: position.tfootTop;
106569
106545
106570
			// Calculate the amount that the footer or header needs to be shuffled
106546
			// Calculate the amount that the footer or header needs to be shuffled
106571
			var shuffle =
106547
			var shuffle;
106572
				item === 'footer'
106548
106573
					? // footer and top of body isn't on screen
106549
			if (item === 'footer') {
106574
					  bodyTop > windowBottom
106550
				shuffle =
106575
						? // Yes - push the footer below
106551
					bodyTop > windowBottom
106576
						  position.tfootHeight
106552
						? position.tfootHeight // Yes - push the footer below
106577
						: // No - bottom set to the gap between the top of the body and the bottom of the window
106553
						: bodyTop + position.tfootHeight - windowBottom; // No
106578
						  bodyTop + position.tfootHeight - windowBottom
106554
			}
106579
					: // Otherwise must be a header so get the difference from the bottom of the
106555
			else {
106580
					  //  desired floating header and the bottom of the table body
106556
				// Otherwise must be a header so get the difference from the bottom of the
106581
					  windowTop + this.c.headerOffset + position.theadHeight - bodyBottom;
106557
				//  desired floating header and the bottom of the table body
106558
				shuffle =
106559
					windowTop +
106560
					this.c.headerOffset +
106561
					position.theadHeight -
106562
					bodyBottom;
106563
			}
106582
106564
106583
			// Set the top or bottom based off of the offset and the shuffle value
106565
			// Set the top or bottom based off of the offset and the shuffle value
106584
			var prop = item === 'header' ? 'top' : 'bottom';
106566
			var prop = item === 'header' ? 'top' : 'bottom';
Lines 106589-106598 $.extend(FixedHeader.prototype, { Link Here
106589
				.css(prop, val)
106571
				.css(prop, val)
106590
				.css({
106572
				.css({
106591
					left: position.left,
106573
					left: position.left,
106592
					height: item === 'header' ? position.theadHeight : position.tfootHeight,
106574
					'z-index': 3
106593
					'z-index': 2
106575
				});
106594
				})
106595
				.append(itemDom.floating);
106596
106576
106597
			importantWidth(position.width);
106577
			importantWidth(position.width);
106598
106578
Lines 106667-106686 $.extend(FixedHeader.prototype, { Link Here
106667
		position.width = tableNode.outerWidth();
106647
		position.width = tableNode.outerWidth();
106668
		position.left = tableNode.offset().left;
106648
		position.left = tableNode.offset().left;
106669
		position.theadTop = thead.offset().top;
106649
		position.theadTop = thead.offset().top;
106670
		position.tbodyTop = scrollEnabled ? scrollBody.offset().top : tbody.offset().top;
106650
		position.tbodyTop = scrollEnabled
106671
		position.tbodyHeight = scrollEnabled ? scrollBody.outerHeight() : tbody.outerHeight();
106651
			? scrollBody.offset().top
106652
			: tbody.offset().top;
106653
		position.tbodyHeight = scrollEnabled
106654
			? scrollBody.outerHeight()
106655
			: tbody.outerHeight();
106672
		position.theadHeight = thead.outerHeight();
106656
		position.theadHeight = thead.outerHeight();
106673
		position.theadBottom = position.theadTop + position.theadHeight;
106657
		position.theadBottom = position.theadTop + position.theadHeight;
106658
		position.tfootTop = position.tbodyTop + position.tbodyHeight; //tfoot.offset().top;
106674
106659
106675
		if (tfoot.length) {
106660
		if (tfoot.length) {
106676
			position.tfootTop = position.tbodyTop + position.tbodyHeight; //tfoot.offset().top;
106677
			position.tfootBottom = position.tfootTop + tfoot.outerHeight();
106661
			position.tfootBottom = position.tfootTop + tfoot.outerHeight();
106678
			position.tfootHeight = tfoot.outerHeight();
106662
			position.tfootHeight = tfoot.outerHeight();
106679
		}
106663
		}
106680
		else {
106664
		else {
106681
			position.tfootTop = position.tbodyTop + tbody.outerHeight();
106682
			position.tfootBottom = position.tfootTop;
106665
			position.tfootBottom = position.tfootTop;
106683
			position.tfootHeight = position.tfootTop;
106666
			position.tfootHeight = 0;
106684
		}
106667
		}
106685
	},
106668
	},
106686
106669
Lines 106715-106724 $.extend(FixedHeader.prototype, { Link Here
106715
		// Body Details
106698
		// Body Details
106716
		var bodyTop = scrollEnabled ? scrollOffset.top : position.tbodyTop;
106699
		var bodyTop = scrollEnabled ? scrollOffset.top : position.tbodyTop;
106717
		var bodyLeft = scrollEnabled ? scrollOffset.left : position.left;
106700
		var bodyLeft = scrollEnabled ? scrollOffset.left : position.left;
106718
		var bodyBottom = scrollEnabled ? scrollOffset.top + scrollHeight : position.tfootTop;
106701
		var bodyBottom = scrollEnabled
106719
		var bodyWidth = scrollEnabled ? scrollBody.outerWidth() : position.tbodyWidth;
106702
			? scrollOffset.top + scrollHeight
106720
106703
			: position.tfootTop;
106721
		var windowBottom = windowTop + windowHeight;
106704
		var bodyWidth = scrollEnabled
106705
			? scrollBody.outerWidth()
106706
			: position.tbodyWidth;
106722
106707
106723
		if (this.c.header) {
106708
		if (this.c.header) {
106724
			if (!this.s.enable) {
106709
			if (!this.s.enable) {
Lines 106728-106751 $.extend(FixedHeader.prototype, { Link Here
106728
			//  the scroll of the window plus the headerOffset and the height of the header
106713
			//  the scroll of the window plus the headerOffset and the height of the header
106729
			else if (
106714
			else if (
106730
				!position.visible ||
106715
				!position.visible ||
106731
				windowTop + this.c.headerOffset + position.theadHeight <= bodyTop
106716
				windowTop + this.c.headerOffset + position.theadHeight <=
106717
					bodyTop
106732
			) {
106718
			) {
106733
				headerMode = 'in-place';
106719
				headerMode = 'in-place';
106734
			}
106720
			}
106735
			// The header should be floated if
106721
			// The header should be floated if
106736
			else if (
106722
			else if (
106737
				// The scrolling plus the header offset plus the height of the header is lower than the top of the body
106723
				// The scrolling plus the header offset plus the height of the header is lower than the top of the body
106738
				windowTop + this.c.headerOffset + position.theadHeight > bodyTop &&
106724
				windowTop + this.c.headerOffset + position.theadHeight >
106725
					bodyTop &&
106739
				// And the scrolling at the top plus the header offset is above the bottom of the body
106726
				// And the scrolling at the top plus the header offset is above the bottom of the body
106740
				windowTop + this.c.headerOffset + position.theadHeight < bodyBottom
106727
				windowTop + this.c.headerOffset + position.theadHeight <
106728
					bodyBottom
106741
			) {
106729
			) {
106742
				headerMode = 'in';
106730
				headerMode = 'in';
106743
				var scrollBody = $($(this.s.dt.table().node()).parent());
106744
106731
106745
				// Further to the above, If the scrolling plus the header offset plus the header height is lower
106732
				// Further to the above, If the scrolling plus the header offset plus the header height is lower
106746
				// than the bottom of the table a shuffle is required so have to force the calculation
106733
				// than the bottom of the table a shuffle is required so have to force the calculation
106747
				if (
106734
				if (
106748
					windowTop + this.c.headerOffset + position.theadHeight > bodyBottom ||
106735
					windowTop + this.c.headerOffset + position.theadHeight >
106736
						bodyBottom ||
106749
					this.dom.header.floatingParent === undefined
106737
					this.dom.header.floatingParent === undefined
106750
				) {
106738
				) {
106751
					forceChange = true;
106739
					forceChange = true;
Lines 106756-106761 $.extend(FixedHeader.prototype, { Link Here
106756
							top: this.c.headerOffset,
106744
							top: this.c.headerOffset,
106757
							position: 'fixed'
106745
							position: 'fixed'
106758
						})
106746
						})
106747
						.children()
106748
						.eq(0)
106759
						.append(this.dom.header.floating);
106749
						.append(this.dom.header.floating);
106760
				}
106750
				}
106761
			}
106751
			}
Lines 106780-106786 $.extend(FixedHeader.prototype, { Link Here
106780
			height: 0
106770
			height: 0
106781
		};
106771
		};
106782
106772
106783
		if (this.c.footer && this.dom.tfoot.length) {
106773
		if (
106774
			this.c.footer &&
106775
			this.dom.tfoot.length &&
106776
			this.dom.tfoot.find('th, td').length
106777
		) {
106784
			if (!this.s.enable) {
106778
			if (!this.s.enable) {
106785
				footerMode = 'in-place';
106779
				footerMode = 'in-place';
106786
			}
106780
			}
Lines 106791-106797 $.extend(FixedHeader.prototype, { Link Here
106791
				footerMode = 'in-place';
106785
				footerMode = 'in-place';
106792
			}
106786
			}
106793
			else if (
106787
			else if (
106794
				bodyBottom + position.tfootHeight + this.c.footerOffset > windowBottom &&
106788
				bodyBottom + position.tfootHeight + this.c.footerOffset >
106789
					windowBottom &&
106795
				bodyTop + this.c.footerOffset < windowBottom
106790
				bodyTop + this.c.footerOffset < windowBottom
106796
			) {
106791
			) {
106797
				footerMode = 'in';
106792
				footerMode = 'in';
Lines 106852-106863 $.extend(FixedHeader.prototype, { Link Here
106852
106847
106853
				// Need some rounding here as sometimes very small decimal places are encountered
106848
				// Need some rounding here as sometimes very small decimal places are encountered
106854
				// If the actual height is bigger or equal to the height we just applied then the footer is "Floating"
106849
				// If the actual height is bigger or equal to the height we just applied then the footer is "Floating"
106855
				if (Math.round(scrollBody.outerHeight()) >= Math.round(newHeight)) {
106850
				if (
106851
					Math.round(scrollBody.outerHeight()) >=
106852
					Math.round(newHeight)
106853
				) {
106856
					$(this.dom.tfoot.parent()).addClass('fixedHeader-floating');
106854
					$(this.dom.tfoot.parent()).addClass('fixedHeader-floating');
106857
				}
106855
				}
106858
				// Otherwise max-width has kicked in so it is not floating
106856
				// Otherwise max-width has kicked in so it is not floating
106859
				else {
106857
				else {
106860
					$(this.dom.tfoot.parent()).removeClass('fixedHeader-floating');
106858
					$(this.dom.tfoot.parent()).removeClass(
106859
						'fixedHeader-floating'
106860
					);
106861
				}
106861
				}
106862
			}
106862
			}
106863
		}
106863
		}
Lines 106875-106890 $.extend(FixedHeader.prototype, { Link Here
106875
		if (this.s.dt.settings()[0]._fixedColumns !== undefined) {
106875
		if (this.s.dt.settings()[0]._fixedColumns !== undefined) {
106876
			var adjustBlocker = function (side, end, el) {
106876
			var adjustBlocker = function (side, end, el) {
106877
				if (el === undefined) {
106877
				if (el === undefined) {
106878
					var blocker = $('div.dtfc-' + side + '-' + end + '-blocker');
106878
					var blocker = $(
106879
						'div.dtfc-' + side + '-' + end + '-blocker'
106880
					);
106879
106881
106880
					el = blocker.length === 0 ? null : blocker.clone().css('z-index', 1);
106882
					el =
106883
						blocker.length === 0
106884
							? null
106885
							: blocker.clone().css('z-index', 1);
106881
				}
106886
				}
106882
106887
106883
				if (el !== null) {
106888
				if (el !== null) {
106884
					if (headerMode === 'in' || headerMode === 'below') {
106889
					if (headerMode === 'in' || headerMode === 'below') {
106885
						el.appendTo('body').css({
106890
						el.appendTo('body').css({
106886
							top: end === 'top' ? header.offset.top : footer.offset.top,
106891
							top:
106887
							left: side === 'right' ? bodyLeft + bodyWidth - el.width() : bodyLeft
106892
								end === 'top'
106893
									? header.offset.top
106894
									: footer.offset.top,
106895
							left:
106896
								side === 'right'
106897
									? bodyLeft + bodyWidth - el.width()
106898
									: bodyLeft
106888
						});
106899
						});
106889
					}
106900
					}
106890
					else {
106901
					else {
Lines 106901-106907 $.extend(FixedHeader.prototype, { Link Here
106901
				'top',
106912
				'top',
106902
				this.dom.header.rightBlocker
106913
				this.dom.header.rightBlocker
106903
			);
106914
			);
106904
			this.dom.header.leftBlocker = adjustBlocker('left', 'top', this.dom.header.leftBlocker);
106915
			this.dom.header.leftBlocker = adjustBlocker(
106916
				'left',
106917
				'top',
106918
				this.dom.header.leftBlocker
106919
			);
106905
			this.dom.footer.rightBlocker = adjustBlocker(
106920
			this.dom.footer.rightBlocker = adjustBlocker(
106906
				'right',
106921
				'right',
106907
				'bottom',
106922
				'bottom',
Lines 106925-106930 $.extend(FixedHeader.prototype, { Link Here
106925
			return true;
106940
			return true;
106926
		}
106941
		}
106927
		return false;
106942
		return false;
106943
	},
106944
106945
	/**
106946
	 * Realign columns by using the colgroup tag and
106947
	 * checking column widths
106948
	 */
106949
	_widths: function (itemDom) {
106950
		if (! itemDom || ! itemDom.placeholder) {
106951
			return;
106952
		}
106953
106954
		// Match the table overall width
106955
		var tableNode = $(this.s.dt.table().node());
106956
		var scrollBody = $(tableNode.parent());
106957
106958
		itemDom.floatingParent.css('width', scrollBody[0].offsetWidth);
106959
		itemDom.floating.css('width', tableNode[0].offsetWidth);
106960
106961
		// Strip out the old colgroup
106962
		$('colgroup', itemDom.floating).remove();
106963
106964
		// Copy the `colgroup` element to define the number of columns - needed
106965
		// for complex header cases where a column might not have a unique
106966
		// header
106967
		var cols = itemDom.placeholder
106968
			.parent()
106969
			.find('colgroup')
106970
			.clone()
106971
			.appendTo(itemDom.floating)
106972
			.find('col');
106973
106974
		// However, the widths defined in the colgroup from the DataTable might
106975
		// not exactly reflect the actual widths of the columns (content can
106976
		// force it to stretch). So we need to copy the actual widths into the
106977
		// colgroup / col's used for the floating header.
106978
		var widths = this.s.dt.columns(':visible').widths();
106979
106980
		for (var i=0 ; i<widths.length ; i++) {
106981
			cols.eq(i).css('width', widths[i]);
106982
		}
106928
	}
106983
	}
106929
});
106984
});
106930
106985
Lines 106933-106939 $.extend(FixedHeader.prototype, { Link Here
106933
 * @type {String}
106988
 * @type {String}
106934
 * @static
106989
 * @static
106935
 */
106990
 */
106936
FixedHeader.version = '3.4.0';
106991
FixedHeader.version = '4.0.1';
106937
106992
106938
/**
106993
/**
106939
 * Defaults
106994
 * Defaults
Lines 106947-106952 FixedHeader.defaults = { Link Here
106947
	footerOffset: 0
107002
	footerOffset: 0
106948
};
107003
};
106949
107004
107005
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
107006
 * DataTables interfaces
107007
 */
107008
107009
// Attach for constructor access
107010
$.fn.dataTable.FixedHeader = FixedHeader;
107011
$.fn.DataTable.FixedHeader = FixedHeader;
107012
107013
// DataTables creation - check if the FixedHeader option has been defined on the
107014
// table and if so, initialise
107015
$(document).on('init.dt.dtfh', function (e, settings, json) {
107016
	if (e.namespace !== 'dt') {
107017
		return;
107018
	}
107019
107020
	var init = settings.oInit.fixedHeader;
107021
	var defaults = DataTable.defaults.fixedHeader;
107022
107023
	if ((init || defaults) && !settings._fixedHeader) {
107024
		var opts = $.extend({}, defaults, init);
107025
107026
		if (init !== false) {
107027
			new FixedHeader(settings, opts);
107028
		}
107029
	}
107030
});
107031
107032
// DataTables API methods
107033
DataTable.Api.register('fixedHeader()', function () { });
107034
107035
DataTable.Api.register('fixedHeader.adjust()', function () {
107036
	return this.iterator('table', function (ctx) {
107037
		var fh = ctx._fixedHeader;
107038
107039
		if (fh) {
107040
			fh.update();
107041
		}
107042
	});
107043
});
107044
107045
DataTable.Api.register('fixedHeader.enable()', function (flag) {
107046
	return this.iterator('table', function (ctx) {
107047
		var fh = ctx._fixedHeader;
107048
107049
		flag = flag !== undefined ? flag : true;
107050
		if (fh && flag !== fh.enabled()) {
107051
			fh.enable(flag);
107052
		}
107053
	});
107054
});
107055
107056
DataTable.Api.register('fixedHeader.enabled()', function () {
107057
	if (this.context.length) {
107058
		var fh = this.context[0]._fixedHeader;
107059
107060
		if (fh) {
107061
			return fh.enabled();
107062
		}
107063
	}
107064
107065
	return false;
107066
});
107067
107068
DataTable.Api.register('fixedHeader.disable()', function () {
107069
	return this.iterator('table', function (ctx) {
107070
		var fh = ctx._fixedHeader;
107071
107072
		if (fh && fh.enabled()) {
107073
			fh.enable(false);
107074
		}
107075
	});
107076
});
107077
107078
$.each(['header', 'footer'], function (i, el) {
107079
	DataTable.Api.register('fixedHeader.' + el + 'Offset()', function (offset) {
107080
		var ctx = this.context;
107081
107082
		if (offset === undefined) {
107083
			return ctx.length && ctx[0]._fixedHeader
107084
				? ctx[0]._fixedHeader[el + 'Offset']()
107085
				: undefined;
107086
		}
107087
107088
		return this.iterator('table', function (ctx) {
107089
			var fh = ctx._fixedHeader;
107090
107091
			if (fh) {
107092
				fh[el + 'Offset'](offset);
107093
			}
107094
		});
107095
	});
107096
});
107097
107098
107099
return DataTable;
107100
}));
107101
107102
106950
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
107103
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
106951
 * DataTables interfaces
107104
 * DataTables interfaces
106952
 */
107105
 */
106953
- 

Return to bug 36291