function sortableTable(initField, initDir) { return { sortField: initField || "score", sortDir: initDir || "desc", sort(field) { if (this.sortField === field) { this.sortDir = this.sortDir === "asc" ? "desc" : "asc"; } else { this.sortField = field; this.sortDir = "desc"; } this.reorder(); }, reorder() { const tbody = this.$refs.tbody; if (!tbody) return; const rows = Array.from(tbody.querySelectorAll("tr")); const field = this.sortField; const dir = this.sortDir === "asc" ? 1 : -1; rows.sort((a, b) => { const aVal = parseFloat(a.dataset[field]) || 0; const bVal = parseFloat(b.dataset[field]) || 0; if (aVal !== bVal) return (aVal - bVal) * dir; // Tiebreak: alphabetical by player name const aName = (a.dataset.name || "").toLowerCase(); const bName = (b.dataset.name || "").toLowerCase(); return aName < bName ? -1 : aName > bName ? 1 : 0; }); rows.forEach((row) => tbody.appendChild(row)); }, }; }