Column widths

Column widths

peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
edited October 2010 in General
How does Datatables determine the column widths? Is it based on the widest content or the header labels? I don't know in advance what content I will have, so I don't want to specify widths. I would like Datatables to take care of it.

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    DataTables will determine the widths to apply to columns thought a couple of methods. The first is if you are using a plain HTML table, then it will just take the widths which the table has already been drawn with. If however it needs to use Ajax data, or updated data, or a customised width, or anything that would effect the original table, it will look through the content of each column, find the max length string, and then construct a temporary table with the head, footer (if there is one) and the max string for each column, and draw that on the page and use the widths the browser calculates. This happens so quickly it can't be seen (visibility is 'hidden' just in case though).

    So yes, DataTables should do this for you automatically.

    I did experiment with using DOM width calculations which is a lot more accurate than the strlen (for example 'mmm' is much wider than 'iiii'!), but it was so unbelievably slow in IE that it simply wasn't worth it. I do have the code still available for anyone who does need this level of accuracy, but strlen is normally good enough.

    Allan
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Can you explain why the columns in this example are not as wide as the content? The column width seems to be dependent on the header width and not the content.

    http://www.nova.org/~pak/test/columnWidth.html
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Just add table { width: 100% } to your CSS (possibly with a more accurate selector.

    Allan
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    That is effectively what I have, but someone is adding a width of 0 directly to the element. When I edit it in Firebug, it fixes the problem, but I can't figure out how that is getting there. Do you add a width style directly to the table when doing your calculations?
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Yes - the width style is explicitly added so the table doesn't "bounce around" when changing pages. If it's being set to zero (had thought there was protection in to stop that actually) then it suggests you are hiding the table (display:none) during it's initialisation, in which case the browser doesn't calculate any dimensions. A call to http://www.datatables.net/api#fnAdjustColumnSizing should do it.

    Allan
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Ah, you're exactly right. This isn't the first time the table hiding has caused problems :-). I'll have to take another look to see if it's really worth it.
    I'll take a look at fnAdjust ColumnSizing
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    edited November 2010
    Allan,
    Not only did I comment out the hiding, but I added a call to fnAdjustColumnSizing. The style that is applied to the table no longer has a width of 0, but it is still not nearly sufficient. And again, if I change the width in Firebug to 100%, it looks fine. Can you take another look? http://www.nova.org/~pak/test/columnWidth.html
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Allan,
    Any thoughts on this? I still can't get the table to use the full width. I'm not hiding the table and I'm calling fnAdjustColumnSizing but some of the fields are still wrapping
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Anything on this yet? I'm sure it's something I'm doing, but can't figure out how to get the table to use the full width
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Can you not just put in table { width: 100% } into your CSS?

    Allan
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    edited November 2010
    The problem is that I don't want the width to really be 100%. I only want it to be as big as it needs to be. I have the table set to 100% with margin-left=auto and margin-right=auto, and it's within another container div, which doesn't have a width set. After the browser and Datatables renders the table, I set the width of the container div to be the same, so I can place other elements around the table properly. But the table width is being overridden with a style applied directly to the element.
    Can you take a look at the css? Maybe you could spot the problem or figure out how Datatables is coming up with the width that it is applying directly.
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    The table is being drawn as big as it needs to be :-). If you don't want any line breaks then consider using td { white-space: nowrap; }.

    Allan
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    But why is it wrapping before it needs to? There is plenty of room to make the table wider. I don't want it to never wrap. Only when it absolutely has to.
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    If you don't initialise DataTables on that table, what does it look like? What should be happening is that DataTables is letting the browser decide what the width of the table should be according to it's rules. DataTables then copies and applies that width as needed - as such, I suspect that it's simply the algorithm that is used (unless there is something somewhere overriding it).

    Allan
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Well, the table doesn't exist outside of Datatables, since I just pass the data in. Guess I'll have to play around some more with it.
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    If you call fnDestory() on the table, it should insert the table as plain HTML. Might not be perfect, but perhaps worth a go. An alternative is just to make a quick loop which will construct a plain table and insert it.

    Allan
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Well, after extensive tracing through the DataTables code, particularly _fnCalculateColumnWidths, I believe I found the problem.

    The temporary table that is created in order to calculate the widths, was using a different font and font size. I wouldn't go so far as to call this a bug, but definitely a design limitation that should be better documented. The problem is that in your css files, you simply use a 'table' selector to describe the table. In my code, I was a little more specific, using table#mainTable. I could certainly see other people using other classes or other selectors. But if 'table' is not used, then the temporary table will not take on the same characteristics as the actual table that is being formatted.
    It's late, so I will finish playing with this tomorrow, but I'm sure I'll get this to work.

    I think a possible solution, to make DataTables be a little more flexible in this area, is to allow the user to define a class that will be used for the temporary table. Then, I would at least know that my css file needs to be defined as
    [code]
    table#mainTable, table.class {
    }
    [/code]
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Allan,
    It seems that _fnCalculateColumnWidths is called twice on a single call to DataTables. Why is that?
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Allan,
    This wasn't quite as simple as I thought it was, but I'm getting close. I think there is definitely a bug for one case. And the other case, I still can't figure out. I really hope you can take a look at this. The example is at http://www.nova.org/~pak/test/columnWidths.html. I added a bunch of log statements in DataTables. Here is what I'm seeing.

    I believe there is a bug in the first part of fnCalculateColumnWidths (line 5329). If the table is not yet rendered, because the data is sent in to DataTables, then this code is just being executed on the columns headers. So each column is as wide as the header. You can see this in my example if you use the drop-down to select the 2nd table (4colTable). If you look at the 3rd column, you can clearly see that the column is only as wide as the header.

    If you do this with a table that has a hidden column (3colTable in my example), that triggers the else clause of your code at line 5346. Notice that I am leaving the test table that you create so we can see it. It appears that the test table you create and the actual table are the same width. So you are calculating the width correctly. But if you look at the 1st and 2nd displayed column ('value' and '3rd'), it appears that the 'value' column has a little space added to it and the same amount of space if taken away from the other column. This is what I can't figure out at all. The styles are exactly the same. I can't figure out what is causing that extra space to be added.

    thanks so much for your help
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Allan,
    Hopefully you are back in town now. I hope you get a chance to look at this. Still trying to solve my column width problem.
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Not back yet actually, and won't be for a little while. I'll try to look at this when I do get back - it looks a little more involved than something I can do on the road.

    Allan
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Allan,
    I'd really appreciate it if you could tale a look at this one. It still has me stumped. I made 2 donations in the last two weeks in the hopes that it would help.

    thanks
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Sorry I had forgotten about this thread in amongst your other ones :-).

    What I believe is happening here is an issue with the CSS styles applied to the table - specifically:

    [code]
    table thead tr th.sorting {
    padding-right: 20px;
    }
    [/code]
    That is applied to the column TH elements which aren't currently being sorted on - while the sorting column TH element only has 1px of padding. Setting them both to be the same should solve the issue. You can see this in action if you click on the first visible column to sort by it - the table is displayed as expected.

    Allan
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Hmm, I see the inconsistency you're talking about and in fact, I think I made changes to that in the last couple of days to fix it, so I'll have to look more closely. But the temporary table has the same styling applied to it. Why is the temporary table rendered correctly, but the actual table isn't?

    What do you think about the bug that I identified above. I do think there is a bug when passing data in to DataTables, as opposed to it being already in the HTML.
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    As I thought, I had recently fixed the specific problem you pointed out, but I don't think that's the whole problem. I just uploaded the latest code to http://www.nova.org/~pak/test/colWidths.html. The main js file is at http://www.nova.org/~pak/test/js/colWidths.js.
    Note that the first table has a hidden column, but it is hidden after DataTables initializes, using fnSetColumnVis and not using the bVisible init flag. I'm letting you know this just in case it makes a difference.

    I know that it must be something I'm doing and I'm perfectly prepared to be embarrassed :-)

    thanks
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    Allan,
    Did you have a chance to look at this again?
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    I've just had a look and the table itself looks okay now, but the FixedHeader is shrunk compared to the rest of the table. Is this due to a modification between your post an now, or is that what you are seeing? I don't actually see why that would be happening (unless it's a weird side effect of the fixed table layout) - the redraw should clone and copy the header.

    Allan
  • peterkronenbergpeterkronenberg Posts: 112Questions: 0Answers: 0
    I see that problem once in a while, but it usually goes away quickly. That's not what I'm talking about. The column widths are still not as wide as they should be. Column 3 is wrapping, even though there should be plenty of room for that column to be wider
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    The sizing table appears to have width 0 on it. Are you hiding it when drawing the table? Can you just put in something like table { width: 100% } and resize the container element? It might make things easier in this set up!

    Allan
This discussion has been closed.