Coty Embry
Coty Embry

Reputation: 978

DataTables issue: VM9075 dataTables.min.js:24Uncaught TypeError: Cannot set property '_DT_CellIndex' of undefined

I just started using DataTables and everything works fine when creating the table.

When I display 5, 24, 47 rows in my table, DataTables behaves as I would expect.

But I have this table that has around 700 rows and I get the error in Google Chrome,

"VM9075 dataTables.min.js:24Uncaught TypeError: Cannot set property '_DT_CellIndex' of undefined "

and in IE 9,

"SCRIPT5007: Unable to set value of the property '_DT_CellIndex': object is null or undefined 
jquery-1.10.2.min.js, line 4 character 2367"

I don't have jQuery included twice btw.

I'm not sure how to proceed from here.

I tried to use the unminified version of the .js file to debug it more myself but i kept getting an "ext" method or property is undefined and couldn't fix that either.

Any help is appreciated!

Upvotes: 12

Views: 27773

Answers (6)

ryanrain
ryanrain

Reputation: 4837

this error can also be triggered if you try to set options for the responsive extension for more columns than you have.

Upvotes: 0

jay
jay

Reputation: 1

$( '.table' ).each(function( i ) { 

    var worktable = $(this);
    var num_head_columns = worktable.find('thead tr th').length;
    var rows_to_validate = worktable.find('tbody tr');

    rows_to_validate.each( function (i) {

        var row_columns = $(this).find('td').length;
        for (i = $(this).find('td').length; i < num_head_columns; i++) {
            $(this).append('<td class="hidden"></td>');
        }
    });
});

Upvotes: -1

Mahesh Vora
Mahesh Vora

Reputation: 91

you always keep four column but sometimes you will receive or append null td or only one td, td count always match with total column so when you does not have record then make td as following.

<th>No</th>
<th>Name</th>
<th>place</th>
<th>Price</th>
----------------------------------------   
<td colspan="4">Data not found.</td>
<td style="display: none;"></td>
<td style="display: none;"></td>
<td style="display: none;"></td>

Upvotes: 4

frostedpops
frostedpops

Reputation: 165

Ran into this same issue and implemented this same solution (essentially) in jquery based on Coty's. Hope this helps someone. :)

$( '.table' ).each(function( i ) { 

    var worktable = $(this);
    var num_head_columns = worktable.find('thead tr th').length;
    var rows_to_validate = worktable.find('tbody tr');

    rows_to_validate.each( function (i) {

        var row_columns = $(this).find('td').length;
        for (i = $(this).find('td').length; i < num_head_columns; i++) {
            $(this).append('<td class="hidden"></td>');
        }

    });

});

Upvotes: 7

Abhishek Poojary
Abhishek Poojary

Reputation: 809

As answered by Coty, the problem lies in the mismatch of td elements generated in the header and body of table.

I'd like to highlight one of the reasons why it can occur (For .Net Users). If Page numbers are being displayed at the end of gridview, they can disrupt table structure.

Remove AllowPaging="true" from your gridview to solve this. And no worries because Datatable handles Paging.

Upvotes: 6

Coty Embry
Coty Embry

Reputation: 978

I figured it out

The biggest issue was not knowing exactly what this error actually meant. In my case it meant "the number of every <td> element in your table that is a child of a <tr> element doesn't match the number of <th> elements that are a child of the <thead> element."

My table was being generated by the server, and some of the <tr> elements had 27 <td> children (which was filling the whole width of the table up, but some of the <tr> elements only had 3, 4, or 5, ... <td> child elements which isn't a valid table.

I solved it by adding empty <td> elements in my table for the <tr> elements that lacked the correct number of <td> elements

var makeTableValidObject = {
    thisWasCalled: 0,
    makeTableValid: function() {
        var tableToWorkOn = document.getElementById("table1");      
        //check the number of columns in the <thead> tag
                                                   //thead     //tr        //th      elements
        var numberOfColumnsInHeadTag = tableToWorkOn.children[1].children[0].children.length;
        var numberOf_trElementsToValidate = tableToWorkOn.children[2].children.length;      
        //now go through each <tr> in the <tbody> and see if they all match the length of the thead columns
                       //tbody     //all trs//all tds   elements
         //tableToWorkOn.children[2].children.children);        
        for(var i = 0; i < numberOf_trElementsToValidate; i++) {
            //row my row make sure the columns have the correct number of elements
            var tdColumnArray =  tableToWorkOn.children[2].children[i].children
            var trElementToAppendToIfNeeded = tableToWorkOn.children[2].children[i];
            if(tdColumnArray.length != numberOfColumnsInHeadTag) {
                //since they don't match up, make them valid                
                if(tdColumnArray.length < numberOfColumnsInHeadTag) {
                //add the necessary number of blank <td> tags to the <tr> element to make this <tr> valid
                    var tdColumnArrayLength = tdColumnArray.length;
                    for(var j = 0; j < (numberOfColumnsInHeadTag - tdColumnArrayLength); j++) {
                        var blank_tdElement = document.createElement("td");
                        blank_tdElement.id = "validating_tdId" + i + "_" + j;
                    trElementToAppendToIfNeeded.appendChild(blank_tdElement);           
                    }
                }
                else {
                    //TODO: remove <td> tags to make this <tr> valid if necessary                   
                }
            }
        }
    }
};

Edit 1:

It has been awhile and this question is still getting a bunch of views. I have since updated the code.

I replaced the first line of code with the second line to be more general

var numberOfColumnsInHeadTag = tableToWorkOn.children[1].children[0].children.length;

var numberOfColumnsInHeadTag = tableToWorkOn.querySelectorAll('thead')[0].querySelectorAll('th');

Pretty much where ever in the prior code you see the children.children I replaced that with the querySelectorAll(...) Function.

It uses css selectors which makes it amazingly powerful.

stay blessed

Upvotes: 23

Related Questions