mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
72 lines
7.7 KiB
JavaScript
72 lines
7.7 KiB
JavaScript
/*! Widget: stickyHeaders - updated 10/31/2015 (v2.24.0) */
|
|
/*
|
|
* Requires tablesorter v2.8+ and jQuery 1.4.3+
|
|
* by Rob Garrison
|
|
*/
|
|
!function(a,b){"use strict";var c=a.tablesorter||{};a.extend(c.css,{sticky:"tablesorter-stickyHeader",// stickyHeader
|
|
stickyVis:"tablesorter-sticky-visible",stickyHide:"tablesorter-sticky-hidden",stickyWrap:"tablesorter-sticky-wrapper"}),
|
|
// Add a resize event to table headers
|
|
c.addHeaderResizeEvent=function(b,c,d){// make sure we're using a dom element
|
|
if(b=a(b)[0],b.config){var e={timer:250},f=a.extend({},e,d),g=b.config,h=g.widgetOptions,i=function(a){var b,c,d,e,f,i,j=g.$headers.length;for(h.resize_flag=!0,c=[],b=0;j>b;b++)d=g.$headers.eq(b),e=d.data("savedSizes")||[0,0],f=d[0].offsetWidth,i=d[0].offsetHeight,(f!==e[0]||i!==e[1])&&(d.data("savedSizes",[f,i]),c.push(d[0]));c.length&&a!==!1&&g.$table.trigger("resize",[c]),h.resize_flag=!1};return i(!1),clearInterval(h.resize_timer),c?(h.resize_flag=!1,!1):void(h.resize_timer=setInterval(function(){h.resize_flag||i()},f.timer))}},
|
|
// Sticky headers based on this awesome article:
|
|
// http://css-tricks.com/13465-persistent-headers/
|
|
// and https://github.com/jmosbech/StickyTableHeaders by Jonas Mosbech
|
|
// **************************
|
|
c.addWidget({id:"stickyHeaders",priority:60,// sticky widget must be initialized after the filter widget!
|
|
options:{stickyHeaders:"",// extra class name added to the sticky header row
|
|
stickyHeaders_attachTo:null,// jQuery selector or object to attach sticky header to
|
|
stickyHeaders_xScroll:null,// jQuery selector or object to monitor horizontal scroll position (defaults: xScroll > attachTo > window)
|
|
stickyHeaders_yScroll:null,// jQuery selector or object to monitor vertical scroll position (defaults: yScroll > attachTo > window)
|
|
stickyHeaders_offset:0,// number or jquery selector targeting the position:fixed element
|
|
stickyHeaders_filteredToTop:!0,// scroll table top into view after filtering
|
|
stickyHeaders_cloneId:"-sticky",// added to table ID, if it exists
|
|
stickyHeaders_addResizeEvent:!0,// trigger 'resize' event on headers
|
|
stickyHeaders_includeCaption:!0,// if false and a caption exist, it won't be included in the sticky header
|
|
stickyHeaders_zIndex:2},format:function(d,e,f){
|
|
// filter widget doesn't initialize on an empty table. Fixes #449
|
|
if(!(e.$table.hasClass("hasStickyHeaders")||a.inArray("filter",e.widgets)>=0&&!e.$table.hasClass("hasFilters"))){var g,h,i,j,k=e.$table,
|
|
// add position: relative to attach element, hopefully it won't cause trouble.
|
|
l=a(f.stickyHeaders_attachTo),m=e.namespace+"stickyheaders ",
|
|
// element to watch for the scroll event
|
|
n=a(f.stickyHeaders_yScroll||f.stickyHeaders_attachTo||b),o=a(f.stickyHeaders_xScroll||f.stickyHeaders_attachTo||b),p=k.children("thead:first"),q=p.children("tr").not(".sticky-false").children(),r=k.children("tfoot"),s=isNaN(f.stickyHeaders_offset)?a(f.stickyHeaders_offset):"",t=s.length?s.height()||0:parseInt(f.stickyHeaders_offset,10)||0,
|
|
// is this table nested? If so, find parent sticky header wrapper (div, not table)
|
|
u=k.parent().closest("."+c.css.table).hasClass("hasStickyHeaders")?k.parent().closest("table.tablesorter")[0].config.widgetOptions.$sticky.parent():[],v=u.length?u.height():0,
|
|
// clone table, then wrap to make sticky header
|
|
w=f.$sticky=k.clone().addClass("containsStickyHeaders "+c.css.sticky+" "+f.stickyHeaders+" "+e.namespace.slice(1)+"_extra_table").wrap('<div class="'+c.css.stickyWrap+'">'),x=w.parent().addClass(c.css.stickyHide).css({position:l.length?"absolute":"fixed",padding:parseInt(w.parent().parent().css("padding-left"),10),top:t+v,left:0,visibility:"hidden",zIndex:f.stickyHeaders_zIndex||2}),y=w.children("thead:first"),z="",A=0,B=function(a,c){var d,e,f,g,h,i=a.filter(":visible"),j=i.length;for(d=0;j>d;d++)g=c.filter(":visible").eq(d),h=i.eq(d),"border-box"===h.css("box-sizing")?e=h.outerWidth():"collapse"===g.css("border-collapse")?b.getComputedStyle?e=parseFloat(b.getComputedStyle(h[0],null).width):(f=parseFloat(h.css("border-width")),e=h.outerWidth()-parseFloat(h.css("padding-left"))-parseFloat(h.css("padding-right"))-f):e=h.width(),g.css({width:e,"min-width":e,"max-width":e})},C=function(){t=s.length?s.height()||0:parseInt(f.stickyHeaders_offset,10)||0,A=0,x.css({left:l.length?parseInt(l.css("padding-left"),10)||0:k.offset().left-parseInt(k.css("margin-left"),10)-o.scrollLeft()-A,width:k.outerWidth()}),B(k,w),B(q,j)},D=function(b){if(k.is(":visible")){// fixes #278
|
|
// Detect nested tables - fixes #724
|
|
v=u.length?u.offset().top-n.scrollTop()+u.height():0;var d=k.offset(),e=a.isWindow(n[0]),// $.isWindow needs jQuery 1.4.3
|
|
f=a.isWindow(o[0]),
|
|
// scrollTop = ( $attach.length ? $attach.offset().top : $yScroll.scrollTop() ) + stickyOffset + nestedStickyTop,
|
|
g=(l.length?e?n.scrollTop():n.offset().top:n.scrollTop())+t+v,h=k.height()-(x.height()+(r.height()||0)),i=g>d.top&&g<d.top+h?"visible":"hidden",j={visibility:i};l.length&&(j.top=e?g-l.offset().top:l.scrollTop()),f&&(
|
|
// adjust when scrolling horizontally - fixes issue #143
|
|
j.left=k.offset().left-parseInt(k.css("margin-left"),10)-o.scrollLeft()-A),u.length&&(j.top=(j.top||0)+t+v),x.removeClass(c.css.stickyVis+" "+c.css.stickyHide).addClass("visible"===i?c.css.stickyVis:c.css.stickyHide).css(j),(i!==z||b)&&(
|
|
// make sure the column widths match
|
|
C(),z=i)}};
|
|
// onRenderHeader is defined, we need to do something about it (fixes #641)
|
|
if(
|
|
// only add a position relative if a position isn't already defined
|
|
l.length&&!l.css("position")&&l.css("position","relative"),
|
|
// fix clone ID, if it exists - fixes #271
|
|
w.attr("id")&&(w[0].id+=f.stickyHeaders_cloneId),
|
|
// clear out cloned table, except for sticky header
|
|
// include caption & filter row (fixes #126 & #249) - don't remove cells to get correct cell indexing
|
|
w.find("thead:gt(0), tr.sticky-false").hide(),w.find("tbody, tfoot").remove(),w.find("caption").toggle(f.stickyHeaders_includeCaption),j=y.children().children(),w.css({height:0,width:0,margin:0}),j.find("."+c.css.resizer).remove(),k.addClass("hasStickyHeaders").bind("pagerComplete"+m,function(){C()}),c.bindEvents(d,y.children().children("."+c.css.header)),k.after(x),e.onRenderHeader)for(i=y.children("tr").children(),h=i.length,g=0;h>g;g++)
|
|
// send second parameter
|
|
e.onRenderHeader.apply(i.eq(g),[g,e,w]);
|
|
// make it sticky!
|
|
o.add(n).unbind("scroll resize ".split(" ").join(m).replace(/\s+/g," ")).bind("scroll resize ".split(" ").join(m),function(a){D("resize"===a.type)}),e.$table.unbind("stickyHeadersUpdate"+m).bind("stickyHeadersUpdate"+m,function(){D(!0)}),f.stickyHeaders_addResizeEvent&&c.addHeaderResizeEvent(d),
|
|
// look for filter widget
|
|
k.hasClass("hasFilters")&&f.filter_columnFilters&&(
|
|
// scroll table into view after filtering, if sticky header is active - #482
|
|
k.bind("filterEnd"+m,function(){
|
|
// $(':focus') needs jQuery 1.6+
|
|
var d=a(document.activeElement).closest("td"),g=d.parent().children().index(d);
|
|
// only scroll if sticky header is active
|
|
x.hasClass(c.css.stickyVis)&&f.stickyHeaders_filteredToTop&&(
|
|
// scroll to original table (not sticky clone)
|
|
b.scrollTo(0,k.position().top),
|
|
// give same input/select focus; check if c.$filters exists; fixes #594
|
|
g>=0&&e.$filters&&e.$filters.eq(g).find("a, select, input").filter(":visible").focus())}),c.filter.bindSearch(k,j.find("."+c.css.filter)),
|
|
// support hideFilters
|
|
f.filter_hideFilters&&c.filter.hideFilters(e,w)),k.trigger("stickyHeadersInit")}},remove:function(d,e,f){var g=e.namespace+"stickyheaders ";e.$table.removeClass("hasStickyHeaders").unbind("pagerComplete filterEnd stickyHeadersUpdate ".split(" ").join(g).replace(/\s+/g," ")).next("."+c.css.stickyWrap).remove(),f.$sticky&&f.$sticky.length&&f.$sticky.remove(),// remove cloned table
|
|
a(b).add(f.stickyHeaders_xScroll).add(f.stickyHeaders_yScroll).add(f.stickyHeaders_attachTo).unbind("scroll resize ".split(" ").join(g).replace(/\s+/g," ")),c.addHeaderResizeEvent(d,!1)}})}(jQuery,window); |