I am using the code from the individual column filtering and I came across what I think could be a bug in the code. I have multiple tables in my site on different pages. Each table has its own settings therefor I need to utilize this filtering multiple times. I found that when doing this if you give your footer a class name and each tables footer has the same class name then datatables crashes.
I have pulled the common code out into a single file:
Then the code specialized for each table is in its own separate file. The first file is:
And the second file is this:
As you see I have $("tfoot th.makeSelect") in both files. Having it the same class name causes datatables to crash. If a user assigns class names to table footers the only way this can work is if each table has a different class name. To be specific the error I was getting is "uncaught typeerror: cannot read property 'aiDisplay' of null". As a side note I get the same error even if I keep the code in a single file.
I have pulled the common code out into a single file:
(function($) { /* * Function: fnGetColumnData * Purpose: Return an array of table values from a particular column. * Returns: array string: 1d data array * Inputs: object:oSettings - dataTable settings object. This is always the last argument past to the function * int:iColumn - the id of the column to extract the data from * bool:bUnique - optional - if set to false duplicated values are not filtered out * bool:bFiltered - optional - if set to false all the table data is used (not only the filtered) * bool:bIgnoreEmpty - optional - if set to false empty values are not filtered from the result array * Author: Benedikt Forchhammer <b.forchhammer /AT\ mind2.de> */ $.fn.dataTableExt.oApi.fnGetColumnData = function ( oSettings, iColumn, bUnique, bFiltered, bIgnoreEmpty ) { // check that we have a column id if ( typeof iColumn == "undefined" ) return new Array(); // by default we only want unique data if ( typeof bUnique == "undefined" ) bUnique = true; // by default we do want to only look at filtered data if ( typeof bFiltered == "undefined" ) bFiltered = true; // by default we do not wany to include empty values if ( typeof bIgnoreEmpty == "undefined" ) bIgnoreEmpty = true; // list of rows which we're going to loop through var aiRows; // use only filtered rows if (bFiltered == true){ aiRows = oSettings.aiDisplay; } else { // use all rows aiRows = oSettings.aiDisplayMaster; // all row numbers } // set up data array var asResultData = new Array(); var sortType = false; for (var i=0,c=aiRows.length; i<c; i++) { iRow = aiRows[i]; var aData = this.fnGetData(iRow); var sValue = aData[iColumn]; // sets sortType sortType = isNumber(sValue); // ignore empty values? if (bIgnoreEmpty == true && sValue.length == 0){ continue; } else if(bUnique == true && jQuery.inArray(sValue, asResultData) > -1){ // ignore unique values? continue; } else { // else push the value onto the result data array asResultData.push(sValue); } } if(sortType){ return asResultData.sort(numOrdA); }else{ return asResultData.sort(alph); } }})(jQuery); function fnCreateSelect( aData ) { var r='<select><option value=""></option>', i, iLen=aData.length; for ( i=0 ; i<iLen ; i++ ) { r += '<option value="'+aData[i]+'">'+aData[i]+'</option>'; } return r+'</select>'; } function isNumber(n) { return !isNaN(parseFloat(n)) && isFinite(n); } function alph(a, b){ if(a>b) return 1; if(a==b) return 0; if(a<b) return -1; } function numOrdA(a, b){ return a-b; }
Then the code specialized for each table is in its own separate file. The first file is:
$(document).ready(function() { /* Initialise the DataTable */; var oTable = $('#users_table').dataTable({ "bJQueryUI": true, "sPaginationType": "full_numbers", "iDisplayLength": 25, "bAutoWidth": true, "oLanguage": {"sSearch": "Search:"}, "aaSorting": [[3,'desc'],[0,'asc']] }); /* Add a select menu for each TH element in the table footer */ $("tfoot th.makeSelect").each( function(i) { this.innerHTML = fnCreateSelect( oTable.fnGetColumnData(i) ); $('select', this).change( function () { oTable.fnFilter( $(this).val(), i ); } ); } ); } );
And the second file is this:
$(document).ready(function() { /* Initialise the DataTable */; var oTable = $('#boards_table').dataTable({ "bJQueryUI": true, "sPaginationType": "full_numbers", "iDisplayLength": 25, "bAutoWidth": true, "oLanguage": {"sSearch": "Search:"}, "aaSorting": [[3,'desc'],[0,'asc']] }); /* Add a select menu for each TH element in the table footer */ $("tfoot th.makeSelect").each( function(i) { this.innerHTML = fnCreateSelect( oTable.fnGetColumnData(i) ); $('select', this).change( function () { oTable.fnFilter( $(this).val(), i ); } ); } ); } );
As you see I have $("tfoot th.makeSelect") in both files. Having it the same class name causes datatables to crash. If a user assigns class names to table footers the only way this can work is if each table has a different class name. To be specific the error I was getting is "uncaught typeerror: cannot read property 'aiDisplay' of null". As a side note I get the same error even if I keep the code in a single file.