GithubHelp home page GithubHelp logo

jmosbech / stickytableheaders Goto Github PK

View Code? Open in Web Editor NEW
906.0 50.0 297.0 340 KB

A jQuery plugin that makes large tables more usable by having the table header stick to the top of the screen when scrolling.

License: MIT License

JavaScript 100.00%

stickytableheaders's Introduction

StickyTableHeaders

So what's it good for? Well, let's say you want to display a long list of fairly uniform tabluar data, like stock exchange listings or sport statistics but you don't want your users to get lost in the data as they scroll down on the page.

StickyTableHeaders to the rescue: By applying the StickyTableHeaders jQuery plugin to the table, the column headers will stick to the top of the viewport as you scroll down.

Go ahead and try out a demo.

The code is based on this proof of concept.

Installation

The best way to install is using npm:

npm install sticky-table-headers

or Bower:

bower install StickyTableHeaders

or by loading it directly from the unpkg CDN:

<script src="https://unpkg.com/sticky-table-headers"></script>

Usage

Initializing the plugin is pretty straight forward:

$('table').stickyTableHeaders();

Tear down

To remove the plugin:

$('table').stickyTableHeaders('destroy');

Trigger an update manually

$(window).trigger('resize.stickyTableHeaders');

Options

You can initialize the plugin with an options map to tweak the behavior. The following options are supported:

fixedOffset

A number or jQuery object specifying how much the sticky header should be offset from the top of the page:

$('table').stickyTableHeaders({fixedOffset: $('#header')});

scrollableArea

A DOM element or jQuery object. Allows you to overwrite which surrounding element is scrolling. Defaults to window. Check this demo for an example:

$('table').stickyTableHeaders({scrollableArea: $('.scrollable-area')});

cacheHeaderHeight

Performance tweak: When set to true the plugin will only recalculate the height of the header cells when the width of the table changes.

Default value: false

$('table').stickyTableHeaders({cacheHeaderHeight: true});

z-index

The plugin uses z-index to make the thead overlay the body. You can override the z-index value by passing in a zIndex option:

$('table').stickyTableHeaders({zIndex: 999});

Reinitialize

As described in pull request #33 responsive pages might need to reinitialize the plugin when the user resizes his browser. This is can be done by calling the plugin with the new options:

$('table').stickyTableHeaders({fixedOffset: [new-offset]});

Events

The plugin triggers the following events on the targeted <table> element:

  • clonedHeader.stickyTableHeaders: When the header clone is created.
  • enabledStickiness.stickyTableHeaders: When the sticky header is enabled.
  • disabledStickiness.stickyTableHeaders: When the sticky header is disabled.

Confused?

If any of this is confusing, please check out the /demo folder. There are a couple of examples in there. E.g. you can see how to use it with Twitter Bootstrap.

