A very sad realization

A very sad realization

TheSisbTheSisb Posts: 18Questions: 0Answers: 0
edited November 2012 in General
I need a table where the left column is fixed. So I use the FixedColumns plugin. The problem with the FixedColumn plugin is that all your other rows must remain on a single line otherwise you have height alignment issues. The documentation doesn't seem to mention is that, at least not obviously. Fine, throw in a "white-space:nowrap;" for your table s and call it a day.

However, cells not being able to wrap is horrible for UX because when you switch pages, your data changes - the length of your columns are now dynamic. It is a really bad feeling to have your vision forcibly blurred by a resizing table: what you were looking at just a second ago is now off your screen in a scrollbar.

I looked into maybe having resizable column headers as this is the only reasonable way to solve this issue and it is a staple feature in grid software, but there are no solid options.

This is saddening because I spent the last week learning and working with DataTables. I really didn't expect it to lack such basic table functionality.

Replies

  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    > The problem with the FixedColumn plugin is that all your other rows must remain on a single line otherwise you have height alignment issues.

    That's not true though as you'll see here: http://live.datatables.net/uwaqit/edit#javascript,html . FixedColumns copes just fine with rows of different heights (unless you disable row height matching).

    Allan
  • TheSisbTheSisb Posts: 18Questions: 0Answers: 0
    edited November 2012
    I haven't disabled row height matching and it doesn't work for me.
    [code]
    someTable.dataTable({
    "oLanguage": {
    "sLengthMenu": "_MENU_ records per page"
    },

    'sPaginationType': 'full_numbers',
    'sScrollX': '100%',

    'bProcessing': true,
    'bServerSide': true,
    'sAjaxSource': url,
    'sAjaxDataProp': 'd',
    'iDisplayLength': 20,
    "sServerMethod": "POST",
    "bDestroy": destroy,
    "bAutoWidth": false,
    // d is a placeholder
    "aoColumns": [
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' },
    { "mData": "d", "sWidth": '100px' }
    ],

    // Other stuff

    // Fix left column
    "fnInitComplete": function (oSettings, json) {
    new FixedColumns( someTable );
    }
    });
    [/code]

    sWidth and bAutoWidth doesn't work as intended as well. Columns are still being set by dataTables.
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    Can you please link me to a page showing the problem. There are a wide range of variables which will effect things that aren't covered in the code drop above.

    Allan
  • TheSisbTheSisb Posts: 18Questions: 0Answers: 0
    edited November 2012
    I can't share what I'm working on unfortunately.

    I've spent the last few hours working on a column resizer plugin. Now that I finished the functionality, when I went to test it I realized why you didn't implement one yourself. As it stands, table cells refuse to be shrunk past their content. I think it would require changing the way datatables works entirely, correct?

    [edit] wait nevermind I think I can just get it to work.... Just need to find how dataTables automatically calculates column widths. If I get this working I will share it.

    I tried setting "bAutoWidth": false and am doing
    [code]
    "aoColumns": [
    { mData: "id", sWidth: '100px' },
    { mData: "type", sWidth: '100px' },
    { mData: "stuff", sWidth: '100px' },
    [/code]
    and yet when I refresh I get an inline style='width:88px;' - where is that 88px being calculated because you're doing (width - (borderWidth*2) - (paddingLeft + paddingRight) ) but I'm using box-sizing:border-box.


    [edit2] One of my last issues before I can share this plugin is that when I click on a column header to sort that column, the column's width is reverted to default. Is there any way to block that functionality?
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    > As it stands, table cells refuse to be shrunk past their content. I think it would require changing the way datatables works entirely, correct?

    Correct - HTML table cells can be exceptionally difficult to work with in terms of sizing. The only way I've come up with to deal with this kind of issue is to wrap the content in a DIV and assign an absolute width and overflow:hidden to that liner div.

    Having said that, there is one other option:

    > width

    If you want pixel perfect control over the table, use `table-layout: fixed` - then your table will be perfectly aligned for the layout, completely overruling the control (indeed, overflow:hidden works for the cells here).

    The reason that your 100px isn't being applied is because the browser is overruling you - its doing a calculation that says your table + the content can't fit into the widths you've assigned. The way DataTables works is to create a temporary table, apply your widths and if the browser overrules, use the browser's values. Only `table-layout: fixed` can overcome that, but that brings its own raft of issues...

    Allan
  • TheSisbTheSisb Posts: 18Questions: 0Answers: 0
    edited November 2012
    I've come up with another way.

    [code]
    .dataTables_wrapper .poithead th,
    .dataTables_wrapper .poitbody td {
    border: 1px solid #ccc;
    color: #222222;
    font-size: 12px;
    padding: 2px 5px;
    display:block;
    float:left;
    width:100px;
    height:26px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    -moz-box-sizing:border-box;
    box-sizing:border-box;
    }
    [/code]

    By using [b]float:left;[/b] it allows you to reduce column size as much as you want.

    My solution is almost completely working, the only problem I have now is when, clicking on a header (to sort that column) or switching pages, the table re-sizes (re-draws?) all my columns to their default width of 100px as written in my css above.

    If I can remove that feature, it would work perfectly. Otherwise I would need to loop through everything after drawing and re-do it myself, which is less than optimal.

    Help me solve this and I'll clean it up into a perfectly working plugin. Works with FixedColumn too.
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    I'd never considered making the TD elements block level rather than cell level. I can certainly see how that would work - although it might not work in some older browsers?

    To have your new width applied you'll need to modify the `aoColumns[ i ].sWidth` attribute in the table's settings object (which can be obtained using the fnSettings method). Its not a public property, so it might change between major versions, but there is currently no public API to change the column width.

    If you set that before the draw, then it should apply your new width again.

    Allan
  • TheSisbTheSisb Posts: 18Questions: 0Answers: 0
    edited November 2012
    I'm doing
    [code]
    "fnPreDrawCallback": function( oSettings ) {
    if (firstLoad >= 3) {
    var cLen = columns.length;
    for (var i = 0; i < cLen; i++){
    oSettings.aoColumns[i].sWidth = columns[i].sWidth;
    //oSettings.aoColumns[i].sWidthOrig = columns[i].sWidth; tried with and without
    console.log(oSettings.aoColumns[i].sWidth);
    }
    }
    // return oSettings; tried with and without this

    },
    [/code]

    And it still ignores my column width. Did I miss something?


    [edit]
    console logging on the fnDrawCallback clearly shows that
    sWidth = 37
    sWidthOrig = 37

    for the column, and yet it still reverts to 100px when it actually draws.
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    As far as I know - that should be all that is needed. Can you link me to your page that has that code in it so I can take a peak?

    One thought that strikes me - how are you setting the width of your block level cells? If they are properly block level then they will each need to have width applied to them individually. Absolutely not something DataTables will do itself since in a table layout that isn't needed.

    Allan
  • TheSisbTheSisb Posts: 18Questions: 0Answers: 0
    edited November 2012
    [quote]allan said: how are you setting the width of your block level cells? If they are properly block level then they will each need to have width applied to them individually.[/quote]

    You are correct in thinking that. I am applying the width to every cell in the table in a for loop. It seems like it would be slow but by limiting the table to 20 rows and utilizing pagination it makes it very feasible.



    [quote]allan said: Can you link me to your page that has that code in it so I can take a peak?[/quote]
    I really wish I could but I don't have a public webserver. I've pasted bits of my code, it's not pretty -at all- but it's a work in progress.
    js: http://pastebin.com/wf59D7ry
    css: http://pastebin.com/grXWZiGh
    some markup: http://pastebin.com/YUGurWZZ

    Start reading it from the bottom up. If you're wondering where a variable is coming from, it's probably in the plugin's namespace. (right after $.fn.poiLoader =)


    [edit]
    Maybe aoColumns[columnIndex].nTh.style.cssText is what's causing it?
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    > Maybe aoColumns[columnIndex].nTh.style.cssText

    Thats the TH's `style` attribute - I thought you were applying the style directly (el.style.width would directly effect cssText).

    I couldn't actually see the code clips I'm afraid as pastebin asks for a password. Do you have scrolling (x or y) enabled in the DataTable? Try disabling that and see if that helps?

    Allan
  • TheSisbTheSisb Posts: 18Questions: 0Answers: 0
    Sorry about the private pastes, they should be visible now.

    I am applying the styles both directly and through aoColumns.

    I only have sScrollx: 100% and disabling it breaks the table further.
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    Thanks for the pastebin updates - I'm afraid I don't see anything obvious there for why the columns would be reset to 100px on a redraw.

    Perhaps it might be possible to put a working example of where you've got to on http://live.datatables.net ?
This discussion has been closed.