Not Working - Changing the width using "columnDefs" OR "columns"

Not Working - Changing the width using "columnDefs" OR "columns"

versaceversace Posts: 8Questions: 1Answers: 0

Link to test case:
columns: http://live.datatables.net/garizemo/1/edit
columnDefs: http://live.datatables.net/powuboco/1/edit
Debugger code (debug.datatables.net):
$(document).ready( function () {
$('#example').dataTable( {
"columns": [
{ "width": "15px" },
null,
null,
null,
null
],
} );
} );
Error messages shown:
columns error: Uncaught TypeError: Cannot read properties of undefined (reading 'mData')
columnDefs error: none
Description of problem:
The width of the columns do not change. It does not matter whether I put "columns" or "columnDefs". How can I change the widths?

I have been trying to apply this guide to no avail: https://datatables.net/reference/option/columns.width

I am using DataTables 1.11.1 on my actual (not test case) project.

Is there any way I can just disable all javascript auto sizing and allow me to style using CSS? I've found it's frustrating having to change styles with javascript.

This question has accepted answers - jump to:

Answers

  • colincolin Posts: 15,112Questions: 1Answers: 2,583

    The error was because you were missing a columns declaration - it needs to match the width of the table - see test case updated here.

    Colin

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,735
    edited January 2022

    Uncaught TypeError: Cannot read properties of undefined (reading 'mData')

    The table has 6 columns but you defined only 5. Updated example:
    http://live.datatables.net/garizemo/2/edit

    You might be interested in this thread talking about how column widths work.

    Kevin

  • versaceversace Posts: 8Questions: 1Answers: 0

    @colin, @kthorngren Thank you for the quick responses and helping me understand the first issue with the mData error.

    @colin you mentioned: it needs to match the width of the table
    If that's the case with 6 columns at 15px each the table would be 90px wide. However after setting the table's style property width and width attribute both to 90px, the columns still aren't 15px each. How would you fix this?
    UPDATED TEST: http://live.datatables.net/garizemo/5/edit

    You might ask, why am I trying to get 15px for each column?
    In my actual project, I would like to be able to display all columns without having to utilize ScrollX. I want the table to be responsive to the browser; I tried implementing the responsive plugin (https://datatables.net/extensions/responsive/) but the table still pushes off page with "responsive:true" enabled. This is why my other question is how can I disable javascript widths altogether so I can easily create these responsive styles in just CSS? Styling with both javascript and css seems harder to maintain.

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,735

    I think Colin is referring to the Cannot read properties of undefined (reading 'mData' error and added another column to the table.

    How would you fix this?

    Did you see Allan's response in the thread I linked to?

    I want the table to be responsive to the browser; I tried implementing the responsive plugin (https://datatables.net/extensions/responsive/) but the table still pushes off page with "responsive:true" enabled.

    Sounds like you haven't defined style="width:100%" on the -table tag as described in this example. Start with this. If you still have problems please provide a link to your page or a test case replicating the issues so we can help debug. You should have to manually manipulate CSS or column widths for Responsive to work.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • versaceversace Posts: 8Questions: 1Answers: 0

    Based on the thread you provided, I understand that making this change:

    <

    table id="example" style="table-layout: fixed;" class="display nowrap" width="90px">
    Would allow me to achieve desired width but then that creates an issue with the height of each cell:

    How would I make it so the content expands in height to accommodate the decreased width?


    I've tried setting the style's width:100% within the table to no avail.
    Here's the test link for the responsive issue: http://live.datatables.net/qibevule/1/edit

    As you can see from the image below, the horizontal scroll is still there:

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,735
    edited January 2022

    Your test case isn't running. Its has these errors:

    Uncaught ReferenceError: jQuery is not defined

    Fixed by moving the responsive.js library to load after everything else.

    Uncaught ReferenceError: nameType is not defined

    Fixed by commenting out the line of code referencing nameType.

    Looks like your table is responsive.

    If you have a horizontal scroll and you are not using `-option scrollX then the scroll bar is from the web browser. This suggests that the container that the Datatable is in is not resizing to the page size.

    Based on the thread you provided, I understand that making this change:
    <table id="example" style="table-layout: fixed;" class="display nowrap" width="90px">

    No. That would fix the table at 90px. Use 100% as specified. This way Datatables can make its calculations based on the width of the container it is in. If you want the table to be 90px then set the container to be 90px with the table width at 100%.

    Kevin

  • versaceversace Posts: 8Questions: 1Answers: 0

    It's hard for me to post an entire test case for my project because information is sensitive, and the file is large. Expanding further, my project is also using: https://cdn.datatables.net/plug-ins/1.11.3/sorting/absolute.js"

    However, it seems that both plugins need to be imported last in order to work properly. I tried switching the import sequence on these plugins to find this out: http://live.datatables.net/nodicanu/1/edit

    Regarding the responsive plugin, even when the responsive plugin is functioning properly it just hides the columns that go off screen as the browser gets smaller. I'm trying to keep the columns all on the same page but scale the text down.

    Would be much easier to have all this javascript disabled and rewrite the css to accomodate.

  • versaceversace Posts: 8Questions: 1Answers: 0

    Here's an updated test link with the absoluteSorting plugin imported without responsive: http://live.datatables.net/vahoqiro/1/edit

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,735
    Answer ✓

    It's hard for me to post an entire test case for my project because information is sensitive, and the file is large.

    We don't expect nor want a full solution with the test case. We just need to see an example of the problem. The problem you are having isn't data specific so you can use fake data.

    Now you are getting this error causing Responsive to not work:

    dataTables.responsive.js:908 Uncaught TypeError: dt.columns(...).header(...).filter is not a function

    It seems the $.fn.dataTable.Api.register('filter.push'.... is overwriting the filter function called by Responsive. You can rename it to something else. I changed it to use `filter1. The change is in two spots:
    http://live.datatables.net/bewozivu/1/edit

    Now responsive works.

    I'm trying to keep the columns all on the same page but scale the text down.

    Don't think there is anything built into Datatables to help with this. Maybe this SO Thread will give you some ideas. @allan or @colin may have some ideas for you.

    Kevin

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,735
    Answer ✓

    Maybe you can adapt the ellipsis plugin to do what you want.

    Kevin

  • versaceversace Posts: 8Questions: 1Answers: 0

    Thank you for all the help Kevin.

    The workaround I found is a bit tough to look at but using jquery after the .DataTable() call I managed to get the result I want. The maintable has 16 columns so this was a challenge.

    var maintable = $('#mainTable').DataTable( {
          "columns": [
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
            { "width": "75px" },
          ],
          //responsive: true,
          dom: 'Bfrtip',
          "scrollY": "600px",
          "scrollX":true,
          "scrollCollapse": true,
          "paging": false,
          "bPaginate": false
        });
    
    $('#mainTable').attr('style', 'table-layout:fixed!important;width: 1200px!important;max-width: 1200px!important;margin:0!important;');
        $('.steel-table.dataTable.no-footer').attr('style', 'table-layout:fixed!important;width: 1200px!important;max-width: 1200px!important;margin:0!important;');
        $('.dataTables_scrollHeadInner').attr('style', 'table-layout:fixed!important;width: 1200px!important;max-width: 1200px!important;');
        $("#mainTable").width('1200px');
        $(".steel-table.dataTable.no-footer").width('1200px');
        $(".dataTables_scrollHeadInner").width('1200px');
    
        $("#mainTable td, #mainTable th").width('75px');
        $(".steel-table.dataTable.no-footer th, .steel-table.dataTable.no-footer td").width('75px');
    
        $("#mainTable td, #mainTable th").attr('style','width:75px!important;max-width:75px!important;overflow: hidden!important;text-overflow: ellipsis!important;word-wrap: break-word!important;padding: 0!important;margin: 0!important;');
        $(".steel-table.dataTable.no-footer th, .steel-table.dataTable.no-footer td").attr('style', 'width:75px!important;max-width:75px!important;overflow: hidden!important;text-overflow: ellipsis!important;word-wrap: break-word!important;padding: 0!important;margin: 0!important;');
    

    Reason for calling, the jQuery after .DataTable() is because even with the width and table-layout style properties being set in my HTML, the moment .DataTable() was done executing it would change those values (ex: to width:3005px;)

    The CSS I'm using from the SO Thread you mentioned doesn't really help but left it there for time being. Important CSS changes was reducing padding, margin, and font-size.

    table { 
      table-layout:fixed!important;
    }
    
    td, th { 
      overflow: hidden!important; 
      text-overflow: ellipsis!important; 
      word-wrap: break-word!important;
      font-size: 12px;
      padding: 0!important;
      margin: 0!important;
    }
    
    @media only screen and (max-width: 480px) {
        /* horizontal scrollbar for tables if mobile screen */
        table {
            overflow-x: auto!important;
            display: block!important;
        }
    }
    

    I plan on cleaning this up today, and changing the width, and max-width that are set to be values calculated from $(window).width() - [size of left colum where other tables are]. Then width of all of the <th> and <td> will be calculated by that value /16.

    I like the idea of enabling the horizontal scroll on phones because 16 columns on a phone would be illegible (hence keeping the overflow-x:auto, display:block media query). As expected, performance is terrible, but I don't mind being patient as long as I can easily scroll through and compare data.

    Other solutions I'm working on would be adding checkboxes to show/hide columns for easier comparison and highlighting the row on mouseclick/tap.

  • versaceversace Posts: 8Questions: 1Answers: 0
    edited January 2022

    Also, explaining my selectors for the workaround a bit.

    I noticed that another table element is created just for the <th> elements that takes only the table class names (.steel-table.dataTable.no-footer)

    All of the <td> elements are stored in a table with the original assigned ID (#mainTable)

    When setting the #mainTable and .steel-table style property widths, I noticed that .dataTables_scrollHeadInner would then be assigned the undesired width (3005px). So that was also changed with jQuery as well.

    Not sure all the .width() are needed. Going to be cleaning this up today.

  • versaceversace Posts: 8Questions: 1Answers: 0

    After cleaning the above code up. Here's my workaround:
    function fixMainTableSize(){
    var browser_width = $(window).width();
    var sidebar_width = $('sidebar').width();
    var table_width = browser_width - sidebar_width;
    var th_td_width = table_width / $('#mainTable th').length;

              //#mainTable is the id of my table
              //.steel-table is the class of that same table
    
              $('#mainTable').attr('style', 'table-layout:fixed!important;width: ' + table_width + 'px!important;max-width: ' + table_width + 'px!important;margin:0!important;');
              $('.steel-table.dataTable.no-footer').attr('style', 'table-layout:fixed!important;width: ' + table_width + 'px!important;max-width: ' + table_width + 'px!important;margin:0!important;');
              $('.dataTables_scrollHeadInner').attr('style', 'table-layout:fixed!important;width: ' + table_width + 'px!important;max-width: ' + table_width + 'px!important;');
    
              $("#mainTable td").attr('style','width:' + th_td_width + 'px!important;max-width:' + th_td_width + 'px!important;overflow: hidden!important;text-overflow: ellipsis!important;word-wrap: break-word!important;padding: 0!important;margin: 0!important;');
              $(".steel-table.dataTable.no-footer th").attr('style', 'width:' + th_td_width + 'px!important;max-width:' + th_td_width + 'px!important;overflow: hidden!important;text-overflow: ellipsis!important;word-wrap: break-word!important;padding: 0!important;margin: 0!important;');
            }
    
            $( window ).resize(function() {
              fixMainTableSize();
            });
    
        $(document).ready(()=>{
          var maintable = $('#mainTable').DataTable( {
            columnDefs: [
              { targets: 0, type: nameType },
            ],
            dom: 'Bfrtip',
            "scrollY": "600px",
            "scrollX":true,
            "scrollCollapse": true,
            "paging": false,
            "bPaginate": false
          });
    
          fixMainTableSize();
        });
    

    Again minus performance issues, this gets me the desired result.

  • colincolin Posts: 15,112Questions: 1Answers: 2,583
    edited January 2022

    Thanks for posting, twice, the spam filter caught the first one for some reason!

    Colin

Sign In or Register to comment.