Built in Length menu change event causing img click events to duplicate

Built in Length menu change event causing img click events to duplicate

viper1884viper1884 Posts: 5Questions: 0Answers: 0
edited February 2014 in General
My datatable uses hidden detail rows to display/hide information, i have added an expand/collapse all image to the table header (th) row to open or close all detail rows.

Everything works fine except for one bug. When the length menu, https://datatables.net/release-datatables/examples/advanced_init/length_menu.html is changed the onClick event for the expand/collapse image is duplicated.

When the length menu is changed once, the onChange is fired twice when the image is clicked, when its changed again it fires three times and so forth.

Anyone know whats causing this and how to fix this?

My Code
[code]"fnDrawCallback": function (oSettings) {

var nCloneTh = document.createElement('th');
var nCloneTd = document.createElement('td');
nCloneTh.innerHTML = ' ';

nCloneTd.innerHTML = "";
nCloneTd.className = "center";
if (hasRan == false) {
$('#DataTable thead tr').each(function () {
this.insertBefore(nCloneTh, this.childNodes[0]);

});
}
$('#DataTable tbody tr').each(function () {
this.insertBefore(nCloneTd.cloneNode(true), this.childNodes[0]);
});
//Header expand/collapse event
$('#DataTable th img').on('click', function () {
var nodes = new Array();
nodes = oTable.fnGetNodes();
if (rowClosed == false) {
rowClosed = true;
for (var i = 0; i <= nodes.length - 1; i++) {


var nTr = nodes[i];
if (nodes[i].nextSibling != null) {
var a = nodes[i].nextSibling.cells[0];
if (a.className == "details") {

nTr.cells[0].children[0].src = '@Html.Raw(Model.ExpandRow)';
oTable.fnClose(nTr);

}
}

}
this.src = '@Html.Raw(Model.ExpandAllRows)';
}
else {
rowClosed = false;
for (var i = 0; i <= nodes.length - 1; i++) {


var nTr = nodes[i];
if (nodes[i].nextSibling != "td.details") {

nTr.cells[0].children[0].src = '@Html.Raw(Model.CollapseRow)';

oTable.fnOpen(nTr, fnFormatDetails(oTable, nTr), 'details');
$(".details").attr("colspan", 9);

}

}
this.src = '@Html.Raw(Model.CollapseAllRows)';
}

});


$('#DataTable td img').on('click', function () {
var nTr = $(this).parents('tr')[0];
if (oTable.fnIsOpen(nTr)) {
/* This row is already open - close it */

this.src = '@Html.Raw(Model.ExpandRow)';
oTable.fnClose(nTr);
}
else {
/* Open this row */

this.src = '@Html.Raw(Model.CollapseRow)';
oTable.fnOpen(nTr, fnFormatDetails(oTable, nTr), 'details');
$(".details").attr("colspan", 9);
}
});
hasRan = true;
}[/code]

Replies

  • allanallan Posts: 63,692Questions: 1Answers: 10,500 Site admin
    I've very much suggest you don't add the events in fnDrawCallback, but rather use a single delegated event in your main function:

    [code]
    $('#DataTable').on('click', 'tbody th img', function () {
    [/code]

    See the jQuery documentation on delegated events for more information.

    Allan
This discussion has been closed.