Access DataTables' auto-calculated column widths
Access DataTables' auto-calculated column widths
Let's say I have a table where some cells have too much text, which I'd like to clip with a trailing ellipsis instead of wrapping to the next line.
Right now, the only solution I can think of is to set a custom render()
for the given column, and wrap the cell text in a <span>
with some css classes (text-overflow: ellipsis
etc.), and then set a max-width
on said <span>
.
However, this means I have to manually set the max-width
, sacrificing this library's automatic column width calculation. Which is why I'm wondering: is it possible to somehow get the calculated width of a column using this library, in the preDrawCallback
for instance?
It's also possible I'm wrong and there is a much better solution for this.
P.S. I'm using DataTables 1.13.7.
Answers
With 1.x no (other than reading the width that was calculated in the DOM).
With 2+ you could use
column().width()
.However I don't think that will do what you need since the column widths depend on the content. You are proposing to change the content, which would effect the column widths! It becomes circular.
It is a bit of an unsolved problem at the moment. There are workarounds, such as assigning max-widths manually, but a table which does ellipsis overflow with auto widths... that's a difficult problem. Imagine for example you have two columns which need that, do you do them equally, or give one a higher priority?
Sorry I don't have a better answer!
Allan
I was thinking more along the lines of allowing DataTables to calculate the optimal widths by itself, and then, before the table is actually drawn, clipping the cell text(s) at exactly the width(s) that DataTables has calculated. AFAIU this shouldn't affect the resulting widths of the columns that much, i.e. they should be as wide as they would have been otherwise, the only difference being the cell text no longer being multi-line, but rather being clipped and ellipsized.
I'm with you now - yes, let it multi-line render and then clip it down. I wonder if a
div
as a wrapping element for the cells (which could be done with a rendering function) set toheight: 1em; overflow: hidden
would do it. You wouldn't get ellispsis if you did that though. There is no way to get text ellispis without usingwhite-space: nowrap
, which would make this approach fail. Javascript could add them, but that seems like a lot of overhead.Allan
@allan can I also read the css (padding etc.) of the cell nodes in
preDrawCallback
?column().cells()
seems to be empty when I try to access it at this point.It looks like it: https://live.datatables.net/buvumiqa/1/edit .
If you are Ajax loading the data though, then the table would be empty at that point, so there would be no cell to read.
Allan
@allan hi again
I have noticed a (weird/expected/idk) behavior when trying to read
table.column(idx).width()
withoptions.scrollY
on.https://live.datatables.net/xedayiyo/2/edit
In the JS file, if you comment out the
scrollY
setting, the correct calculated widths will be logged. But with the setting on, you'll just see equally divided widths (even though visually both cases will look the same).This doesn't precisely replicate the problem I have in my local setup (where some of the width logs are actually
0
), but I suppose it's close enough.Do you know why this is the case?
Its almost certainly to do with the sequence of events and dynamic loading of data. If you use
drawCallack
it works as expected. Think what is happening is that in the preDraw there is no data in the table, thus the columns are effectively spaced out at that point. Putting a breakpoint into thepreDrawCallback
confirms that.So I think this is actually expected, if not exactly what might be desired. I don't see a way to change that.
Allan
@allan But isn't there also no data during
preDraw
withscrollY
unset? By the logic of your explanation, I would expect the logs to be inaccurate in both cases. But they happen to be correct if you comment outscrollY
.Fair point! I missed that point and in that case, I'm not 100% certain why it is different. I'll need to go through the code at some point and remind myself what is happening. I never expected
column().width()
to be used inpreDrawCallback
so it isn't something I ever tested.Allan