Skip to content

Commit dcb6733

Browse files
author
chprpipr
committed
Sorry for the reworked formatting. There are a few nuggets in this check in that I think are worthwhile:
- Takes colspans into account - Clones and hides the original THEAD and TFOOT rather than removing them. This helps to preserve column alignment - Inserts TH/TD elements to account for addition of scroll bar (preserves column alignment, particularly if the column is right justified - Adds a window.resize event handler to update the table's display if the window changes dimensions.
1 parent b33f240 commit dcb6733

File tree

1 file changed

+115
-52
lines changed

1 file changed

+115
-52
lines changed

Diff for: jquery.tablescroll.js

+115-52
Original file line numberDiff line numberDiff line change
@@ -29,52 +29,20 @@ OTHER DEALINGS IN THE SOFTWARE.
2929
*/
3030

3131
;(function($){
32-
33-
var scrollbarWidth = 0;
34-
35-
// http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php
36-
function getScrollbarWidth()
37-
{
38-
if (scrollbarWidth) return scrollbarWidth;
39-
var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div></div>');
40-
$('body').append(div);
41-
var w1 = $('div', div).innerWidth();
42-
div.css('overflow-y', 'auto');
43-
var w2 = $('div', div).innerWidth();
44-
$(div).remove();
45-
scrollbarWidth = (w1 - w2);
46-
return scrollbarWidth;
47-
}
4832

4933
$.fn.tableScroll = function(options)
5034
{
51-
if (options == 'undo')
52-
{
53-
var container = $(this).parent().parent();
54-
if (container.hasClass('tablescroll_wrapper'))
55-
{
56-
container.find('.tablescroll_head thead').prependTo(this);
57-
container.find('.tablescroll_foot tfoot').appendTo(this);
58-
container.before(this);
59-
container.empty();
60-
}
61-
return;
62-
}
35+
var Me = this;
36+
var timeoutHandle;
37+
38+
this.scrollbarWidth = 0;
6339

64-
var settings = $.extend({},$.fn.tableScroll.defaults,options);
65-
66-
// Bail out if there's no vertical overflow
67-
//if ($(this).height() <= settings.height)
68-
//{
69-
// return this;
70-
//}
71-
72-
settings.scrollbarWidth = getScrollbarWidth();
73-
74-
this.each(function()
40+
this.FormatTable = function()
7541
{
7642
var flush = settings.flush;
7743

44+
var originalClass = $(this).attr("class");
45+
7846
var tb = $(this).addClass('tablescroll_body');
7947

8048
var wrapper = $('<div class="tablescroll_wrapper"></div>').insertBefore(tb).append(tb);
@@ -101,7 +69,7 @@ OTHER DEALINGS IN THE SOFTWARE.
10169
var diff = wrapper_width-width;
10270

10371
// assume table will scroll
104-
wrapper.css({width:((width-diff)+settings.scrollbarWidth)+'px'});
72+
wrapper.css({width:((width-diff)+Me.scrollbarWidth)+'px'});
10573
tb.css('width',(width-diff)+'px');
10674

10775
if (tb.outerHeight() <= settings.height)
@@ -121,26 +89,62 @@ OTHER DEALINGS IN THE SOFTWARE.
12189
var tbody_tr_first = $('tbody tr:first',tb);
12290
var tfoot_tr_first = $('tfoot tr:first',tb);
12391

124-
// remember width of last cell
125-
var w = 0;
126-
92+
// Record cell widths
93+
// Shoud colspan > 1, evenly distribute width among grouped cells
94+
var aWidths = [];
12795
$('th, td',thead_tr_first).each(function(i)
12896
{
129-
w = $(this).width();
97+
var jCell = $(this);
98+
var colspan = jCell.attr('colspan') || 1;
99+
var colspanIterator = colspan;
100+
var avgWidth = jCell.width()/colspan;
101+
while (colspanIterator) {
102+
aWidths.push(avgWidth);
103+
colspanIterator--;
104+
}
130105

131-
$('th:eq('+i+'), td:eq('+i+')',thead_tr_first).css('width',w+'px');
132-
$('th:eq('+i+'), td:eq('+i+')',tbody_tr_first).css('width',w+'px');
133-
if (has_tfoot) $('th:eq('+i+'), td:eq('+i+')',tfoot_tr_first).css('width',w+'px');
134106
});
135107

108+
// Explicitly set width of header cells
109+
function SetCellWidths(_selector, _base, _aCellWidths) {
110+
var cellIdx = 0;
111+
var w = 0;
112+
$(_selector, _base).each(function(i) {
113+
var jCell = $(this);
114+
var colspan = jCell.attr('colspan') || 1;
115+
var w = 0;
116+
while (colspan) {
117+
w += _aCellWidths[cellIdx];
118+
cellIdx++;
119+
colspan--;
120+
}
121+
jCell.width(w);
122+
});
123+
}
124+
125+
SetCellWidths("th, td", thead_tr_first, aWidths);
126+
SetCellWidths("th, td", tbody_tr_first, aWidths);
127+
if (has_tfoot) SetCellWidths("th, td", tfoot_tr_first, aWidths);
128+
136129
if (has_thead)
137130
{
138-
var tbh = $('<table class="tablescroll_head" cellspacing="0"></table>').insertBefore(wrapper).prepend($('thead',tb));
131+
var thead = $('thead',tb);
132+
var tbh = $('<table class="tablescroll_head '+originalClass+'" cellspacing="0"></table>')
133+
.insertBefore(wrapper)
134+
.css({'margin-bottom':'0'})
135+
.prepend(thead.clone());
136+
tb.css({'table-layout':'fixed'});
137+
thead.hide();
139138
}
140139

141140
if (has_tfoot)
142141
{
143-
var tbf = $('<table class="tablescroll_foot" cellspacing="0"></table>').insertAfter(wrapper).prepend($('tfoot',tb));
142+
var tfoot = $('tfoot',tb);
143+
var tbf = $('<table class="tablescroll_foot '+originalClass+'" cellspacing="0"></table>')
144+
.insertAfter(wrapper)
145+
.css({'margin-top':'0'})
146+
.prepend(tfoot.clone());
147+
tfoot.hide();
144148
}
145149

146150
if (tbh != undefined)
@@ -149,7 +153,10 @@ OTHER DEALINGS IN THE SOFTWARE.
149153

150154
if (flush)
151155
{
152-
$('tr:first th:last, tr:first td:last',tbh).css('width',(w+settings.scrollbarWidth)+'px');
156+
$('tr:first', tbh).append($('<th></th>').css({
157+
'width': Me.scrollbarWidth + 'px'
158+
, 'padding': 0
159+
}));
153160
tbh.css('width',wrapper.outerWidth() + 'px');
154161
}
155162
}
@@ -160,11 +167,67 @@ OTHER DEALINGS IN THE SOFTWARE.
160167

161168
if (flush)
162169
{
163-
$('tr:first th:last, tr:first td:last',tbf).css('width',(w+settings.scrollbarWidth)+'px');
170+
$('tr:first', tbf).append($('<td></td>').css({
171+
'width': Me.scrollbarWidth + 'px'
172+
, 'padding': 0
173+
}));
164174
tbf.css('width',wrapper.outerWidth() + 'px');
165175
}
166176
}
167-
});
177+
};
178+
179+
this.UndoFormatTable = function() {
180+
var jThis = $(this);
181+
var container = jThis.parents("div.tablescroll");
182+
if (container.length > 0)
183+
{
184+
container.before(this);
185+
container.empty();
186+
jThis.removeAttr("style");
187+
jThis.find("thead, tfoot").show();
188+
}
189+
return;
190+
}
191+
192+
// http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php
193+
this.GetScrollbarWidth = function() {
194+
if (Me.scrollbarWidth) return Me.scrollbarWidth;
195+
var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div></div>');
196+
$('body').append(div);
197+
var w1 = $('div', div).innerWidth();
198+
div.css('overflow-y', 'auto');
199+
var w2 = $('div', div).innerWidth();
200+
$(div).remove();
201+
Me.scrollbarWidth = (w1 - w2);
202+
}
203+
204+
// -----------------------------------------------------------------------------
205+
if (options == 'undo') {
206+
Me.UndoFormatTable();
207+
}
208+
209+
var settings = $.extend({}, $.fn.tableScroll.defaults, options);
210+
211+
// Bail out if there's no vertical overflow
212+
//if ($(this).height() <= settings.height)
213+
//{
214+
// return this;
215+
//}
216+
217+
// Calculate scrollbar width and save for later
218+
Me.GetScrollbarWidth();
219+
220+
// Apply formatting to each table
221+
this.each(Me.FormatTable);
222+
223+
// Setup window.resize event handler
224+
$(window).unbind("resize.tableScroll").bind("resize.tableScroll", function() {
225+
clearTimeout(Me.timeoutHandle);
226+
Me.timeoutHandle = setTimeout(function() {
227+
Me.each(Me.UndoFormatTable);
228+
Me.each(Me.FormatTable);
229+
}, 300);
230+
});
168231

169232
return this;
170233
};

0 commit comments

Comments
 (0)