/*! 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('
'),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++) // 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);