diff --git a/assets/app.js b/assets/app.js
index ea38c1f..ca0f83b 100644
--- a/assets/app.js
+++ b/assets/app.js
@@ -48,9 +48,15 @@ function columnFromTh(th, rowUrl) {
return col;
}
+// Live DataTable instances, keyed by their
element. Used to tear them
+// down before Turbo caches a page - otherwise the back button restores a
+// snapshot that still contains DataTables' injected controls, and re-init
+// stacks a second set of "search" / "entries per page" rows on top.
+const instances = new Map();
+
function initDataTables(root = document) {
root.querySelectorAll('table.datatable').forEach((table) => {
- if (table.dataset.datatable === 'false' || DataTable.isDataTable(table)) {
+ if (table.dataset.datatable === 'false' || instances.has(table) || DataTable.isDataTable(table)) {
return;
}
@@ -76,9 +82,16 @@ function initDataTables(root = document) {
};
}
- new DataTable(table, options);
+ instances.set(table, new DataTable(table, options));
});
}
+function destroyDataTables() {
+ instances.forEach((dt) => dt.destroy());
+ instances.clear();
+}
+
document.addEventListener('DOMContentLoaded', () => initDataTables());
document.addEventListener('turbo:load', () => initDataTables());
+// Restore the plain before Turbo snapshots the page for its cache.
+document.addEventListener('turbo:before-cache', destroyDataTables);