Pagination don't work when i remove and add rows
Pagination don't work when i remove and add rows

I have a table that i can remove and add rows, everything is working except when i´m in a page of the table and try remove or add any row, the table only recognizes the current page and the others disappear.
This are the actions of the table:
// :: Begin Popup Actions ::
protected async Task AllTranslationPopup(ModuleTypesResponse moduleType)
{
SelectedI18NCodes = UnselectedI18NCodes;
SelectedModule = moduleType;
var resultGetAllModule = await ModuleService.GetAllModules(new ModulesFilters { ModuleTypeId = moduleType.Id });
if (resultGetAllModule.Data is { Count: > 0 })
{
ModuleResponseList = resultGetAllModule.Data;
var codes = resultGetAllModule.Data.Select(x => x.CodeI18N).ToList();
SelectedI18NCodes = UnselectedI18NCodes.Where(x => !codes.Contains(x.CodeI18N?.Code)).ToList();
}
else
{
ModuleResponseList = new List<ModuleResponse>();
}
StateHasChanged();
await JS.InvokeVoidAsync("KTTablesTranslationListPopUp.init");
await JS.InvokeVoidAsync("KTTablesModuleListPopUp.init");
await JS.InvokeVoidAsync("eval", "$('#allTranslationPopup').modal('show')");
}
protected async Task HandleAddTranslationPopUp(CodeI18NTranslationSummaryResponse translationSummaryResponse)
{
if (SelectedModule != null && ModuleResponseList != null && ModuleResponseList.All(x => x.CodeI18N != translationSummaryResponse.CodeI18N?.Code))
{
try
{
var moduleRequest = new ModuleRequest { ModuleTypeId = SelectedModule.Id, CodeI18NId = translationSummaryResponse.CodeI18N?.Id.ToString() };
var result = await ModuleService.CreateModules(moduleRequest);
if (result != null)
{
ModuleResponseList.Add(new ModuleResponse
{
Id = result.Id,
CodeI18N = translationSummaryResponse.CodeI18N!.Code,
CodeI18NId = translationSummaryResponse.CodeI18N.Id.ToString(),
Name = translationSummaryResponse.CurrentLanguageShortName
});
SelectedI18NCodes.Remove(translationSummaryResponse);
StateHasChanged();
await JS.InvokeVoidAsync("KTTablesTranslationListPopUp.reloadTable");
var successMessage = ModalHelper.LoadModalMessages("Submit");
await JS.InvokeVoidAsync("KTSubmitEvent2.init", "allTranslationPopup", successMessage, true);
}
}
catch (Exception ex)
{
// Handle error and show message
var errorMessage = ModalHelper.LoadModalMessages("Submit");
await JS.InvokeVoidAsync("KTSubmitEvent2.init", "allTranslationPopup", errorMessage, false);
}
StateHasChanged();
}
}
protected async Task HandleDeleteTranslationPopUp(ModuleResponse moduleResponse)
{
ModalMessages = ModalHelper.LoadModalMessages("Delete");
var result = await JS.InvokeAsync<bool>("KTDeleteEvent.init", ModalMessages);
if (result)
{
var deleteResult = await ModuleService.DeleteModules(moduleResponse.Id)!;
if (deleteResult)
{
if (SelectedI18NCodes.All(x => x.CodeI18N?.Code != moduleResponse.CodeI18N))
{
SelectedI18NCodes.Add(new CodeI18NTranslationSummaryResponse
{
CodeI18N = new CodeI18NResponse
{
Id = Guid.Parse(moduleResponse.CodeI18NId!),
Code = moduleResponse.CodeI18N
},
CurrentLanguageShortName = moduleResponse.Name
});
}
ModuleResponseList?.Remove(moduleResponse);
StateHasChanged();
await JS.InvokeVoidAsync("KTTablesTranslationListPopUp.reloadTable");
var successMessages = ModalHelper.LoadModalMessages("DeleteSuccess");
await JS.InvokeVoidAsync("KTDeleteEvent.init", successMessages, ModalMessages, true);
}
StateHasChanged();
}
}
// :: End Popup Actions ::
And this is my script:
"use strict";
// Class definition
"use strict";
// Class definition
var KTTablesTranslationListPopUp = function () {
// Shared variables
var table;
var datatable;
// Private functions
var initDatatable = function () {
// Set date data order
const tableRows = table.querySelectorAll('tbody tr');
tableRows.forEach(row => {
const dateRow = row.querySelectorAll('td');
});
// Init datatable --- more info on datatables: https://datatables.net/manual/
datatable = $(table).DataTable({
"info": true,
'order': [],
'pageLength': 25,
"columnDefs": [{
"targets": 'no-sort',
"orderable": false,
}]
});
}
// Search Datatable --- official docs reference: https://datatables.net/reference/api/search()
var handleSearchDatatable = () => {
const filterSearch = document.querySelector('[data-kt-filter="searchTranslationPopUp"]');
filterSearch.addEventListener('keyup', function (e) {
datatable.search(e.target.value).draw();
});
}
var reloadTable = function () {
if (datatable) {
datatable.clear(); // Clear existing data
datatable.rows.add($(table).find('tbody tr')).draw(); // Re-add rows and redraw
}
};
// Public methods
return {
init: function () {
table = document.querySelector('#kt_datatable1');
if (!table) {
return; // Se a tabela não existir, sai da função
}
// Verifica se o DataTable já existe
if ($.fn.dataTable.isDataTable('#kt_datatable1')) {
// Destrói o DataTable existente
$(table).DataTable().destroy();
}
// Reconfigura o DataTable
initDatatable();
handleSearchDatatable();
},
reloadTable: reloadTable,
};
}();
// Webpack support
if (typeof module !== 'undefined') {
window.KTTablesTranslationListPopUp = module.exports = KTTablesTranslationListPopUp;
}
Probably my problem is with this function:
var reloadTable = function () {
if (datatable) {
datatable.clear(); // Clear existing data
datatable.rows.add($(table).find('tbody tr')).draw(); // Re-add rows and redraw
}
};
but without this the table don't update the counter of rows when i add or remove rows.
Anyone can help?
Thanks!!
This question has accepted answers - jump to:
Answers
The only rows available for
$(table).find('tbody tr'))
to find are the rows displayed on the page. Datatables removes the rows from other pages. So yes on;y the rows on the page will then be in the Datatable after therows.add()
. Userows().data()
orrows().nodes()
to get all the rows.I'm not sure what the
reloadTable
function is needed for. It looks like the idea is to clear the Datatable then re-add the same rows to the Datatable. I'm not clear why you are doing this. Please explain what you are trying to accomplish with this function. I'm thinking that you don't really need it. See the next paragraph.How are you adding and removing rows? Are you using
row().remove()
androw.add()
for this? If not then Datatables won't know about the changes. Is this why you are calling thereloadTable
function in an attempt to inform Datatables of the changes?Kevin
Yes, i'm calling the reloadTable to inform the Datatables of the changes when i add and remove rows. There is other way to do it?
"The only rows available for $(table).find('tbody tr')) to find are the rows displayed on the page." I suspected this was the problem but I can't solve it.
As I asked before how are you doing this?
You should use the Datatables API s
row.add()
,rows.add()
,row().remove()
androws().remove()
to add and remove the rows from the client side. Possibly you need to do this in-conjunction with the code you might have telling the server which rows to add and delete.If you still need help please provide details of your row add and delete process and requirements.
Kevin
I added this two funtions in .js file to add and remove rows from the datatable and deleted the reloadTable function, everything works fine except the click in the button added, the function in .razor file is not called
Can returns a string and thus results in a new node - one which won't have a click event.
With DataTables 2 you can simply give it the DOM node - so
button
rather thanbutton.outerHTML
. Example here.Allan
Is there any way to rebuild the datatable without row.add() and row.remove() or without reload the page?
For example, when i add a row, the datatable is built completely new.
You can use
clear()
to clear the table followed byrow.add()
orrows.add()
.Looks like you are using DOM sourced table for the Datatable. You can use
destroy()
then empty and repopulate the HTML table followed by reinitializing the Datatable.If this doesn't help then please provide more specific details of how you want this to work.
Kevin
Thanks, i resolved my problem. The only thing that i need now is to apply classes to the initial four tr 's, here:
You can return the
row().node()
and apply the class as shown in therow.add()
examples.Kevin
Sorry, i said tr but i meant td's. I want to add classes to the td's
If you want to add the same class name to all cells in a column then use
columns.className
.Otherwise you can still use the
row().node()
returned from examples to apply classes to the specific cell in thetr
that is returned. For example:This should apply those attributes to the second cell in that row.
Kevin
Thanks, this works for me.
Now i have another question, how i can add the new row on top of the table?
The way i was doing in the beggining isn't the correct way:
$(newRow).prependTo(datatable.table().body());
Do you mean to the table header? You'd need to modify the header before the DataTable is initialised. A new row can't be added to the header after initialisation - there is no API for that in DataTables.
Allan
No, i mean the new row became the first in the datatable instead of being added at the end of the table. The table header is always the same.
The order of the rows in the table body are defined by the ordering that is applied to the table. If you need specific data to be at the top of the table, then have a look at this blog post which describes one method for how that can be done.
Allan