fnDeleteRow Seems to Not Delete on Client?
fnDeleteRow Seems to Not Delete on Client?
mattygabe
Posts: 1Questions: 0Answers: 0
So, I think I've found an issue, but I may be misunderstanding the documentation of DataTables and its features. Let me outline the high-level view of what I'm doing with my data table:
I have a table of objects that we'll say is my class People. People are soft-deleted, meaning that when you delete one it's still persisted in the database, its just marked as deleted and hidden from the client side altogether. To go along with the soft delete, I wanted to make a UI that does a non-obtrusive soft delete - you click delete, it "deletes" the row from the datatable (and makes a behind-the-scenes XHR request to the server to flip that flag), and replaces it with a message that says "Click here to undo" (also makes an XHR request to flip that flag back). So essentially I'm playing that game where I need to make the UI on the client side match the state of the data on the server side.
The issue here is that I can only get my DataTable to correctly match that state by using the fnAjaxReload (my table is generated by sAjaxSource). If I don't, and just perform redraws, I come across a few issues (will show code below):
1. When I do a fnDraw() call after calling fnDeleteRow(node, null, false), the row is removed from that page. Assuming I delete a row from a page of 5 rows - I see 4 rows. If I page forward, and then back to that same page - the row I deleted is there again!
2. The counts are always wonky - this one I have never been able to fix. If I have 14 rows, and fnDeleteRow one of them, it remains at 14.
3. By having to perform the complete AJAX reload, I create the possibility that if you delete multiple people on a page, you can only undo one of them (the "undo" link is removed by the reload). Hence why I'd prefer
Here's the code I have, any advice would be helpful. Thanks!
Table initialization:
[code]
$('#people').dataTable({
bProcessing: true,
sAjaxSource: myApp.AjaxUrl,
bStateSave: true,
bLengthChange: false,
iDisplayLength: 5,
sScrollX: "100%",
sScrollXInner: "100%",
aoColumns: [
{ sTitle: "Name" },
{ sTitle: "Email" },
{ sTitle: "PhoneNumber" },
{ sTitle: "Address1" },
{ sTitle: "Address2" },
{ sTitle: "City" },
{ sTitle: "State" },
{ sTitle: "Zip" },
{ sTitle: "Country" },
{ sTitle: "Url" },
{ sTitle: "Edit", sClass: "center edit" },
{ sTitle: "Delete", sClass: "center delete" },
{ sTitle: "Id", sClass: "id" }
],
aoColumnDefs: [
{ bSortable: true, aTargets: ['_all'] },
{ bSearchable: true, aTargets: [0, 1] },
{ bVisible: false, aTargets: [-1] },
{ sWidth: "90px", aTargets: [5, 6, 7, 8] },
{ sWidth: "120px", aTargets: [0, 2, 3, 4] },
{ sWidth: "210px", aTargets: [1, 9] },
{ sWidth: "60px", aTargets: [-2, -3] }
]
});
[/code]
Code that is run when you click "Delete":
[code]
//AJAX call made here, success handler body, you can assume $tableRow is a jQuery selector of the TR dataTable element:
var personName = $tableRow.children('td:first').text(),
$newRow = $(''),
$newCell = $('').addClass('undoDelete')
.data("item-id", itemId)
.attr('colspan', $tableRow.children('td').length)
.text(personName + ' has been deleted - click to restore')
.appendTo($newRow),
$dataTable = $('#people').dataTable();
$dataTable.fnDeleteRow($tableRow.get(), function() {
$dataTable.fnDraw(true);
$tableRow.replaceWith($newRow);
}, true);
[/code]
Code that's run when you click the "click to restore" row, is also in AJAX success handler:
[code]
var $dataTable = $('#people').dataTable();
$undoRow.remove();
$dataTable.fnAddData([
data.People.Name,
data.people.Email,
data.People.PhoneNumber,
data.People.Address1,
data.People.Address2,
data.People.City,
data.People.State,
data.People.Zip,
data.People.Country,
data.People.Url,
"Edit",
"Delete",
data.People.Id
], false);
//Would prefer to just redraw table client side, not performing another ajax reload of table data:
$dataTable.fnReloadAjax();
[/code]
I have a table of objects that we'll say is my class People. People are soft-deleted, meaning that when you delete one it's still persisted in the database, its just marked as deleted and hidden from the client side altogether. To go along with the soft delete, I wanted to make a UI that does a non-obtrusive soft delete - you click delete, it "deletes" the row from the datatable (and makes a behind-the-scenes XHR request to the server to flip that flag), and replaces it with a message that says "Click here to undo" (also makes an XHR request to flip that flag back). So essentially I'm playing that game where I need to make the UI on the client side match the state of the data on the server side.
The issue here is that I can only get my DataTable to correctly match that state by using the fnAjaxReload (my table is generated by sAjaxSource). If I don't, and just perform redraws, I come across a few issues (will show code below):
1. When I do a fnDraw() call after calling fnDeleteRow(node, null, false), the row is removed from that page. Assuming I delete a row from a page of 5 rows - I see 4 rows. If I page forward, and then back to that same page - the row I deleted is there again!
2. The counts are always wonky - this one I have never been able to fix. If I have 14 rows, and fnDeleteRow one of them, it remains at 14.
3. By having to perform the complete AJAX reload, I create the possibility that if you delete multiple people on a page, you can only undo one of them (the "undo" link is removed by the reload). Hence why I'd prefer
Here's the code I have, any advice would be helpful. Thanks!
Table initialization:
[code]
$('#people').dataTable({
bProcessing: true,
sAjaxSource: myApp.AjaxUrl,
bStateSave: true,
bLengthChange: false,
iDisplayLength: 5,
sScrollX: "100%",
sScrollXInner: "100%",
aoColumns: [
{ sTitle: "Name" },
{ sTitle: "Email" },
{ sTitle: "PhoneNumber" },
{ sTitle: "Address1" },
{ sTitle: "Address2" },
{ sTitle: "City" },
{ sTitle: "State" },
{ sTitle: "Zip" },
{ sTitle: "Country" },
{ sTitle: "Url" },
{ sTitle: "Edit", sClass: "center edit" },
{ sTitle: "Delete", sClass: "center delete" },
{ sTitle: "Id", sClass: "id" }
],
aoColumnDefs: [
{ bSortable: true, aTargets: ['_all'] },
{ bSearchable: true, aTargets: [0, 1] },
{ bVisible: false, aTargets: [-1] },
{ sWidth: "90px", aTargets: [5, 6, 7, 8] },
{ sWidth: "120px", aTargets: [0, 2, 3, 4] },
{ sWidth: "210px", aTargets: [1, 9] },
{ sWidth: "60px", aTargets: [-2, -3] }
]
});
[/code]
Code that is run when you click "Delete":
[code]
//AJAX call made here, success handler body, you can assume $tableRow is a jQuery selector of the TR dataTable element:
var personName = $tableRow.children('td:first').text(),
$newRow = $(''),
$newCell = $('').addClass('undoDelete')
.data("item-id", itemId)
.attr('colspan', $tableRow.children('td').length)
.text(personName + ' has been deleted - click to restore')
.appendTo($newRow),
$dataTable = $('#people').dataTable();
$dataTable.fnDeleteRow($tableRow.get(), function() {
$dataTable.fnDraw(true);
$tableRow.replaceWith($newRow);
}, true);
[/code]
Code that's run when you click the "click to restore" row, is also in AJAX success handler:
[code]
var $dataTable = $('#people').dataTable();
$undoRow.remove();
$dataTable.fnAddData([
data.People.Name,
data.people.Email,
data.People.PhoneNumber,
data.People.Address1,
data.People.Address2,
data.People.City,
data.People.State,
data.People.Zip,
data.People.Country,
data.People.Url,
"Edit",
"Delete",
data.People.Id
], false);
//Would prefer to just redraw table client side, not performing another ajax reload of table data:
$dataTable.fnReloadAjax();
[/code]
This discussion has been closed.