--- /dev/null
+// vim: smarttab tabstop=8 shiftwidth=2 expandtab
+// to change columne header colors
+//
+let columns=[];
+let currentSearch="";
+
+const searchInput = document.getElementById("searchInput");
+const limitSelect = document.getElementById("limitSelect");
+
+// Header click pour multi-colonnes
+document.querySelectorAll(".filter-col").forEach(th=>{
+ th.addEventListener("click",()=>{
+ const col = th.dataset.col;
+ if (columns.includes(col)){
+ columns = columns.filter(c=>c!==col);
+ th.classList.remove("active");
+ }
+ else {
+ columns.push(col);
+ th.classList.add("active");
+ }
+ refresh();
+ });
+});
+
+// Recherche et changement de limit
+searchInput.addEventListener("input",refresh);
+limitSelect.addEventListener("change",refresh);
+
+// AJAX vers le même fichier
+function refresh(){
+currentSearch = searchInput.value.trim();
+const form = new FormData();
+form.append("search", currentSearch);
+form.append("limit", limitSelect.value);
+
+const activeColumns = columns.length ? columns : ["remoteip","reverse","creation"];
+activeColumns.forEach(c=>form.append("columns[]",c));
+
+fetch("", {method:"POST", body:form})
+ .then(r=>r.json())
+ .then(json=>renderTable(json.rows,json.search));
+}
+
+// Remplissage tableau avec surbrillance
+function renderTable(rows,search){
+console.log("AJAX: nombre de lignes reçues =", rows.length);
+const tbody=document.querySelector("#dataTable tbody");
+tbody.innerHTML="";
+const re = search ? new RegExp(search,"gi") : null;
+for(const row of rows){
+ const tr=document.createElement("tr");
+ const cells = ["remoteip","reverse","creation"].map(c=>{
+ // NULL -> "NULL"
+ let val = row[c] === null ? "NULL" : row[c];
+ if(re) val = val.replace(re,m=>`<span class="highlight">${m}</span>`);
+ return `<td>${val}</td>`;
+ });
+ tr.innerHTML=cells.join("");
+ tbody.appendChild(tr);
+ }
+}
+
+// Load initial
+refresh();