Datatable with multi header

Datatable with multi header

svyas001svyas001 Posts: 41Questions: 4Answers: 0

Hi Team,

My requirement is like as below

1] Multi-header
2] Category should be display as Group
3] Excel and pagging on TOP display left side and search text box should be display right side.

I have created the html and when we ran the app we are getting an unknown parameters error.

When I implemented the same html into editor the excel button, grouping and pagging is not working see the example

https://live.datatables.net/teduneji/1/

Attached the actual output we need with column sorting, pagging, search and excel.
- this should be removed

Appreciate your help!

Thank you

Answers

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0

    Hi Team,

    https://live.datatables.net/teduneji/4/

    I have created another example but I am getting below error

    Uncaught TypeError: Cannot read properties of undefined (reading 'cell')
    at Te (datatables.min.js:16:23904)
    at _e (datatables.min.js:16:24169)
    at n (datatables.min.js:16:34521)
    at Me (datatables.min.js:16:35329)
    at HTMLTableElement.<anonymous> (datatables.min.js:16:6980)
    at E.each (jquery-3.5.1.slim.min.js:2:3182)
    at E.fn.init.each (jquery-3.5.1.slim.min.js:2:1660)
    at E.fn.init.V [as dataTable] (datatables.min.js:16:1327)
    at H.fn.DataTable (datatables.min.js:16:95586)
    at HTMLDocument.<anonymous> (4:528:44)

  • kthorngrenkthorngren Posts: 21,837Questions: 26Answers: 5,048
    edited March 19

    Cannot read properties of undefined (reading 'cell')

    The colspan values add up to 18 in the first two header rows. In the third they only add up to 12. Each header row needs to have the same total number of colspan. Dataatables uses the first -tag thead` row to determine the number of columns. It places sorting event listeners in each cell. I believe this error is coming from the fact that you are missing the last 6 cells in the third header and thus they are undefined.

    You defined colspan in the tbody which is not supported by Datatables. See the html requirements doc for more details. I believe this is why you are seeing the extra cells to the right of the table.

    unknown parameters error

    See the url linked in the error for troubleshooting steps:
    https://datatables.net/manual/tech-notes/4

    It is due to using colspan in the tbody. Datatables counts each td as a cell and doesn't pay attention to the colspan. Datatables sees 16 columns defined in the -tag tbodybut 18 in the -tag thead. Datatables believes that the data for columns 17 and 18 are missing thus the error.

    Category should be display as Group

    Looks like you are using the Target column for this. Is this working as expected?

    Excel and pagging on TOP display left side and search text box should be display right side.

    Use the layout option for this. Here are some examples.

    Kevin

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0
    edited March 19

    Hi Kevin,

    Thanks for reply and as you suggested I made equal colspan and it fixed the issue.

    Can you please let me know how we can make this responsive?

    The current pagging is into center, I want to be set to the left side end and how can we change the pagging buttons and text?

    I want to take of the datatable scroll bar and make it responsive.

    https://live.datatables.net/teduneji/9/

    I want to change the pagging UI like attached and want to merge the buttons as attached.


  • kthorngrenkthorngren Posts: 21,837Questions: 26Answers: 5,048

    Can you please let me know how we can make this responsive?

    You need to add the Responsive library. See the Responsive download docs for details.

    It sounds like you want to apply styling to the buttons. You can use buttons.buttons.className to assign classes then use CSS to apply the appropriate styling.

    Kevin

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0
    edited March 19

    Hi Kevin,

    When I applied the bootstrap js and css it gives me an error, I have already set responsive property. When I add below two scripts

    <script src="https://cdn.datatables.net/responsive/3.0.4/js/dataTables.responsive.js"></script>
    <script src="https://cdn.datatables.net/responsive/3.0.4/js/responsive.bootstrap4.js"></script>
    

    it gives started me an error, see the reference.

    Uncaught TypeError: Cannot read properties of undefined (reading 'cell')
    at vt (dataTables.min.js:4:56009)
    at X.<anonymous> (dataTables.min.js:4:62640)
    at X.iterator (dataTables.min.js:4:48690)
    at X.<anonymous> (dataTables.min.js:4:62601)
    at X.<anonymous> (dataTables.min.js:4:50384)
    at X.header (dataTables.min.js:4:49642)
    at X.<anonymous> (dataTables.responsive.js:574:28)
    at X.map (<anonymous>)
    at X.map (dataTables.min.js:4:48902)
    at Responsive._classLogic (dataTables.responsive.js:572:5)

    https://live.datatables.net/teduneji/10/

  • kthorngrenkthorngren Posts: 21,837Questions: 26Answers: 5,048

    I copied your full HTML code into the W3C Validator and it reports this error affect Datatables.

    Warning: A table row was 16 columns wide and exceeded the column count established by the first row (15).
    From line 60, column 96; to line 61, column 37

    Looks like your second header row has 16 cells where the first has 15.

    Kevin

  • kthorngrenkthorngren Posts: 21,837Questions: 26Answers: 5,048
    edited March 19

    Also this error in the tbody:

    Warning: A table row was 16 columns wide and exceeded the column count established by the first row (15).
    From line 119, column 46; to line 120, column 41

    I guess an additional th needs to be added to the first header.

    Also the test case was missing dataTables.responsive.min.js and responsive.bootstrap5.js but has responsive.bootstrap5.min.css.

    I added the two responsive JS includes and added a th to the last column in the first header.

    https://live.datatables.net/teduneji/11/edit

    Responsive is now working.

    EDIT: Typically when you see Cannot read properties of undefined (reading 'cell') you can assume there is a mismatch in the number of columns in the thead and tbody and start troubleshooting there.

    Kevin

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0

    Thank you. so much Kevin. You are star :smile:

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0

    Hi Kevin,

    https://live.datatables.net/teduneji/11/edit

    Can we remove this scrollbar?

  • kthorngrenkthorngren Posts: 21,837Questions: 26Answers: 5,048
    edited March 20

    You have this:

    <div class="table-responsive">
    

    Which enables Bootstrap's table responsive. It's goal is similar to Datatables Responsive. They will compete with each other. Remove he class table-responsive or the div to use Datatables Responsive.

    Also this is incorrect:

    <table id="projectTable" class="table datatable-responsive">
    

    According to the Responsive docs use either responsive or dt-responsive on the table tag. This is redundant to using responsive: true. You can use both but I would suggest using only one to reduce confusion later when making changes or troubleshooting.

    Kevin

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0

    HI Kevin,

    https://live.datatables.net/teduneji/15/

    Thanks it worked, but now I have another problem, When I expand the row it is not displaying the first header title such as 2026,2027 and Overall Total, see example. If you want to see the title then you have to zoom out you can see two columns header.

    Actual output

  • kthorngrenkthorngren Posts: 21,837Questions: 26Answers: 5,048
    edited March 20

    Your test case still has only 15 columns in the first header:

                                    <tr>
                                        <th width="15%" colspan="1" data-dt-order="disable"></th>
                                        <th width="15%" colspan="1" data-dt-order="disable"></th>
                                                    <th colspan="10" class="text-center" data-dt-order="disable">
                                                        2025
                                                    </th> <!-- Merged Year Header -->
                                                    <th colspan="1" class="text-center" data-dt-order="disable">
                                                        2026
                                                    </th> <!-- Merged Year Header -->
                                                    <th colspan="1" class="text-center" data-dt-order="disable">
                                                        2027
                                                    </th> <!-- Merged Year Header -->
                                        <th colspan="1" data-dt-order="disable">
    
                                        </th>
                                    </tr>
    

    I believe Responsive follows the orderCellsTop definition to choose when header row to use for the titles in the default Responsive renderer. The default is to use the bottom header row. You will need to use responsive.details.renderer to fetch the titles from different header rows. See this example. Use column().title() to specify the row to get the title from.

    I updated your test case to show an example:
    https://live.datatables.net/teduneji/16/edit

    I updated the last column with colspan="2" otherwise my test case will result in your favorite error Cannot read properties of undefined (reading 'cell') :wink:

    Kevin

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0

    Hi Kevin,

    Thank you :smiley:

    Can we hide other fields and show when we click on particular header column like slider in excel.

    For example, we will hide the fields related to 2026 and 2027 and show particular fields when click on 2026 or 2027 into the same datatable?

    Thank you,
    Sanket Vyas

  • kthorngrenkthorngren Posts: 21,837Questions: 26Answers: 5,048

    One option is to use Column Visibility. See these examples.

    Another option is to use column().visible() or columns().visible() to programmatically show / hide columns in your event handlers.

    Kevin

  • kthorngrenkthorngren Posts: 21,837Questions: 26Answers: 5,048

    You may have some interesting effects with Responsive since it also hides columns. You may need to use Column Priority like this example or use class control like this examples or this example to keep the proper columns visible.

    Kevin

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0

    Hi Kevin,

    Thank you, I will try to implement and let you know.

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0
    edited March 20

    Hi Kevin,

    https://live.datatables.net/teduneji/17

    When I hide the columns the header is displaying weird. Can we display all the column for section wise e.g all the column for 2025 Actual, Target, Actual, Target, Actual, Target, Forecast, Target, currently to see the last Target column we have to do expand.

    Also, I have added one button to Show all the column it shows all the column but how we can display the title name before start the other column? See the second image.

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0

    Hi Kevin,

    https://live.datatables.net/teduneji/18

    Also, when I tried to set the width of the particular column, it's not working.

    { width: '5%', targets: 3 }

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0

    Hi Kevin,

    I did try to set using the class as well but it's not working.

    Appreciate your help.

    Thank you,
    Sanket Vyas

  • kthorngrenkthorngren Posts: 21,837Questions: 26Answers: 5,048
    edited March 21

    I think your requirement will be very complex using both responsive and columns.visible(). I think using responsive to hide the groups would be easiest. First thing to do is to add the all class to the first two and last two columns - I assume you want those always visible. Like this:

               {
                 targets: [0, 1, -1, -2],
                 className: 'all main'
               },
    

    I'm adding main, you can call it what you like, to those columns as they aren't part of a section, ie 2025, 2026 or 2027. You will see how its used in a moment.

    Then add a class to designate the columns in each section, for example:

               {
                 targets: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
                 className: 'year-25'
               },
    

    You could add this class directly in HTML if you prefer.

    If you want to start by displaying 2025 then use something like this to force to show and 2026, 2027 to hide:

         table.columns( ['.year-26', '.year-27'] )
          .header()
          .to$()
          .addClass('none');;
    
         table.columns('.year-25')
          .header()
          .to$() // Convert to a jQuery object
          .addClass('all');;
    
        // Tell reposnive to recalc the hidden columns
        table.responsive.rebuild();
        table.responsive.recalc();
    

    You could start with adding the none or all class names in columnDefs to set the default display.

    Then toggle the two classnames depending on which section or sections you want to show. For example:

       // Show all columns
       table.columns( ':not(".main")')
        .header()
        .to$()
        .removeClass('none')
        .addClass('all');
    

    Note the use of the column-selector as a class with :not(".main"). This will select all the columns but the first two and last two with the class main.

    To get the title when the section changes add a variable to keep track of where the sections change:

                       // Define section start indexes
                       let startCols = [2, 12, 22];
    

    Then get the first header row title when the section changes:

                               if ( startCols.includes( index ) && col.hidden ) {
                                 sectionTitle = '<tr><td><b>' + api.column( index ).title(0) + '</b></td></tr>';
                               } else {
                                 sectionTitle = '';
                               }
    

    Prefix the child row HTML with the tr for each section change:

                                 return col.hidden
                                     ? sectionTitle + 
                                     '<tr data-dt-row="' +
    

    I added a button to show year 2027.

    This solution negates the automatic hiding of columns by responsive. See the following docs for the additional APIs used:

    column().header()
    responsive.rebuild()
    responsive.recalc()

    Also, when I tried to set the width of the particular column, it's not working.

    It could be the data in the column is larger than 5% so the browser will widen the column. See this thread for Allan's explanation of how column widths are calculated.

    Kevin

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0

    Hi Kevin,

    https://live.datatables.net/teduneji/20/

    Thanks for reply as usual.

    Somehow I am able to set the title and header when expand the column. Now the only issue is to set the width of the column.

    Thanks.

  • svyas001svyas001 Posts: 41Questions: 4Answers: 0

    Hi Kevin,

    I added a button to show year 2027.

    I did not find this, also I have gone through Allan's explanation but it's not working.

  • kthorngrenkthorngren Posts: 21,837Questions: 26Answers: 5,048

    I updated your test case to add table-layout: fixed; to your table. This uses the width's you configured instead the browser determining the width. You can see the column content is actually bigger that you defined causing the text to overwrite the sorting icons:
    https://live.datatables.net/teduneji/21

    Kevin

  • kthorngrenkthorngren Posts: 21,837Questions: 26Answers: 5,048

    I did not find this

    Sorry I forgot to post the test case :smile:

    https://live.datatables.net/fuhehili/1/edit

    Never mind my post about table-layout. It is incorrect. However if you apply it with autoWidth false you can see the width setting is applied. Note the width setting will need to be applied to all the columns when using table-layout.: fixed.

    https://live.datatables.net/qojaduco/1

    Note I also applied width setting to the first two columns.

    Kevin

Sign In or Register to comment.