The neighborhood tool library lists available resources out of order. Add a sort button to the Resource header, then make it reorder the three existing rows alphabetically in either direction. The preceding workshop demo shows the full pattern.
Here is a separate worked example: a book table with its own IDs. The th describes the sort; the button activates it. The rows are moved rather than rebuilt:
<th id="book-heading" scope="col" aria-sort="none"><button id="sort-books" type="button">Sort books</button></th>
<tbody id="books"><tr><td>Zines</td></tr><tr><td>Atlases</td></tr></tbody>
const books = document.querySelector("#books");
const heading = document.querySelector("#book-heading");
document.querySelector("#sort-books").addEventListener("click", () => {
const next = heading.getAttribute("aria-sort") === "ascending" ? "descending" : "ascending";
const rows = Array.from(books.rows);
rows.sort((a, b) => next === "ascending"
? a.cells[0].textContent.localeCompare(b.cells[0].textContent)
: b.cells[0].textContent.localeCompare(a.cells[0].textContent));
books.replaceChildren(...rows);
heading.setAttribute("aria-sort", next);
});
Array.from makes an array of the row elements; localeCompare compares words; replaceChildren(...rows) reattaches those very elements. The aria-sort value begins at none, then alternates ascending and descending. Use a real button so Enter and Space already work. For your resource table, retain the category cells with their original rows.
type="button" sort control and initialize that header with aria-sort="none".aria-sort="ascending".aria-sort="descending"; keep alternating on subsequent clicks.Try keyboard activation, then click again. Watch both columns: a category must stay with its resource, while the header's announced direction follows the visible order.
You can now filter, reveal, add, remove, and reorder existing page content without losing accessible controls or treating visitor text as HTML.
Copy rows into an array with Array.from(tbody.rows), then compare first-cell text.
Keep aria-sort on the column header; replaceChildren moves the original rows.