adinfinit / jamvote

Application for organising Game Jams
1 stars 0 forks source link

Sorting in the Results table #68

Open jee7 opened 1 year ago

jee7 commented 1 year ago

In the result tables, it is unclear how the rows are currently sorted. Make the columns clickable and rows sortable by clicking on the columns. image

Use case: 1) User lands on this page. The tables are by default sorted by Ove. There has to be some small arrow next to Ove or other visual indicator showing that fact. 2) User clicks on Bon: The rows of that table are then sorted by the bonus points. The sorting indicator is shown now next to Bon and not for Ove anymore. 3) User clicks on Bon again: The rows are now sorted by the bonus points, but in reverse order. Repeated clicking on the column heading reverses the sorting (the visual indicator also has to show that). The first click (also after another column has been used) always sorts in descending order.

Sorting should always be based on just one column.

Note. The games have position indicators (#‎1, #‎2, etc). These should also be sorted.

egonelbre commented 1 year ago

For the sorting code, it should be sufficient to add a script along the lines of:

document.addEventListener("DOMContentLoaded", function() {
    "use strict";

    // Some browsers don't support this function.
    if(!document.replaceChildren) return;

    let tables = document.querySelectorAll("table.sortable");
    for(let i = 0; i < tables.length; i++) {
        addSortingToTable(tables[i]);
    }

    function addSortingToTable(table) {
        let header = table.querySelector("thead > tr");
        if(!header) return;

        let body = table.querySelector("tbody");
        if(!body) return;

        for(let i = 0; i < header.childElementCount; i++) {
            let columnIndex = i;
            let columnTitle = header.children[i];
            let columnDirection = false;

            columnTitle.style.cursor = "pointer";

            let compareFn = function(a, b) {
                return a.localeCompare(b);
            };

            columnTitle.addEventListener("click", function(ev) {
                columnDirection = !columnDirection;

                let rows = Array.from(body.rows);
                let sorted = rows.sort(function(arow, brow) {
                    var a = arow.children[columnIndex];
                    var b = brow.children[columnIndex];
                    var r = compareFn(a.innerText, b.innerText)
                    return columnDirection ? r : -r;
                })
                body.replaceChildren(...sorted);
            });
        }
    }
});

But localeCompare should be natural sort -- not sure whether it make a significant difference.