Known Issues

  • Internet Explorer: You need to set the padding of the <th>s explicitly in the css in order to make the plugin work
  • Internet Explorer: Adding horizontal margin to the table causes the header to be misaligned when scrolling. (Issue #10)
  • Using the plugin together with tablesorter breaks in Internet Explorer 8

Browser Support

The plugin has been verified to work in:

  • Chrome 35
  • Firefox 29
  • Internet Explorer 8-11
  • Safari 5

NOTE: It does not work in Internet Explorer 7 (but it degrades nicely)

stickytableheaders's People

Contributors

alekstorm avatar alexbeletsky avatar arfordweb avatar axelarge avatar c960657 avatar ced-b avatar coderkk avatar d3artagnan avatar dkhayzin avatar floticerus avatar gandhi11 avatar grigorieff avatar jasonbrady avatar jmosbech avatar kavun avatar krishnasagr avatar kyleamathews avatar meodai avatar mitermayer avatar mygoodgomez avatar nawawi avatar raisoblast avatar simon04 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stickytableheaders's Issues

ipad support

I know iPad (and probably other touch devices) may be a bit tricky about scrolling, viewport, and fixed position... but I was surprised that it's not mentioned at all in the readme and in existing issues. Are the challenges with the ipad surmountable?

Fixed tfoot or tr:last

Can I use this plugin for fixed tfoot or tr:last child in my table?
What should I modify to get it?

header jumps down and up with the first scroll

Hi,

In the "offset" demo, if you scroll slowly till you reach the top of the table, the next scroll causes the fixed header to jump several rows down. In this situation you have 2 headers. it will be fixed with the next scroll down and never happens again.

prevent duplicate stylesheet rules

Not sure if this is worth a fix, but in my code I use several sticky tables and for each new sticky table header the plugin adds a new style to the head section. The following check around line 61 prevents this:

            if ($("[data-style=tableFloatingHeader]").length === 0)
            {
                base.$printStyle = $('<style data-style="tableFloatingHeader" type="text/css" media="print">' +
                    '.tableFloatingHeader{display:none !important;}' +
                    '.tableFloatingHeaderOriginal{position:static !important;}' +
                    '</style>');
                $('head').append(base.$printStyle);
            }

"Destroy" method?

First off, love the plugin. This is super useful!

One problem I'm having though is normally plugins have a means of being destroyed as to unbind all the events the plugin creates. I don't see any way to do this with this plugin. (Or perhaps I'm just not seeing it)

Any chance this could be added?

A problem caused IE to refresh page using compatibility view

Table initially displays OK. On scrolling down, at the instant the fixed header hits the top of the window (initially there is a tiny gap) the page redisplays in compatability view and IE9 pops up above message. Problem occurs on 2 machines. Does NOT occur with Chrome/FF/Opera/Safari.
This is my third use of this software - 2 previous tables both work absolutely fine in all browsers & continue to do so.

Table header width is wrong with twitter bootstrap nav tabs

If a table is inside a tab of twitter bootstrap (http://twitter.github.io/bootstrap/), the sticky table header width is not correct (very small). I believe this is because the page loads with no tables, and then a table is only shown once a tab is clicked, which is a jquery action to display, so the page is never reloaded to reset the width.

To fix this I had to add base.$window.on('scroll.' + name, base.updateWidth); to the base.bind section, which seems sloppy to me, but I couldn't find another way, and reloading the stickytable on tab clicks didn't seem to do anything.

Not sure if all this makes sense, but basically I was curious if there is a better way to re-adjust the width of the table one time on a jquery tab click instead of continuously with scroll.

Thanks,
Colin

Problem with Chrome

Chrome Version 30.0.1599.69 m
jQuery JavaScript v1.9.1

The sticky Width was always Zero.
Fixed problem with code below.

base.getWidth = function ($clonedHeaders)
{
$clonedHeaders.each(function (index) {
var width, $this = $(this);

            if ($this.css('box-sizing') === 'border-box') {
                width = $this.outerWidth(); // #39: border-box bug
            } else {
                width = ($this[0].clientWidth - $this[0].offsetWidth) || $this.width();
            }

            base.cellWidths[index] = width;
        });
    };

How to get function to execute when table header is floating or not

Hi jmosbech ,

First of all, I want to thank you for building this.

Second of all, I am a beginner in jquery/javascript - I just started two weeks ago.

Here is my sample code: http://jsfiddle.net/mersenneprimes/enPyB/17/

I am having trouble executing this event/function whether the table is floating or not:

$('#submitButton').click( function(){

    $('#resetButton').show();

    alert('it worked');

});

I have placed this code and the $("table").stickyTableHeaders(); line all over the place with differing results.

The alert box must be displayed and the reset button must show when I click on the Submit button...if the table header is floating or not.

To get the alert box when floating or not floating, what I did is place that code twice, once outside the StickyTableHeaders function and once inside. Obviously there must be a better way of doing this.

But now the resetButton will only display when the header is floating.

If you could guide me to what javascript/jquery concepts I need to look at I would really appreciate it. There is something that I can't figure out about event handling .

Thanks,
Ehab

Change fixedOffset after initialization

Hi everybody,
is it already possible to change the default fixedOffset after initialization? I need to change it because of my responsive layout...

Best regards
lufox

not working when window is not scrollable

Using the wrong offset.

My situation:

  • using the table's div tag as the scrollableArea because window was not the one being scrolled
  • led to bug where offsetTop was always 0. Because it was pulling from window's offset, not the scrollableArea's offset
  • fixed it using the following hack:
    base.toggleHeaders = function () {
      if (base.$el) {
        base.$el.each(function () {
          var $this = $(this),
            newLeft,
            newTopOffset = base.isWindowScrolling ? (
                  isNaN(base.options.fixedOffset) ?
                  $(base.options.fixedOffset).outerHeight() :
                  base.options.fixedOffset
                ) :
                base.$scrollableArea.offset().top +
                (!isNaN(base.options.fixedOffset) ?
                    base.options.fixedOffset : 0),
            offset = $this.offset(),

            scrollTop = base.$scrollableArea.scrollTop() + newTopOffset,
            scrollLeft = base.$scrollableArea.scrollLeft(),

            scrolledPastTop = base.isWindowScrolling ?
                scrollTop > offset.top :
                newTopOffset > offset.top,
            notScrolledPastBottom = (base.isWindowScrolling ? scrollTop : 0) <
                (offset.top + $this.height() - base.$clonedHeader.height() - (base.isWindowScrolling ? 0 : newTopOffset));

          //===============================================================
          //===
          // Hack to fix the bug.
          newTopOffset = scrollTop;
          //===
          //===============================================================

          if (scrolledPastTop && notScrolledPastBottom) {
            newLeft = offset.left - scrollLeft + base.options.leftOffset;
            base.$originalHeader.css({
              'position': 'fixed',
              'margin-top': 0,
              'left': newLeft,
              'z-index': 1 // #18: opacity bug
            });
            base.leftOffset = newLeft;
            base.topOffset = newTopOffset;
            base.$clonedHeader.css('display', '');
            if (!base.isSticky) {
              base.isSticky = true;
              // make sure the width is correct: the user might have resized the browser while in static mode
              base.updateWidth();
            }
            base.setPositionValues();
          } else if (base.isSticky) {
            base.$originalHeader.css('position', 'static');
            base.$clonedHeader.css('display', 'none');
            base.isSticky = false;
            base.resetWidth($('td,th', base.$clonedHeader), $('td,th', base.$originalHeader));
          }
        });
      }
    };

header overflow if the table is inside a container

I like what you have done for making a fixed header html table. But since you are using 'position: fixed', there is this drawback of headers overflowing the container boundary, if the table is inside a containing div which has a given width/height and handles overflow using scrollbars.

I have modified your fiddle to show this here:

http://jsfiddle.net/cGF4W/

Try scrolling using the outside scrollbar & you'll see headers overflowing the boundary.
I think you can get rid of this using 'position:absolute' but then the scrolling logic goes for a toss.

I think the scenario of having tables within a container is very generic and when handled, will make this plugin very versatile.

Thanks.

Can't get StickyTableHeaders to line up on IE9

I'm having a difficult time getting StickyTableHeaders to line up correctly in IE9. As far as I have seen, it works fine in everything else. IE9 though it won't line up. Here's a screenshot of what it does - http://i.imgur.com/UEcPb.png

I'm guessing this is some sort of css issue but I've messed around a lot with css and it doesn't seem to matter.

Error: Maximum call stack size exceeded.

Fix scrolling performance outside of table

Using the latest minified version, there's a major performance problem while scrolling in Firefox when a table only has just a few hundred rows of data. I figure around 200 rows is the point where this plugin becomes handy. IE also seems to be mildly affected but to a lesser extent. Google Chrome seems to be completely free of lag. Here's a Fiddle that demonstrates the problem:

http://jsfiddle.net/stFcx/2287/

Scrolling above and below the table in Firefox has some pretty significant lag. However, all of the lag vanishes whenever the table headers start tracking within the table itself. Removing the plugin also makes the lag vanish. The problem seems to become more prevalent as more rows are added to the table, which is why this bug doesn't appear in the official demo for this plugin.

Text entered inside textbox in header is not cloned

I added a textbox <input type="text" name="firstname" /> inside <th>. Text I enter in it before it becomes sticky is not cloned into a sticky copy. And vice versa. FF & Chrome.

<table id="xxx">
    <colgroup>
       <col span="1" style="width: 100px" />
       <col span="1" style="width: 200px" />
       <col span="1" />
    </colgroup>
    <thead>
        <tr>
            <th class="bID">ID</th>
            <th class="bStatus"><span class="statusCol">Status</span></th>
            <th class="bSummary">Summary <input type="text" name="firstname"/></th>
        </tr>
    </thead>
    <tbody>
        <tr class="can">
            <td class="bID">...</td>
            <td class="bStatus">...</td>
            <td class="bSummary">...</td>
        </tr>

If TH in THEAD is modified by IDs, it is only modified when scrolling after header. But classes work perfectly.

  1. Enter value in the form.
  2. Click the Submit button.
  3. Notice no extra row appears in the header.
  4. Scroll down, notice the row appears.

See: http://jsfiddle.net/mersenneprimes/mAKjh/5/ (With id="change")

HOWEVER, if you use Classes instead of IDs, it works all the time.

See: http://jsfiddle.net/mersenneprimes/U4vMF/1/ (With class="change")

Thank you for your help. This work is abundantly praise worthy to the community.

Without a doubt, there are fuchsia javascript and css pearls which I have yet to discover from the people of knowledge.

Make the original header invisible when the clone is visible

It doesn't matter in most cases whether the original header is visible or not, since normally it is hidden by the clone anyway. But when you add some transparency to the header, you can see the overlap between the original one and clone. Check this out: http://jsfiddle.net/stFcx/428/ (scroll down slowly to see the overlap)

So I suggest the following patch:

 if ((scrollTop > offset.top) && (scrollTop < offset.top + $this.height())) {
     base.$clonedHeader.css({
         'top': fixedHeaderHeight,
         'margin-top': 0,
         'left': offset.left - scrollLeft,
         'display': 'block'
     });
+    base.$originalHeader.css('visibility', 'hidden');

     base.updateCloneFromOriginal();
 }
 else {
     base.$clonedHeader.css('display', 'none');
+    base.$originalHeader.css('visibility', 'visible');
 }

It makes the transition seamless. See http://jsfiddle.net/stFcx/429/

stickyTableHeaders not aligning headers properly with data content on the table in the IE

Hi,

I have a table which has large data with headers need to be fixed on scroll down. I used stickyTableHeaders plugin for this and working in firefox and safari/chrome. But when i run the same on IE(all versions), the headers of the table not aligning properly with data content on the table within tbody on scrolling down. The js fiddle link for this is http://jsfiddle.net/qk5Fq/15/ . Attached here the snapshot.
untitled
Can you please help me to get this fixed ?

Thanks,
Raghav

Weird behavior in Chrome 18.0.1025.151, not in FF or IE. Cells are hidden after sticktableheaders is executed, but header stays there

OK, here is the site I've been working on and I credit your great help in making it come alive: http://countsimple.com/

See video here for the immediate problem: http://screencast.com/t/TlIZqrbMf

  1. To inform you, this is a filtering type table. You click on a row, it shows you all the columns without a datacell that has a "No" in it.
  2. Click on any row to filter. Make sure you are above the header in your window.
  3. Now scroll down below the header.
  4. Boom, the LAST column cells always disappear, but they are supposed to stay there. Try some more filtering, above and below the table header, and you will see two more columns disappear. I could only get the last 3 to disappear.

After clicking the "clear all" button, all td, tr, everything is supposed to be displayed. But doesn't work, still last 3 columns are missing.

This only happens in Chrome, and not Firefox or IE (Maybe Safari, but don't have that yet).

If I turn off stickytableheaders I do not get this problem.

Since I am such a beginner, I do not know where to start to investigate. I validated my tables and I tried deleting the parentRows. I tried to find a specific reason why only the last columns disappear after you scroll above the table header but couldn't figure out why.

I very much appreciate your help and thank you.

handling text-overflow in table header

Hi!

Nice work, this is the first fixed header plugin that really works for me. Thanks :-) One issue, though. Is there a way to handle overlapping text in the table header? Please see this fiddle: http://jsfiddle.net/papermoon/bpDfV/

(Its using the modified stickytableheaders plugin from issue #1, but it's the same for the default one.)

Thanks!

Andre

Clone header after original (instead of before)

Is there any reason you cloned the thead before the original, instead of after? I think it makes more sense from a structure standpoint. Also, for those using Twitter Bootstrap, this avoids some strange styling issues, because that library targets the first thead for its styling.

Just a thought. I changed line 43 from:

base.$originalHeader.before(base.$clonedHeader);

to:

base.$originalHeader.after(base.$clonedHeader);

and it seems behave exactly the same (while resolving the Twitter Bootstrap issues).

adds commas into input boxes within thead

Hi - best solution I've found yet to the debacle which is FF dropping table scrolling in 4+. However, there seems to be an issue when you have input fields in any of the tags when the table is contained within a form. When i submit the form (back to the same page), your jquery is populating (somewhat randomly) commas into the input text fields I have in the second row of my two row header. Has this been encountered before and/or work around been achieved yet?

Poor performance with large tables

I'm expericing slow performance when scrolling, resizing etc and general lack of responsiveness with large tables and using this sticky header plugin. I've pinned it down to the base.toggleHeaders() function which is calling base.updateWidth() every time the user is scrolling, which in turn is looping through the table cells to get the width etc. Is there a more efficient way to do this? i.e. does the whole table really need to be scanned in order to get the cell widths?

box-sizing: border-box;

The width of each th in the sticky header is not the good one when using this css declaration

* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }

Doesn't work in OPERA

thanks for your fine script. It works in each Browser, except in OPERA. Your script is now in use international.

Greetings vom Switzerland
Erich

Slow scroll before header sticks with 20+ columns

This plugin solved my problem with sticky table headers in IE but now Firefox lags behind significantly. Chrome doesn't have a problem, maybe because it doesn't have smooth scrolling. Although disabling SS in Firefox didn't quite remove the delay.

In Firefox, when the header is not yet sticky, the scroll has a delay of more than 0.5s. My table is a bit large, with 25 columns. Hiding some columns (display: none) makes the table fast again, so if you don't explicitly discriminate hidden cells, it might be just a rendering issue. I can't seem to point exactly the cause, but will try to analyze the code.

Minimum Margin top when "navbar-fixed-top" has present

When page have a Twitter Bootstrap, if body has a header menu with navbar-fixed-top class, the minimum margin-top must be 70px.

In my fork, I just add some lines to verify that page contains this class..

var minMarginTop = $(".navbar-fixed-top").length > 0 ? 54 : 0;

base.$clonedHeader.css({
    'top': newTopOffset,
    'margin-top': minMarginTop,
    'left': newLeft,
    'display': 'block'
});

Smooth scrolling in IE10/Chrome

Firstly, thanks for the great plugin.

Just wondering if anyone encounters the issue when scrolling down the table using mouse middle button. For the first few rows, the animation of table header is actually jumping instead of smooth scrolling. It is especially obvious in IE. In Firefox it is very smooth. Any idea how to overcome this?

Cell width in floatingHeader slightly off

Hey Jonas,

Great work with StickyHeaders jQuery plugin. I am running into an issue, that I am hoping you may shed some light. The cell width on the floatingHeader is slightly smaller than the original thead. Then progressively it gets smaller for each additional column. Therefore, it is not aligned perfectly when scrolling down the table. In Firefox it seems to be less off, compared to Chrome and IE.

I have uploaded two screen shots, before and after, to illustrate this issue. Screenshots: http://www.use.com/f8f3b43c3bda74504771

Thanks!
Merg

Feature request

Very nice plugin! One minor feature request: trigger a custom event right after cloning the table header so the copy can be modified before being managed by stickyTableHeaders. Maybe something like:

base.$clonedHeader = base.$originalHeader.clone();
$this.trigger('stickyTableHeader.clonedHeader',[base.$clonedHeader]);

I have an application that hides table columns (header and body) before stickyTableHeaders gets added, and have to remove the hidden table headers from the copy so the header column widths are right for the table body.

Printing problems

I've noticed that once you scroll down with a sticky header, the latest versions of Safari (6.0.3) and FF (20) don't display the header when you print the page... User must reload the page for it to print properly.

Doesn't work with IE v8/9

Very good product in concept and seems to work well on Firefox but has small cell sizing issues on Chrome and doesn't work at all on IE v8 and v9 - this I would guess is something to do with thead fixed positioning and results in the copied thead remaining within the normal element flow so appearing immediately below the original thead and scrolling out of view as if not fixed position. Nothing we've tried corrects this - if anyone's got any ideas they'd be very welcome!

Doesn't handle nested tables

When a table has another table nested within it, then when you scroll down the second table's header overlays the first. This is not optimal.

Ideally, the sticky portion would also include the three components: the outer table's header, the nested/inner table's header, and then also the outer table's row that precedes the outer table row that contains the nested table. Sample table HTML follows. (Not sure, but I think such pairs of TRs are commonly used for tables that contain nested tables.)

Enabling stickiness on three rows like this might entail setting up a fixed div or something at the top of the page that could contain multiple rows. The height of the entire div and all of its contents would need to be measured.

<table>
  <thead>
    <tr>
      <th>column header - stays in view while its table stays in view</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>header information for the table that is nested into the next row - should stay in view while the nested table stays in view</td>
    </tr>
    <tr>
      <td>
        <table>
          <thead>
            <tr>
              <th>header for the nested table - stays in view while the nested table stays in view</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>data in the nested table</td>
            </tr>
          </tbody>
        <table>
      </td>
    </tr>
  </tbody>
<table>

horizontal scroll

how to deal with this:
jsfiddle.net/mmacin/M35xT

use scroll's to find problem

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.