Add client-side table sorting to all tables

Clicking any column header sorts the table rows. Supports text and
numeric sorting with ascending/descending toggle and arrow indicators.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shuki
2026-03-04 15:48:51 +02:00
parent 46b5644074
commit 3a74e4fd7a

View File

@@ -719,7 +719,39 @@ sub _scope_to_container {
}
sub page_footer {
return "</div>\n";
return qq{<script>
(function(){
document.querySelectorAll('table.table').forEach(function(table){
var headers = table.querySelectorAll('thead th');
headers.forEach(function(th, colIdx){
if(!th.textContent.trim()) return;
th.style.cursor='pointer';
th.style.userSelect='none';
th.dataset.sortDir='';
th.addEventListener('click',function(){
var tbody=table.querySelector('tbody');
if(!tbody) return;
var rows=Array.from(tbody.querySelectorAll('tr'));
headers.forEach(function(h){if(h!==th){h.dataset.sortDir='';h.textContent=h.textContent.replace(/ [\\u25B2\\u25BC]\$/,'')}});
var dir=th.dataset.sortDir==='asc'?'desc':'asc';
th.dataset.sortDir=dir;
th.textContent=th.textContent.replace(/ [\\u25B2\\u25BC]\$/,'')+(dir==='asc'?' \\u25B2':' \\u25BC');
rows.sort(function(a,b){
var ca=a.cells[colIdx],cb=b.cells[colIdx];
if(!ca||!cb) return 0;
var va=ca.textContent.trim(),vb=cb.textContent.trim();
var na=parseFloat(va.replace(/[^0-9.\\-]/g,'')),nb=parseFloat(vb.replace(/[^0-9.\\-]/g,''));
if(!isNaN(na)&&!isNaN(nb)&&va.match(/^[0-9.,\\-\\s]+[A-Za-z\\s]*\$/)){
return dir==='asc'?na-nb:nb-na;
}
return dir==='asc'?va.localeCompare(vb):vb.localeCompare(va);
});
rows.forEach(function(r){tbody.appendChild(r)});
});
});
});
})();
</script>\n</div>\n};
}
sub render_errors {