Best way to prevent column widths from changing after sort

Best way to prevent column widths from changing after sort

DanSwitzer2DanSwitzer2 Posts: 21Questions: 4Answers: 0

I'm using the Responsive extension so my column resize and play nicely at different resolutions. One of the usability issues I'm running into is the column width can change when I click a column to change the sort order.

I know I can wrap the table in the "nowrap" class, but that's not the behavior we're after.

What I really want is for columns to have a minimum width and for text that doesn't fit in the column to have a text-overflow with an ellipsis.

I've been able to accomplish what I want by doing the following:

  1. Adding an inner div (.datatable-column-width) to each cell w/a the text overflow rules (i.e. overflow: hidden; text-overflow: ellipsis; white-space: nowrap;)
  2. Setting an min-width to each .datatable-column-width element
  3. Attaching a column-sizing.dt event which: (a) sets the width of each header to it's current width (this shouldn't be necessary, but seems to be required) and (b) updating the max-width for each .datatable-column-width element to match it's heading width (using instance.column(idx).nodes()).

This works, but it's pretty expensive because it has to loop through every cell in the table each time the resize event fires.

I could speed things up by building dynamic classes and then updating those styles instead of updating the property on each cell directly. That should speed things up quite a bit.

However, before I do that, does anyone else have a better solution?

(NOTE: I'm also doing something similar so I can create columns with a fixed width. I have some columns where I want to set a specific width for the column and setting the width, min-width and max-width on the cell data seems to be the only way to reliable do this.)

Answers

  • allanallan Posts: 63,457Questions: 1Answers: 10,466 Site admin

    This blog post describes a method that can be used to do the ellipsis - although that is based on a character count rather than exact width (since that is very slow in the DOM).

    The other option is basically to do as you have done. Step 3 shouldn't be required though - I'm not sure why that would be needed. Can you link to a test case showing the issue?

    Allan

  • DanSwitzer2DanSwitzer2 Posts: 21Questions: 4Answers: 0

    @allan

    Thanks for the reply.

    Step 3a definitely shouldn't be needed, but it's not working correctly without it. I still need to look into that. Step 3b is needed to ensure that none of the data inside the cell ends up wider than the header element. Without defining the max-width, the data in the cell can end up being wider than the header and of course that can force the cell to make the column wider.

    I'm getting ready to refactor this code to use dynamic CSS classes, which should be much faster (since I only need to update the classes).

  • DanSwitzer2DanSwitzer2 Posts: 21Questions: 4Answers: 0

    Here's an example of what I'm seeing with the columns changing size. Sort by the "Age" column to see the change in columns widths.

    https://jsfiddle.net/dswitzer/czz8mzrm/

    I set the table width to something small to illustrate the problem. In my use case, I have the width set to 100% but I have a lot of columns.

    Here's a dirty hack which shows what I'm having to do to prevent the columns from changing size:

    https://jsfiddle.net/dswitzer/czz8mzrm/1/

  • allanallan Posts: 63,457Questions: 1Answers: 10,466 Site admin

    Thanks for the test cases!

    https://jsfiddle.net/dswitzer/czz8mzrm/ (Age column)

    The problem here is that the content of the table is forcing the width of the columns. The content simply doesn't allow for the columns to be set at a fixed size, while still keeping the content visible.

    If we add width=100% to your table ( https://jsfiddle.net/czz8mzrm/2/ ) then you will be able to see that there is enough space and thus the Age column does have extra space available in it, even when the large number isn't shown.

    There is one other option - use table-layout: fixed which forces the column widths irrespective of content. Then use text-overflow: ellipsis - https://jsfiddle.net/czz8mzrm/3/ .

    Column widths, without a doubt, are the part of DataTables that I've had the most trouble with!

    Allan

  • DanSwitzer2DanSwitzer2 Posts: 21Questions: 4Answers: 0

    @allan:

    Yes, making the table 100% width changes the behavior (in this specific example), but it doesn't fix the root problem. In my case, my table has a lot of columns that each contain a lot of data. I changed the width in the example because it illustrates the same behavior I'm seeing.

    I've got a table that's 100% wide and even at 1920px wide, the columns are shifting widths because the table ends up re-drawing to best fit the information in the space available.

    This ends up causing usability issues, because you can click on "Column D" and after the table is re-rendered, the cursor ends up under "Column C" because the column width changes. So clicking immediately after the sort doesn't end up sorting by "Column D" again, but instead by "Column C". After the sort the cursor might once again be under "Column D" or it could still be over "Column C". It really depends on the width of the data.

    I'd be happy to use table-layout: fixed, but it doesn't play well with the Responsive extension—which I require.

    I'm planning on working on writing up an extension today which will add in support for:

This discussion has been closed.