Uncaught TypeError: col is undefined

Uncaught TypeError: col is undefined

coursevectorcoursevector Posts: 4Questions: 1Answers: 0

Link to test case: https://dev.coursevector.com/boroughtest/test-table/
Debugger code (debug.datatables.net): https://debug.datatables.net/efemeb
Error messages shown: Uncaught TypeError: col is undefined
Description of problem: Trying to use Datatables on an html table that has no thead or tfoot. There looks to be an error in Datatables.js where if it can't find columns it tries to pull data from an empty array and fails. Looking at the code, aoColumnsInit is initially null. It is then supposed to be populated via anThs, except if there is no <thead> found, then anThs is never populated. So it runs through, checks aoColumns which is null, initializes aoColumnsInit as an empty array and then doesn't populate it with anything because anThs is empty. It later initializes oSettings.aoColumns with nothing because aoColumnsInit it empty. Then finally it tries to pull col from the oSettings.aoColumns which is empty and throws an error. I don't see how this could run unless it has a <thead> available.

            /*
             * Columns
             * See if we should load columns automatically or use defined ones
             */
            var anThs = [];
            var aoColumnsInit;
            var nThead = this.getElementsByTagName('thead');
            if ( nThead.length !== 0 )
            {
                _fnDetectHeader( oSettings.aoHeader, nThead[0] );
                anThs = _fnGetUniqueThs( oSettings );
            }
            
            /* If not given a column array, generate one with nulls */
            if ( oInit.aoColumns === null )
            {
                aoColumnsInit = [];
                for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
                {
                    aoColumnsInit.push( null );
                }
            }
            else
            {
                aoColumnsInit = oInit.aoColumns;
            }
            
            /* Add the columns */
            for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
            {
                _fnAddColumn( oSettings, anThs ? anThs[i] : null );
            }
            
            /* Apply the column definitions */
            _fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
                _fnColumnOptions( oSettings, iCol, oDef );
            } );
            
            /* HTML5 attribute detection - build an mData object automatically if the
             * attributes are found
             */
            if ( rowOne.length ) {
                var a = function ( cell, name ) {
                    return cell.getAttribute( 'data-'+name ) !== null ? name : null;
                };
            
                $( rowOne[0] ).children('th, td').each( function (i, cell) {
                    var col = oSettings.aoColumns[i]; // <--------------------------------- Error
                    // ...
                } );
            }

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,144Questions: 26Answers: 4,736
    edited October 2020 Answer ✓

    I'm seeing this error in your test case:

    datatables.js?ver=1.10.22:1183 Uncaught TypeError: Cannot read property 'mData' of undefined

    I believe thats a mismatch between the number of columns defined in the table and the number defined in Datatables.

    I don't see how this could run unless it has a <thead> available.

    The HTML requirements state this:

    the table must be valid, well formatted HTML, with a header (thead) and a single body (tbody).

    If you don't have a thead defined in HTML then you can use columns.title to define the header.

    Also it looks like you are loading datatables.js twice:

    <script type='text/javascript' src='https://dev.coursevector.com/boroughtest/wp-content/plugins/functional-gov-wp/vendor/datatables/datatables.js?ver=1.10.22' id='functional-gov-wp-datatables-script-js'></script>
    <script type='text/javascript' src='https://dev.coursevector.com/boroughtest/wp-content/plugins/functional-gov-wp/assets/js/datatables.js?ver=1.2.0' id='functional-gov-wp-datatables-script2-js'></script>
    

    This will cause problems. It should be loaded only once.

    Kevin

  • coursevectorcoursevector Posts: 4Questions: 1Answers: 0

    Kevin,

    Thanks for answering, i know i have two JS files named the same but they are two different scripts.

    And thanks for pointing me in the right direction regarding the requirements. I tried looking here: https://datatables.net/examples/data_sources/dom.html but didn't think the Installation page had the requirements (or that thead would be a requirement).
    Might i suggest a graceful exit with a message in console rather than fail out right?

    I originally started using DataTables because it supports responsive tables. But i thought it would work regardless of the thead/column titles. Do you think that will ever be a possibility or have a suggestion on an alternative that does?

    Gabriel

  • kthorngrenkthorngren Posts: 20,144Questions: 26Answers: 4,736

    But i thought it would work regardless of the thead/column titles. Do you think that will ever be a possibility or have a suggestion on an alternative that does?

    Datatables uses the header to attach the sorting listeners and maybe other things.
    You can always hide the header like this:
    http://live.datatables.net/zifasute/1/edit

    Kevin

  • coursevectorcoursevector Posts: 4Questions: 1Answers: 0

    Unfortunately it's not a matter of seeing the headers but that I can't assume the headers will exist in the first place. I was hoping to find a "universal" responsive table script in DataTables. But I should have taken a clue from the name and realized it's literally intended for "data tables". =)

  • kthorngrenkthorngren Posts: 20,144Questions: 26Answers: 4,736

    It is possible to dynamically create the columns. Here is a simple example using Ajax data and the ajax response to build and apply the columns. Note the use of columns.title for the header.

    Kevin

  • coursevectorcoursevector Posts: 4Questions: 1Answers: 0

    Sorry, and you are being helpful, but the tables being displayed aren't necessarily data related. So for example a site like this: https://middleburgborough.com/government/borough-council/ . There are no column headers and really shouldn't be.

    Here they are clearly using a table to display something non-data related. I know this would be better served as divs+css but i can't always control how the client enters the data so I was trying to work around them. Thanks again for your help.

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

    Yep, see this quote from this page:

    For DataTables to be able to enhance an HTML table, the table must be valid, well formatted HTML, with a header (thead) and a single body (tbody). An optional footer (tfoot) can also be used.

    The header is mandatory. You could try hiding the header afterwards in initComplete, but that would break Responsive (and possibly other things) - see here.

    Colin

This discussion has been closed.