DataTables logo DataTables

FixedColumns: New plug-in for DataTables - fix columns when scrolling
  • Hello all,

    I'm very pleased to be able to release a new plug-in for DataTables called "FixedColumns". When DataTables 1.7 was released, there was a gap in functionality for scrolling tables, that is provided by the FixedHeader plug-in for non-scrolling tables (due to the way that scrolling is implemented). FixedColumns is the plug-in to fill that gap providing the ability to fix (or "freeze") one or more columns to the left hand-side of a scrolling table.

    - Example:
    http://datatables.net/release-datatables/extras/FixedColumns/index_column.html

    - Download:
    http://datatables.net/releases/FixedColumns-1.0.0.zip

    - FixedHeader:
    Some of the functionality provided by FixedColumns overlaps with FixedHeader (i.e. the left hand column freezing). The reason for creating FixedColumns as a compliment to FixedHeader is the significantly different way in which a table is constructed for scrolling by DataTables. FixedHeader will remain a first class plug-in for DataTables. If you want scrolling with a fixed column, use FixedColumns. For non-scrolling tables, use FixedHeader.

    - Known limitations:
    Absolute positioning is used, so in some browsers which are a little slower (basically everything but Webkit), there can be a little jarring when scrolling. Fixed positioning cannot be used for FixedColumns (unlike FixedHeader where it is used), since the element must be placed relative to other elements, not to the screen.

    DataTables and it's plug-ins are made possible by your donations. If you find this software useful, please consider making a donation ( http://datatables.net/donate ) so it can continue to be supported and developed.

    Enjoy!
    Allan
  • 1) Download link is not working. 404 - Page not found
    2) If we have several strings into some cells, we have a bug with fixed columns rendering - because they could render like 1 string and the height of the fixed columns and the height of all other columns are different in such case

    3) I wanted to ask. Is it possible to move scroll bar to the top of the table? I didn't see in examples how to do it for it, because it'is not in DOM nodes
  • 1. Sorry about that - there was a typo in the link above :-(. Thanks for letting me know!

    2. Could you post an example of that please? I did consider that when writing the code, but felt that since the column text should be the same as the text in the table, the height should be the same. Although - thinking about it, if it's a cell further on in the table which causes the height to increase - then you'd get this issue. Yup - bug here...

    3. Basically no, it's not possible since its position is dictated by the browser's (and therefore the OS's) widgets. The scrolling element is just a div with overflow: auto, so the browser will put in automatic scrollbars. It is actually possible to trick the browser by putting in other elements and some clever Javascript handling of it - but it's messy...

    Allan
  • test example - [cuted]
  • Super thanks for that. The fix should actually be very simple, and it works great in Safari. But I simply can't get it working correctly in Firefox... For some reason it is adding and subtracting the odd pixel here and there from the assigned heights, and it's very frustrating. Needs more work...

    Allan
  • in IE8 and Opera - the same bug as in FF. So try your fix on such browsers too. thnx a lot and get in touch about when fix would correctly work :)
  • I've not uploaded the fix yet (since it's not working), so not sure how you tried it! I wanted to get it working in Firefox before trying it in IE and Opera...

    Allan
  • and I found 1 more bug with simple Horizontal Scrolling. You could come to the same page - link on what i posted before. You could see that cells are not under the title column tags but they are a little lefter. some render bug
  • And one more thing. Did you try to provide something like jquery.history plugin, to use browser's history for all ajax actions?
  • Regarding your first point, I've not seen that - coudl you post the link again please - it looks like you've removed it.

    With regard to the history plugin, no I've made no attempt to support that kind of thing. I'm not sure how useful it would be for this plugin - but I'm sure it could be implemented if you wanted to do so.

    Allan
  • 2)It could be implemeted only if I make changes to your library, because to support such thing all buttons which generated by your library should also produce not only ajax actions but things like document.location.href = "#fgfdgdgdgdg", and also should be some agent which could parse such url and start the neccessary acton
  • 1. It doesn't look like FixedColumns is currently enabled. However, I believe the issue is caused by the column misalignment - it looks like there isn't enough room to render the table - if you look at the console you'll see a warning from DataTables: "DataTables warning (table id = 'example'): The table cannot fit into the current element which will cause column misalignment. It is suggested that you increase the sScrollXInner property to allow it to draw in a larger area, or simply remove that parameter to allow automatic calculation"

    2. Ah you mean DataTables itself rather than the FixedColumns plug-in. I had always thought about the table as being more or less stateless (although it is possible save the state using cookies), and that it should have no effect on the back button. As a user I'd probably find it a bit frustrating that if I click to sort a column, then it would require two 'back' clicks to go back. Although as I say, I'm sure it would be possible to hack it into DataTables.

    Allan
  • 2- yes i mean DataTables itself. And how much time need to hack this into DataTables?
  • To be honest I'm not sure - I've not investigated it before, so I'm not too sure how the history plug-in for jQuery works. I would imagine that it would be possible to hook into the state saving that DataTables uses (it provides a callback function with which it is possible to customise the settings stored, so at that point you have access to the settings that DataTables is saving for that draw). Assuming that with the history plug-in you can store an arbitrary object for any position in the history (assuming it will generate an anchor hash) and that there is a call back function when a saved history is activated (to restore the DataTables settings from the stored object), I would imagine that it would only take a couple of hours. Assuming of course that my assumptions are correct :-)

    Allan
  • Ecsapt the jquery plugin I found such tool
    http://yuilibrary.com/gallery/show/history-lite
    is it good for this?
  • It looks that that would require YUI on top of jQuery. Fair enough, but perhaps more downloading that is necessary for the end user. It looks like this plug-in is well respected for jQuery: http://www.asual.com/jquery/address/

    Allan
  • Great work on this entire project. I have been evaluating and trying to find out if the DataTables project is intended to be compatible with IE6. I did not see information on targeted browsers, but I probably missed it.

    At least in the case of the FixedColumn plugin, there seems to be multiple issues in IE6. The fixed column headers move with the scrollbar while the others stay fixed. Columns outside the intended visible have headings overflowing to the right outside the area. Upon sorting after a horizontal scroll, the intended fixed headers pop out to the left.

    Thanks!
  • Hi baldwindavid,

    While DataTables itself should be fully compatible with IE6, I've not tested FixedColumn in IE6. I'll have a look at how readily possible it will be to add support for IE6 with this. Part of me is surprised it doesn't work, since it doesn't really do anything all that clever - but then part of me isn't surprised since it is IE6 :-)

    Allan
  • Hi baldwindavid,

    I've just committed a fix for the IE6 issue you were seeing: http://github.com/DataTables/FixedColumns/blob/master/media/js/FixedColumns.js . It will be part of the next release of FixedColumns, but this is it ready to roll :-)

    Regards,
    Allan
  • That's great. Thanks Alan. I did note that there is still the same issue with the footer in the examples including a footer. I got those displaying correctly by changing the two instances of this.dom.footer.parentNode (lines 171 and 299) to this.dom.footer.parentNode.parentNode, but I don't know if that is the preferred solution.

    Best Regards,
    David Baldwin
  • Sorry...that should have been "Thanks Allan" (rather than Alan). I am also running into an issue with stacked headers (when using this FixedColumn plugin) in every browser. Suppose I have stacked column headers like this...

    <thead>
      <tr>
          <th rowspan="2">Rendering engine</th>
          <th rowspan="2">Browser</th>
          <th colspan="2">Machine</th>
          <th rowspan="2">CSS grade</th>
      </tr>
      <tr>
        <th>Platform(s)</th>
        <th>Engine version</th>
      </tr>
    </thead>
    

    In newer browsers, instead of fixing only the "Rendering engine" column, it also places the "Platform(s)" column and fixes it to the right of the single intended fixed column. This is presumably because this is the first column of the second row in the header. It also has a gap below the fixed column headers and the tbody, but that may be due to the aforementioned issue. In IE6, I assume the same would happen, but I get a runtime error on page load "Line: 315 - Error: 'this.dom.clone.body.style' is null or not an object"

    Best regards,
    David Baldwin
  • Hi David,

    I've just committed a fix for the footer issue as well, which can also now be picked up from the link above. Basically the issue appears to be with IE6 and having position: relative, and overflow: hidden on the same element - ouch. Fortunately the DOM is already in a suitable arrangement where by FixedColumns can apply the position: relative to a different element - which is what the fix is.

    With regard to the issue about the multiple TR elements in the header, I'm not surprised that this doesn't work in any browser at the moment, as I hadn't made any attempt at supporting this kind of behaviour. However, you got me thinking about it with your example HTML there (thanks for that) and with that format (i.e. rowspan on the fixed columns, spanning the number of rows, and no colspan on the fixed columns), it's actually not all that difficult to do. I've just committed a change which will allow this to work for both the header and footer (and in IE6 ;-) ). As noted, there are a couple of limitations (addressing them would require a lot more work I think), but the example above seems to work well.

    Regards,
    Allan
  • Hi Allan,
    Excellent stuff. You are probably getting sick of me by now, but I did run into another issue. The cloned fixed column does not seem to take into account for text wrapping in columns of the main table. The example below using the "index.html' example file is contrived, but should describe what I mean...

    <tr class="gradeA">
      <td>Gecko</td>
      <td>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</td>
      <td>Win 98+ / OSX.2+</td>
      <td class="center">1.7</td>
      <td class="center">A</td>
    </tr>
    

    In this example, the "lorem ipsum" column wraps and takes up additional vertical space. However, the adjacent fixed column does not match this additional space. Thus, this column and all columns below do not line up. This is a very common occurrence in tables with a lot of columns, which is also the most common use case for this plugin. Does that make sense?

    Best Regards,
    David Baldwin
  • Agreed - this is what wjshohs was talking about in the comments above. In principle the fix should be easy - but for some reason I just can't get Firefox to play nice - it's most frustrating... And needs more investigation.

    Allan
  • Ah, yeah. I read through that at one point, but apparently didn't realize what they were talking about until I saw it for myself. So, I'm assuming this is caused by the clone taking place prior to the browser's text wrapping behavior.

    Best Regards,
    David Baldwin
  • Allan, a little bit out topic, but is it possible with the standart manual procedure to custumize css styles and custom inputs with datatables library for such table template: http://213.108.45.42:88/public/ust/ ?
  • @David: The problem is basically that when I remove the cells which aren't needed for the fixed column (i.e. all cells in the cloned table other than the first TD child of each TR) it removes the cells which are giving the height to the row - and thus the row collapses to the height of just the text which is now in it.

    So the fix is to copy the height from the original table rows, to the cloned table rows, which is fine until it is tried in Firefox... For whatever reason, Firefox appears to add 1px to some rows, and not to others - you can see the effect in this picture: http://datatables.net/dev/fixedcolumns_height.png . It causes vertical scrolling to occur, and just slight misalignment. I can't figure out why, nor can I reproduce it in a simpler scenario. Hence - frustrating...

    @wjshohs: Yes DataTables could be styled to look like that. It would need a but of work to get the styling and element positioning exactly right, and I'm not sure what 'select columns' is (a bit like ColVis?), but in principle certainly do-able. The styling section of the site explains the classes and elements DataTables adds to the table and how you can control them: http://datatables.net/styling .

    Regards,
    Allan
  • I hear ya...nothing more frustrating than random browser behavior. But the solution you mention about taking it down to a 1-pixel discrepancy, while not perfect, sounds a lot better than the 50px difference right now. :)

    Best Regards,
    David Baldwin
  • Heh - this is true! Although it does annoyingly make the vertical scrollbar appear... The code for this "fix" is actually committed, just commented out - the line "$(this).height( $('tbody tr:eq('+k+')', that.dom.body).height() );" - just uncomment it and it will apply the heights. Works great in Safari...

    Allan
  • The world would be a much better place if we were all using Safari! Unfortunately, 95% of my users use IE...and 75% of those are still on IE6. Ugh! Of course, IE6 does something completely different. Best I can tell is that it increases the height of every fixed column based upon the height of the tallest column in the main table.???

    Best Regards,
    David Baldwin
  • Ah yes - I did actually try that when I was checking the other IE6 issues. What I think is happening is that the line of code there is reading the inner height of the cell, but IE6 is applying it as the outer height (i.e. +padding). I didn't investigate much more, but if that is the case, it means that the script would also need to get the top and bottom padding of the cell - possibly an expensive operation for IE... There might be another option, but I'm not sure what at the moment.

    ~75% of users still using IE6! Ouch...

    Allan
  • I'll have a look at this shortly with IE6 and see if it can be sorted - wonder if jQuery will set one set the outerHeight...

    Allan
  • Yeah, IE6 is company mandated unfortunately.

    I found this experimental fixed table that does nothing else, but sort of has this fixed thing working cross-browser...
    http://www.dotnetoutsource.com/Download/jQuery_FixedTable/jQuery_FixedTable_Demo.htm

    If anything can be gleaned from it that is applicable to datatables, then great. I'm guessing that the structure is so different that it may not be useful though.

    Best regards,
    David Baldwin
  • Hi David,

    Thanks for the link - quite interesting how it's been done, and while fairly different from DataTables it's interesting to see how it has been done. I think the author is encountered some of the same problems that I've been seeing. Specifically there are a number of things which are happening across the browsers:

    - Sub-pixel rounding - the issue with Firefox is how it rounds sub-pixel measurements (or rather the real issue is that all the browsers do it differently!). So if a cell is calculated with a height of 18.1777px, it is actually drawn as 19px. The way around this is to set the original table row's height to it's own height, which in doing so effectively casts the number as an integer.

    - Outer height - as expected IE6 was applying the higher as an inner height, so adding the padding. What I've done is to assume that all cells have the same padding and based a calculation on that (height - paddingTop - paddingBottom). Interestingly Safari seems to be doing the same thing.

    I've committed this now, so perhaps yo could give it a bash and say how you get on: http://github.com/DataTables/FixedColumns/blob/master/media/js/FixedColumns.js

    I've tried this on: IE6, IE7, IE8, Safari 5, Firefox 3.6, Opera 10.60 and Chrome 6. Each with it's own quirks, but I think I've coded around them now...

    Regards,
    Allan
  • Allan

    As I understand to provide customized controls which are not into the table but in some other Div's I need to use JS API functions like fnFilter for example. But I cant found the function which get the data about total founded records. Is there such function?

    Or maybe is it possible to call out of the table some controllers like search panel or total counting rows or pagination by some id with own customized css class?

    And one more thing. Is it possible to hardcoded set the with of columns? because if I try to do it by width parameter into th tag - it's not working

    here - http://213.108.45.42:88/reports/matchedproducts/ How is better to do? With JS API only?
  • Hi Allan:
    Thanks for your work on this. I am still seeing height issues in IE6, but have not yet determined whether it is because I am doing something incorrectly in terms of table setup/css. I am also seeing an issue in Firefox where the fixed header column only covers about 90% of the header vertical space, so scrolling shows the other rows underneath. But again, I have a lot of extra stuff in my integration and need to setup a more stripped down example using your example files before I can verify. Thanks!

    @wjshohs - Maybe I am not understanding correctly, but it sure seems like you are hijacking the crap out of this thread. No? :)
  • @David: It's a daft question, but are you sure IE is seeing the new version, rather than a cached version of FixedColumns? It seems to work okay on my basic examples, but I didn't try anything more complex that putting in line breaks.

    @ wjshohs: I've moved your question to here http://datatables.net/forums/comments.php?DiscussionID=2899 , so this discussion can stay on topic.

    Allan
  • I'm loving this plugin! But, when the thead has multiple tr element the fixed column only applies to the first tr. Is there a fix for this?

    Also, I was wondering if you have a method for swithing all features (sorting, filtering, pagination) to behave as a horizontonal table instead of vertical. Instead of each row being an item each column in the the table is an item. I realize this might be a huge plugin in itself, but I thought I would throw it out there as you seem like quite the master of jquery Allan!

    cheers,
    Eric Bailey
  • Hi Eric,

    1. Have you tried using the version in GitHub linked to above? That should allow multiple TR elements

    2. Heh - thanks for the compliment, but I'm afraid that this is not currently something that DataTables does. It's very much rows and columns based, and would require a significant amount of work to abstract that out. To the point of "omg..." :-). Interesting idea though!

    Allan
  • Hey Allan,

    I heard somewhere you were playing around with using position:fixed on your FixedColumns and would like to get that code if possible. I understand it's not supported/working with IE6 but that's not a problem for me, how awesome is that?!

    Thanks,

    Jeff
  • Hi Jeff,

    I don't believe position: fixed with work for this particular case, since 'fixed' is relative to the screen, not a parent object. As such, if you were to scroll the screen, then the floating column would still be floating around on the screen (unless of course it's position is updated, but then you are as well using absolute positioning). So I'm afraid, I don't see how position: fixed would actually help here.

    Regards,
    Allan
  • Hi Allan:
    I have put together a small example that will hopefully help in diagnosing a few browser issues. I am running into the following issues, the most worrisome of which is IE8...

    IE8
    -----------
    Adding a border to TD's located in the tbody seems to throw off the vertical spacing between the cloned TDs and the corresponding tbody TD's. The following example works fine in IE8 using your example CSS file...
    http://baldwindavid.github.com/datatables_test/no-border.html

    However, adding a border to TD's seems to be the culprit in throwing off the spacing in this example...
    http://baldwindavid.github.com/datatables_test/index.html

    Firefox
    -----------
    Looking at these same examples in Firefox, you can see that the fixed TH does not match the height of the regular thead TH's. Thus, when you scroll horizontally, you can see a piece of the headers below. Of course in my example the backgrounds are transparent, but you can see that the cloned TH does not quite match up vertically.

    IE6 & 7
    -----------
    The same vertical spacing issues are present, but I'm guessing the fix is different for these browsers than IE8. The fixed footer TH also seems to be slightly off, but darn close.

    Note: The example repo is located at...
    http://github.com/baldwindavid/datatables_test

    Best Regards,
    David Baldwin
  • Hi David,

    Thanks very much for putting up the examples - they will be really useful! Can I just check that you are using IE8 in "super-standards" mode, or in compatibility? I suspect that this is just an inner v outer height issue, but I will look into it and let you know what I find.

    Thanks,
    Allan
  • Hi Allan:
    Yes, I was in super-standards mode, but just to be sure I put up another example with the meta tag that forces this mode...
    <meta http-equiv="X-UA-Compatible" content="IE=8" />

    This example is located here...
    http://baldwindavid.github.com/datatables_test/super-standards.html

    Best Regards,
    David Baldwin
  • Hi David,

    Thanks for that. Could you give the version of FixedColumns that I've just committed to git a go please. It should resolve the issues that you were seeing:
    http://github.com/DataTables/FixedColumns/blob/master/media/js/FixedColumns.js

    Regards,
    Allan
  • Hi Allan:
    It is looking pretty good now. However, in IE8 the header seems to no longer support rowspans. You can see this in the example...
    http://baldwindavid.github.com/datatables_test/

    Best Regards,
    David Baldwin
  • Hi David,

    Thanks for spotting that. I can't think off the top of my bead why that would be, and I'm on the move atthe moment, so can't check into it for a little while (should be able to later on today). I'll get back to you :-)

    Allan
  • Hi David,

    I've committed a fix that should do the trick for you. You can grab it from github, or from the new downloads page: http://datatables.net/download/ .

    Allan
  • I just downloaded 1.0.1.dev version, it works much better than 1.0.0

    However, there is a problem with more than one fixed columns, e.g. 5, the header fixed for 5 columns, but body fixed for only 1 column

    The other thing is, the plug-in will not work if table is hidden when init. DataTables asked to call oTable.fnAdjustColumnSizing() after the table is showing. Could fixedcolumns plug in hook-up to that function and adjust itself too?
  • Hi lyiu18,

    1. Interesting. It seems to be fixing two columns no problem for me - although perhaps I'm missing something. Can you put up an example? Also I've just noticed that if the fixed columns take up more width than is visible, then slightly odd things happen to the scrolling (probably not unexpected since you'll never get to see the non-fixed columns though!).

    2. I've just tired the following code with the dev version of DataTables and FixedColumns and it appears to be working okay:

    			$(document).ready( function () {
    				document.getElementById('demo').style.display = "none";
    				var oTable = $('#example').dataTable( {
    					"sScrollX": "100%",
    					"sScrollXInner": "150%",
    					"bScrollCollapse": true
    				} );
    				new FixedColumns( oTable );
    				document.getElementById('demo').style.display = "block";
    				$('#example').dataTable().fnAdjustColumnSizing();
    			} );
    
    Again, could you possibly put up an example?

    Allan
This discussion has been closed.
All Discussions

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Support

Get useful and friendly help straight from the source.