Scroller: resizing & browser zoom should now show proper widths. Fixes #680 & #634.

This commit is contained in:
Mottie 2015-01-14 13:19:02 -06:00
parent cb63aade3f
commit bc85c32190
3 changed files with 189 additions and 62 deletions

View File

@ -8,6 +8,8 @@
<script src="js/jquery-1.4.4.min.js"></script>
<!-- Demo stuff -->
<link class="ui-theme" rel="stylesheet" href="css/jquery-ui.min.css">
<script src="js/jquery-ui-latest.min.js"></script>
<link rel="stylesheet" href="css/jq.css">
<link href="css/prettify.css" rel="stylesheet">
<script src="js/prettify.js"></script>
@ -41,28 +43,40 @@
<script id="js">$(function(){
$("table").tablesorter({
$('.tablesorter').tablesorter({
theme: 'jui',
widthFixed : true,
showProcessing: true,
headerTemplate : '{content} {icon}',
widgets: [ 'uitheme', 'zebra', 'filter', 'scroller' ],
widgetOptions : {
scroller_height : 300,
scroller_barWidth : 18,
scroller_upAfterSort: true,
scroller_jumpToHeader: true,
scroller_idPrefix : 's_'
// In tablesorter v2.18.5 the scroll bar width is auto-detected
// add a value here to override the auto-detected setting
scroller_barWidth : null
// scroll_idPrefix was removed in v2.18.0
// scroller_idPrefix : 's_'
}
});
});</script>
<script>
$(function() {
$('link.theme, link.ui-theme').each(function(){ this.disabled = true; });
$('.options').tablesorter({
theme: 'jui',
headerTemplate : '{content} {icon}',
widthFixed: true,
widgets: ['uitheme','stickyHeaders']
});
$('link.theme').each(function(){ this.disabled = true; });
var b = true, $tbl,
$c = $('#case'),
themes = 'default blue green grey ice black-ice dark dropbox',
themes = 'default blue green grey ice black-ice dark dropbox metro-dark',
i, o = '', t = themes.split(' ');
for (i = 0; i < t.length; i++) {
o += '<option value="' + t[i] + '">' + t[i] + '</option>';
@ -70,19 +84,26 @@ $(function() {
$('select')
.append(o)
.val('jui')
.change(function(){
var theme = $(this).val().toLowerCase(),
name = theme === 'jui' ? 'ui-theme' : theme,
// ui-theme is added by the themeswitcher
files = $('link.theme, link.ui-theme').each(function(){
files = $('link.theme').each(function(){
this.disabled = true;
});
files.filter('.' + name).each(function(){
this.disabled = false;
});
$('table')
.removeClass('tablesorter-' + t.join(' tablesorter-') + ' tablesorter-jui')
.addClass('tablesorter-' + (theme === 'black-ice' ? 'blackice' : theme) );
// refresh uitheme widget class names
$('.tablesorter').each(function(){
if (this.config) {
this.config.theme = theme === 'black-ice' ? 'blackice' : theme;
}
});
$('table').trigger('applyWidgets');
// make sure columns align
$(window).trigger('resize');
}).change();
@ -111,32 +132,96 @@ $(function() {
<div id="main">
<p class="tip">
<em>NOTE!</em>
<ul>
<li>In <span class="version">v2.17+</span>
<ul>
<li>The scroller widget will now work properly with predefined column widths.</li>
<li>Shrinking the browser window will now hide the header overflow.</li>
<li>Horizontal scrolling of the table body will now properly horizontally scroll the header.</li>
<li>Changed the default scroll bar width from <code>17</code> to <code>18</code>.</li>
<li>Added <code>scroller_upAfterSort</code> option.</li>
</ul>
</li>
<li>This widget can not be applied to the original plugin and requires jQuery version 1.4+ to function properly; if you need to make it work with older versions of jQuery and the plugin, please use <a href="http://tconnell.com/samples/scroller/">this version</a> of the widget.</li>
<li>This widget was originally written by <a href="http://tconnell.com/samples/scroller/">Connell & Associates, Inc.</a> and is dual-licensed under the MIT and GPL licenses. It has been modified to work with tablesorter version 2.9+.</li>
<li>Scroller widget options include:
<ul>
<li><code>scroller_height</code> - Set the height of the scroll window in pixels (default is <code>300</code>).</li>
<li><code>scroller_barWidth</code> - Set the width (default is <code>17</code>) of the scroll bar in pixels. This will need to be changed if using a custom scroll bar plugin.</li>
<li><code>scroller_idPrefix</code> - This option contains a prefix string which is added to a random number. This id is then assigned to the wrapping scroll element. Modification is not necessary unless the prefix interferes with ID's already on your page.</li>
<li><code>scroller_upAfterSort</code> - when <code>true</code> (default), the scroller automatically scrolls the inner window back to the top after sorting. Set this option to <code>false</code> to prevent this, or stop the window from scrolling after interacting with a table cell (e.g. clicking on a checkbox); new in <span class="version">v2.17.3</span>.</li>
<li><code>scroller_jumpToHeader</code> - When <code>true</code>, this option makes the table header jump into view when the table body is not scolled to the top and while scrolling up the page. It's not perfect, but it works. Disable it as desired.<br>
<span class="remark">*</span> <em>To see the difference, toggle the button in the demo below, then scroll down &amp; up the page using a mouse wheel with the cursor at the horizontal center of the page and about 100 pixels from the top, so the cursor is within the table body.</em></li>
</ul>
</li>
</ul>
<p>
<p></p>
<br>
<div class="accordion">
<h3><a href="#">Notes</a></h3>
<div>
<ul>
<li>In <span class="version">v2.17+</span>
<ul>
<li>The scroller widget will now work properly with predefined column widths.</li>
<li>Shrinking the browser window will now hide the header overflow.</li>
<li>Horizontal scrolling of the table body will now properly horizontally scroll the header.</li>
<li>Changed the default scroll bar width from <code>17</code> to <code>18</code>.</li>
<li>Added <code>scroller_upAfterSort</code> option.</li>
</ul>
</li>
<li>This widget can not be applied to the original plugin and requires jQuery version 1.4+ to function properly; if you need to make it work with older versions of jQuery and the plugin, please use <a href="http://tconnell.com/samples/scroller/">this version</a> of the widget.</li>
<li>This widget was originally written by <a href="http://tconnell.com/samples/scroller/">Connell & Associates, Inc.</a> and is dual-licensed under the MIT and GPL licenses. It has been modified to work with tablesorter version 2.9+.</li>
</ul>
</div>
<h3><a href="#">Options</a></h3>
<div>
<h4>Filter widget defaults (added inside of tablesorter <code>widgetOptions</code>)</h4>
<div>
<span class="label label-info">TIP!</span> Click on the link in the function column to reveal full details (or <a href="#" class="toggleAll">toggle</a>|<a href="#" class="showAll">show</a>|<a href="#" class="hideAll">hide</a> all) or double click to update the browser location.
</div>
<table class="options tablesorter-jui" data-sortlist="[[0,0]]">
<thead>
<tr><th>Option</th><th>Default</th><th class="sorter-false">Description</th></tr>
</thead>
<tbody>
<tr id="scroller-height">
<td><span class="permalink">scroller_height</span></td>
<td>300</td>
<td>Set the height of the scroll window in pixels.</td>
</tr>
<tr id="scroller-bar-width">
<td><a href="#" class="permalink">scroller_barWidth</a></td>
<td>null</td>
<td>Set the width of the scroll bar in pixels (<span class="version">v2.18.5</span>)
<div class="collapsible">
<br>
As of <span class="version">v2.18.5</span>, this option's default was changed to <code>null</code> because internal code was added to detect the scroll bar width which changes dramatically depending on the browser window zoom level.<br>
<br>
If you are using a custom scroll bar plugin, this option will still accept a scroll bar width value which overrides the scroll bar width auto-detection.
</div>
</td>
</tr>
<tr id="scroller-id-prefix">
<td><a href="#" class="permalink alert">scroller_idPrefix</a></td>
<td>"s_"</td>
<td>This option contains a prefix string which is added to a random number (<span class="alert">Removed</span>).
<div class="collapsible">
<br>
This option was been completely removed in <span class="version alert">v2.18.0</span> as the id is now obtained from the unique namespace.
</td>
</tr>
<tr id="scroller-up-after-sort">
<td><a href="#" class="permalink">scroller_upAfterSort</a></td>
<td>true</td>
<td>
<div class="collapsible">
<br>
When <code>true</code>, the scroller automatically scrolls the inner window back to the top after sorting.<br>
<br>
Set this option to <code>false</code> to prevent this behaviour, or to stop the window from scrolling after interacting with a table cell (e.g. clicking on a checkbox); new in <span class="version">v2.17.3</span>
</td>
</tr>
<tr id="scroller-jump-to-header">
<td><a href="#" class="permalink">scroller_jumpToHeader</a></td>
<td>true</td>
<td>
<div class="collapsible">
<br>
When <code>true</code>, this option makes the table header jump into view when the table body is not scolled to the top and while scrolling up the page. It's not perfect, but it works. Disable it as desired.<br>
<br>
<span class="remark">*</span> <em>To see the difference, toggle the button in the demo below, then scroll down &amp; up the page using a mouse wheel with the cursor at the horizontal center of the page and about 100 pixels from the top, so the cursor is within the table body.</em>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h1>Javascript</h1>
<div id="javascript">
@ -150,7 +235,7 @@ $(function() {
</select><br>
<br>
<button type="button">Toggle</button> scroller_jumpToHeader : <span id="case">true</span> (see the note above)<span class="remark">*</span>
<br>
<p></p>
<table class="tablesorter">
<thead>

View File

@ -508,7 +508,7 @@
<li><a href="example-widgets.html">Repeat Headers widget</a> (v2.0.5; <span class="version updated">v2.18.0</span>)</li>
<li><span class="results">&dagger;</span> <a href="example-widget-resizable.html">Resizable Columns widget</a> (v2.0.23.1; <span class="version updated">v2.18.0</span>)</li>
<li><span class="results">&dagger;</span> <a href="example-widget-savesort.html">Save sort widget</a> (v2.0.27)</li>
<li><a href="example-widget-scroller.html">Scroller widget</a> (<span class="version">v2.9</span>; <span class="version updated">v2.18.0</span>).</li>
<li><a href="example-widget-scroller.html">Scroller widget</a> (<span class="version">v2.9</span>; <span class="version updated">v2.18.5</span>).</li>
<li><span class="label label-info">Beta</span> <a href="example-widget-static-row.html">StaticRow widget</a> (<span class="version">v2.16</span>; <span class="version updated">v2.17.3</span>).</li>
<li><span class="results">&dagger;</span> <a href="example-widget-sticky-header.html">Sticky header widget</a> (v2.0.21.1; <span class="version updated">v2.18.0</span>)</li>
<li><a href="example-widget-css-sticky-header.html">Sticky header (css3) widget</a> (<span class="version">v2.14.2</span>; <span class="version updated">v2.18.3</span>).</li>

View File

@ -10,7 +10,7 @@
Resizable scroller widget for the jQuery tablesorter plugin
Version 2.0 - modified by Rob Garrison 4/12/2013; updated 10/26/2014 (v2.18.0)
Version 2.0 - modified by Rob Garrison 4/12/2013; updated 1/15/2015 (v2.18.5)
Requires jQuery v1.7+
Requires the tablesorter plugin, v2.8+, available at http://mottie.github.com/tablesorter/docs/
@ -32,7 +32,7 @@
Website: www.tconnell.com
*/
/*jshint browser:true, jquery:true, unused:false */
;(function($){
;(function($, window){
"use strict";
$.fn.hasScrollBar = function(){
@ -52,6 +52,7 @@ ts.window_resize = function(){
// Add extra scroller css
$(function(){
var s = '<style>' +
'.tablesorter-scrollbar-measure { width: 100px; height: 100px; overflow: scroll; position: absolute; top: -9999px; } ' +
'.tablesorter-scroller-reset { width: auto !important; } ' +
'.tablesorter-scroller { text-align: left; overflow: hidden; }' +
'.tablesorter-scroller-header { overflow: hidden; }' +
@ -70,9 +71,10 @@ ts.addWidget({
priority: 60, // run after the filter widget
options: {
scroller_height : 300,
scroller_barWidth : 18,
scroller_jumpToHeader: true,
scroller_upAfterSort: true
scroller_upAfterSort: true,
// bar width is now calculated; set a value to override
scroller_barWidth : null
},
init: function(table, thisWidget, c, wo){
var $win = $(window),
@ -83,7 +85,7 @@ ts.addWidget({
.bind('resizeEnd' + namespace, function() {
// init is run before format, so scroller_resizeWidth
// won't be defined within the "c" or "wo" parameters
if (typeof table.config.widgetOptions.scroller_resizeWidth === 'function') {
if ($.isFunction(table.config.widgetOptions.scroller_resizeWidth)) {
// IE calls resize when you modify content, so we have to unbind the resize event
// so we don't end up with an infinite loop. we can rebind after we're done.
$win.unbind('resize' + namespace, ts.window_resize);
@ -93,28 +95,37 @@ ts.addWidget({
});
},
format: function(table, c, wo) {
var h, $hdr, t, resize, $cells,
var maxHt, tbHt, $hdr, resize, getBarWidth, $cells,
// c.namespace contains a unique tablesorter ID, per table
id = c.namespace.slice(1) + 'tsscroller',
$win = $(window),
$tbl = c.$table;
if (!c.isScrolling) {
h = wo.scroller_height || 300;
t = $tbl.find('tbody').height();
if (t !== 0 && h > t) { h = t + 10; } // Table is less than h px
maxHt = wo.scroller_height || 300;
tbHt = $tbl.children('tbody').height();
if (tbHt !== 0 && maxHt > tbHt) { maxHt = tbHt + 10; } // Table is less than h px
$hdr = $('<table class="' + $tbl.attr('class') + '" cellpadding=0 cellspacing=0><thead>' + $tbl.find('thead:first').html() + '</thead></table>');
$hdr = $('<table class="' + $tbl.attr('class') + '" cellpadding=0 cellspacing=0>' +
'<thead>' + $tbl.find('thead:first').html() + '</thead>' +
'</table>');
if (c.$extraTables && c.$extraTables.length) {
c.$extraTables = c.$extraTables.add($hdr);
} else {
c.$extraTables = $hdr;
}
$tbl
.wrap('<div id="' + id + '" class="tablesorter-scroller" />')
.before($hdr)
// shrink filter row but don't completely hide it because the inputs/selectors may distort the columns
.find('.tablesorter-filter-row').addClass('hideme');
$cells = $hdr
.wrap('<div class="tablesorter-scroller-header" style="width:' + $tbl.width() + ';" />')
.find('.' + ts.css.header);
$tbl.wrap('<div class="tablesorter-scroller-table" style="height:' + h + 'px;width:' + $tbl.width() + ';" />');
// use max-height, so the height resizes dynamically while filtering
$tbl.wrap('<div class="tablesorter-scroller-table" style="max-height:' + maxHt + 'px;width:' + $tbl.width() + ';" />');
// make scroller header sortable
ts.bindEvents(table, $cells);
@ -124,37 +135,59 @@ ts.addWidget({
ts.filter.bindSearch( $tbl, $hdr.find('.' + ts.css.filter) );
}
// modified from http://davidwalsh.name/detect-scrollbar-width
getBarWidth = function(){
var $scrollDiv = $('<div class="tablesorter-scrollbar-measure">').appendTo('body'),
div = $scrollDiv[0],
barWidth = div.offsetWidth - div.clientWidth;
$scrollDiv.remove();
return barWidth;
};
resize = function(){
var d, b, $h, $th, w,
// Hide other scrollers so we can resize
$div = $('div.scroller[id != "' + id + '"]').hide();
$div = $('div.tablesorter-scroller[id != "' + id + '"]').hide();
$tbl.find('thead').show();
$tbl.children('thead').show();
// only remove colgroup if it was added by the plugin
// the $.tablesorter.fixColumnWidth() function already does this (v2.18.5)
// but we need to get "accurate" resized measurements here - see issue #680
$tbl.children('colgroup.tablesorter-colgroup').remove();
$hdr.children('colgroup').remove();
// Reset sizes so parent can resize.
$tbl
.addClass('tablesorter-scroller-reset')
.find('thead').find('.tablesorter-header-inner').addClass('tablesorter-scroller-reset');
.children('thead')
.find('.tablesorter-header-inner').addClass('tablesorter-scroller-reset').end()
.find('.tablesorter-filter-row').show();
d = $tbl.parent();
d.addClass('tablesorter-scroller-reset');
d.parent().trigger('resize');
// include left & right border widths
b = parseInt( $tbl.css('border-left-width'), 10 ) + parseInt( $tbl.css('border-right-width'), 10 );
// Shrink a bit to accommodate scrollbar
d.width( d.parent().innerWidth() - ( d.parent().hasScrollBar() ? wo.scroller_barWidth : 0 ) );
w = d.innerWidth() - ( d.hasScrollBar() ? wo.scroller_barWidth : 0 );
w = ( wo.scroller_barWidth || getBarWidth() ) + b;
d.width( d.parent().innerWidth() - ( d.parent().hasScrollBar() ? w : 0 ) );
w = d.innerWidth() - ( d.hasScrollBar() ? w : 0 );
$tbl.width( w );
$hdr.width( w );
$hdr.parent().width( w );
$tbl.closest('.tablesorter-scroller').find('.tablesorter-scroller-reset').removeClass('tablesorter-scroller-reset');
$tbl
.closest('.tablesorter-scroller')
.find('.tablesorter-scroller-reset')
.removeClass('tablesorter-scroller-reset');
// include left & right border widths
b = parseInt( $tbl.css('border-left-width'), 10 ) + parseInt( $tbl.css('border-right-width'), 10 );
$h = $hdr.find('thead').children().children();
// adjust cloned header to match original table width - includes wrappers, headers, and header inner div
$tbl.find('thead').children().children().each(function(i, c){
$tbl.children('thead').children().children().each(function(i, c){
$th = $(c).find('.tablesorter-header-inner');
if ($th.length) {
// I have no idea why this is in here anymore LOL
@ -164,14 +197,23 @@ ts.addWidget({
} else {
w = $th.width();
}
$h.eq(i)
.find('.tablesorter-header-inner').width(w - b)
// set inner width first
.parent()
.width( $th.parent().width() - b );
}
});
// refresh colgroup & copy to cloned header
$.tablesorter.fixColumnWidth( table );
$h = $tbl.children('colgroup').clone();
if ($h.length) {
$hdr.prepend($h);
}
// hide filter row because filterEnd event fires
$tbl.children('thead').find('.tablesorter-filter-row').hide();
$div.show();
};
@ -183,13 +225,13 @@ ts.addWidget({
$tbl.find('thead').css('visibility', 'hidden');
c.isScrolling = true;
t = $tbl.parent().parent().height();
tbHt = $tbl.parent().parent().height();
// The header will always jump into view if scrolling the table body
$tbl.parent().bind('scroll', function(){
if (wo.scroller_jumpToHeader) {
var pos = $win.scrollTop() - $hdr.offset().top;
if ($(this).scrollTop() !== 0 && pos < t && pos > 0) {
if ($(this).scrollTop() !== 0 && pos < tbHt && pos > 0) {
$win.scrollTop( $hdr.offset().top );
}
}
@ -217,4 +259,4 @@ ts.addWidget({
}
});
})(jQuery);
})(jQuery, window);