Solved column filter after column reorder
Solved column filter after column reorder
Ironwil616
Posts: 50Questions: 0Answers: 0
My biggest problem lately was getting column-specific drop-down lists to work in my project. I had four main differences from the examples I found: Some columns (chosen at runtime) might be initially hidden, might be initially reordered, or might be reordered dynamically after the table loads, and only a few of the columns would have drop-down list filters. Basically, a user could set up their view to contain a certain number of the available columns, and set them in a default order, and then also drag them around at runtime. So, I am using ColReorder and ColVis plugins as well as datatables. The problem is that any of the above conditions break the column-specific filtering, except that I saw an example where ColVis could hide a column and not break things. I haven't tried it yet.
So, here's the initial setup:
[code]
$('#example').dataTable({
"sDom": 'RC<"clear">lfrtip',
"bStateSave": false,
"bProcessing": true,
"bAutoWidth": false,
"aaSorting": [],
"fnInitComplete": function ()
{
testInit();
}
});
[/code]
'testInit' is a function for setting up the drop-down lists. I was having a null reference issue when trying to set them up within the dataTable constructor. This is the rest of the init code:
[code]
function testInit()
{
var datatable = $('#example').dataTable();
if (datatable)
InitializeDropdownFilters(datatable);
else
setTimeout(function () { testInit() }, 100);
}
function InitializeDropdownFilters(oTable)
{
$(".drop-down-filter").each(function (i)
{
var column = $(this);
var index = column.parent("tr").children().index(column);
this.innerHTML = fnCreateSelect(oTable.fnGetColumnData(index));
$('select', this).change(function ()
{
oTable.fnFilter($(this).val(), index);
});
});
}
[/code]
This code avoided the need to have a drop-down list for every single column (in the example code, if all columns didn't have a drop-down list, indexes were thrown off), and worked just fine - until I drag/dropped a column, and then the indexes for the column and what it searched on were out of sync. In the ColReorder plugin, I found the function '$.fn.dataTableExt.oApi.fnColReorder' and added this to the end of it:
[code]
var datatable = $('#example').dataTable();
ResetDropdownFilters(datatable);
// This is the function referenced above:
function ResetDropdownFilters(oTable)
{
$("thead select").unbind('change');
$(".drop-down-filter").each(function (i)
{
var column = $(this);
var index = column.parent("tr").children().index(column);
$('select', this).change(function ()
{
oTable.fnFilter($(this).val(), index);
});
});
}
[/code]
My drop-down lists are in the thead section, so I disabled and reassigned their change events on every column reassignment. It's essentially the original init code for the filters, except that it doesn't reassign the innerHTML (if you choose a filter option and move a column, assigning the innerHTML will only leave you with the currently selected value as a possible choice).
I have not tested this with an initial column reordering or with columns set to 'bVisible: false' in the initial state, but it's solved the drag/drop problem for me. Doubtless there are many better solutions, but as a non-guru in all things JavaScript, this is what worked for me.
So, here's the initial setup:
[code]
$('#example').dataTable({
"sDom": 'RC<"clear">lfrtip',
"bStateSave": false,
"bProcessing": true,
"bAutoWidth": false,
"aaSorting": [],
"fnInitComplete": function ()
{
testInit();
}
});
[/code]
'testInit' is a function for setting up the drop-down lists. I was having a null reference issue when trying to set them up within the dataTable constructor. This is the rest of the init code:
[code]
function testInit()
{
var datatable = $('#example').dataTable();
if (datatable)
InitializeDropdownFilters(datatable);
else
setTimeout(function () { testInit() }, 100);
}
function InitializeDropdownFilters(oTable)
{
$(".drop-down-filter").each(function (i)
{
var column = $(this);
var index = column.parent("tr").children().index(column);
this.innerHTML = fnCreateSelect(oTable.fnGetColumnData(index));
$('select', this).change(function ()
{
oTable.fnFilter($(this).val(), index);
});
});
}
[/code]
This code avoided the need to have a drop-down list for every single column (in the example code, if all columns didn't have a drop-down list, indexes were thrown off), and worked just fine - until I drag/dropped a column, and then the indexes for the column and what it searched on were out of sync. In the ColReorder plugin, I found the function '$.fn.dataTableExt.oApi.fnColReorder' and added this to the end of it:
[code]
var datatable = $('#example').dataTable();
ResetDropdownFilters(datatable);
// This is the function referenced above:
function ResetDropdownFilters(oTable)
{
$("thead select").unbind('change');
$(".drop-down-filter").each(function (i)
{
var column = $(this);
var index = column.parent("tr").children().index(column);
$('select', this).change(function ()
{
oTable.fnFilter($(this).val(), index);
});
});
}
[/code]
My drop-down lists are in the thead section, so I disabled and reassigned their change events on every column reassignment. It's essentially the original init code for the filters, except that it doesn't reassign the innerHTML (if you choose a filter option and move a column, assigning the innerHTML will only leave you with the currently selected value as a possible choice).
I have not tested this with an initial column reordering or with columns set to 'bVisible: false' in the initial state, but it's solved the drag/drop problem for me. Doubtless there are many better solutions, but as a non-guru in all things JavaScript, this is what worked for me.
This discussion has been closed.
Replies
Regards,
Allan
Update: Resolved one of my issues on this and will post a new thread.