Button click fired multiple times when performing filtering
Button click fired multiple times when performing filtering
pponzano
Posts: 3Questions: 2Answers: 0
Hello,
I've a datatable with 2 button as first row. The data are retrieved via ajax and there're footer input to filter on the column.
When I perform a filter search, then click the button to edit, it's fired a lot of times. I think that's due to the fact that the rowCallback
assigns more then one handler to the button while performing a search (since rows are recreated).
How can I avoid this?
Here's my dtOptions and afterViewInitalized
ngOnInit(): void {
setTimeout(() => {
const self = this;
this.dtOptions = {
pagingType: 'full_numbers',
searching: true,
dom: 'tlp',
pageLength: 10,
processing: true,
serverSide: false,
destroy: true,
columnDefs: [{
targets: [0, 1],
orderable: false,
},
],
columns: [
{ defaultContent: "<div style='width:200px'><button class='editButton btn btn-sm btn-light-primary btn-hover-rise me-5'>Edit</button><button class='deleteButton btn btn-sm btn-light-danger btn-hover-rise me-5'>Delete</button></div>", title: "Action", width: "200px" },
{ data: 'id', title: 'ID', },
{ data: 'name', title: 'Name', },
{ data: 'edmo', title: 'EDMO', },
{ data: 'countryCode', title: 'Country Code', },
{ data: 'countryName', title: 'Country Name', },
{ data: 'webSite', title: 'Web Site', },
{ data: 'logo', title: 'Logo', },
{ data: 'creationDate', title: 'Creation Date' },
],
order: [3, 'asc'],
ajax: (dataTableParameters: any, callback: any) => {
self.getData(callback);
},
rowCallback: (row: Node, data: any[] | Object, index: number) => {
var btn1 = $('[class*=editButton]', row);
btn1.on('click', () => {
alert('button clicked');
this.itemUpdateOpenModal(data);
});
var btn2 = $('[class*=deleteButton]', row);
btn2.on('click', () => {
this.deleteItem(data);
});
}
}
}, 200);
}
public ngAfterViewInit(): void {
alert('called');
setTimeout(() => {
// race condition fails unit tests if dtOptions isn't sent with dtTrigger
this.dtTrigger.next(this.dtOptions);
this.datatableElement.dtInstance.then((dtInstance: DataTables.Api) => {
var dataTable = $("#mainTable").DataTable();
dtInstance.columns().every(function (colIdx) {
const that = this;
$('input', this.footer()).on('keyup change', function () {
if (that.search() !== this['value']) {
switch (this['name']) {
case "search-name":
dataTable.column(2).search(this['value']).draw();
break;
case "search-edmo":
dataTable.column(3).search(this['value']).draw();
break;
case "search-countryCode":
dataTable.column(4).search(this['value']).draw();
break;
case "search-countryName":
dataTable.column(5).search(this['value']).draw();
break;
}
}
});
});
});
}, 200);
}
Answers
rowCallback
is called for each row. You are using a classname as the selector to assign the button click event. IfrowCallback
runs for 10 rows you could end up with 10 click event handlers assigned to one button. Instead use jQuery delegated evnets as shown in this example.Kevin