Uncaught TypeError: col is undefined
Uncaught TypeError: col is undefined

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
I'm seeing this error in your test case:
I believe thats a mismatch between the number of columns defined in the table and the number defined in Datatables.
The HTML requirements state this:
If you don't have a
thead
defined in HTML then you can usecolumns.title
to define the header.Also it looks like you are loading
datatables.js
twice:This will cause problems. It should be loaded only once.
Kevin
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
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
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".
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
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.
Yep, see this quote from this page:
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