column width

column width

rf1234rf1234 Posts: 2,801Questions: 85Answers: 406
edited April 2022 in DataTables

I have a problem with my table's column width. There is one column that contains a lot of text but it is drawn way too small. In this testcase provided by Kevin: http://live.datatables.net/jatazeho/4150/edit everything works fine but not in my case. I tried to set width the same way as in Kevins example but everything was always completely ignored by Data Tables. Even CSS manipulations outside the API didn't help. That was really amazing.

Please take a look at the screen shot below. Column "Ereignisse" contains a lot of text and is really narrow. Column "Dokumentation" is empty except for only one cell which makes it very wide. I am lost. Please help.

And then I played a trick on Data Tables by using one of those absurdly long German words in the heading (it's more like half a dozen of words - just concatenated).

That must have shocked Data Tables and made it do proper column width calculations ..

This question has an accepted answers - jump to answer

Answers

  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406
    edited April 2022

    And another trick in the HTML which I have echoed by PHP to support two languages:

    <th class="base noSearch visibleForTasks eventsCol" id="furtherEventsCol">
        <?php echo $en?('Events'):('Ereignisse' . 
        '<span style="visibility: hidden;">blablablablablablablablablabblablablablablablablablablablablablabla</span>');?></th>
    

    I have just added blablablablablablablablablabblablablablablablablablablablablablabla with visibility:hidden.

    And it looks like this (see below): That's what I need!

    My impression is that Data Tables uses maximum string length in a column and calculates column width (mostly) based on that. I think I read something like that from Allan in a different thread. If I am mistaken I apologize in advance.

    In my opinion Data Tables should use the length of the entire cell and header content, not just the length of the longest string inside it, to make the column width calculations. Sound like a bug to me.

    I found this comment from @allan of April 2017:

    The way the column widths work in DataTables is that DataTables will create a "worst case" table when it is initialised (and if columns.adjust() is called). The worst case table takes the longest string from each column and puts them all on a single row - so the table (which is hidden btw) has the header, a single body row with all the longest strings and the footer. The widths given are then applied to that table and the actual widths are read back from it.

    https://datatables.net/forums/discussion/comment/195606/#Comment_195606

  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406

    Workaround:

    if you have multiple lines in a cell, e.g. rendered values from an MJoin, make sure you replace all spaces in the text part of your line with non-breaking spaces. At the end of the line add a "<br>" tag. This way you can fool data tables: It thinks that the entire line is one string. And that is what you need in these cases.

    You need to do the replacement BEFORE you add HTML tags to your text. Otherwise it gets really complicated:

    // replace all spaces with non-breaking spaces
    txtLine = ( row.ctr_event[ix].due_date + taskEvent + ': ' +
                row.ctr_event[ix].event_msg )
            .replace(/ /g, '&nbsp;');
    

    If you do an Excel export later you need to get rid of the non-breaking spaces in

    exportOptions.format.body
    
    data = data.replace(/&nbsp;/g, " ");
    

    Looks ok now:

  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406
    edited April 2022

    It's probably not a bug :smiley:

    I think it's pretty cool: Just by replacing spaces with non-breaking spaces in parts of your string you can achieve the desired result. And "search" still works. All you need to take care of is the Excel export.

    Here in this renderer I only replace the spaces in "ctr.ctr_name" with non-breaking spaces. And get the result I need: I want to fit "ctr.ctr_name" in one column cell without line break. The rest may go into the next line(s) within the column.

    Awesome!

    {   data: "ctr.ctr_name",
        render: function ( data, type, row ) {
            var str = renderPurpose(row.ctr.serial, row.ctr.purpose, data.replace(/ /g, '&nbsp;'));
            if ( row.ctr.soft_deleted > 0 ) { 
                var del = lang === 'de' ? '[Gelöscht]' : '[Deleted]';
                str += '<br><span class="text-danger-plus">' + del + '</span>';
            } else if ( row.ctr.expired > 0 ) {
                if ( filterExpirations(-1, row.ctr.end_date ) ) {
                    var exp = lang === 'de' ? 
                        '[Wurde endgültig beendet am ' + row.ctr.end_date + ']' : 
                        '[Was finally ended on ' + row.ctr.end_date + ']';
                } else {
                    var exp = lang === 'de' ? 
                        '[Wird endgültig beendet per ' + row.ctr.end_date + ']' : 
                        '[Will be finally ended on ' + row.ctr.end_date + ']';
                }
                str += '<br><span class="text-danger-plus">' + exp + '</span>';
            }
            return str;
        }
    },
    
  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406

    I am surprised I get zero comments on this!

    Did you guys all know that you only need to fiddle with non-breaking spaces and can fine tune DataTable's column width allocations by doing so?

    Am I the only moron around who wasn't aware of this?

    Not an issue / challenge for anybody else?

    Amazing!

    Another example before everyone goes to sleep about this post. This is to make sure the column doesn't do the first line break before 100 characters have been reached. If I had replaced all spaces with non-breaking spaces the column could become very wide.

    {  data: "vat_question.vat_hint",
        render: function (data, type, row) {
            if ( data > "" ) {
                return data.substr(0,100).replace(/ /g, '&nbsp;') + data.substr(100);
            }
            return data;
        }
    },
    
  • allanallan Posts: 61,439Questions: 1Answers: 10,053 Site admin
    Answer ✓

    Hi Roland,

    I think "moron" is doing yourself down rather a lot there ;). You are absolutely right though and it comes back to my comment that you quoted above - if you use a non-breaking space, then you effectively force the column width by making the line longer.

    The key thing to remember with column widths is that the browser will try to wrap the columns down to fit in as much information as possible. So even if you have Responsive enabled, then the browser will still try to wrap columns down unless you use white-space: nowrap on the table or a specific column, or you use &nbsp;.

    Your use of it for the first 100 characters is really neat - I like that a lot! The only thing I would warn about using nbsp is that it is a different character. So if you copy / paste from the table and expect the data to only have spaces, that might no longer be the case.

    Allan

Sign In or Register to comment.