| 1 |
/** |
| 2 |
* This is a "plugin" for the sortable package: |
| 3 |
* https://www.npmjs.com/package/sortable-tablesort |
| 4 |
* https://github.com/tofsjonas/sortable |
| 5 |
* |
| 6 |
* Enhances the accessibility of class="sortable" tables by adding ARIA attributes and keyboard event listeners. |
| 7 |
* @param tables - A list of HTML table elements to enhance. |
| 8 |
*/ |
| 9 |
var enhanceSortableAccessibility = function (tables) { |
| 10 |
/** |
| 11 |
* Generates an aria-label attribute for a table header cell based on its content and current sort direction. |
| 12 |
* @param element - The table header cell to update. |
| 13 |
* @param default_direction - The default sort direction for the table. |
| 14 |
*/ |
| 15 |
function updateAriaLabel(element, default_direction) { |
| 16 |
var _a; |
| 17 |
if (default_direction === void 0) { default_direction = ''; } |
| 18 |
// Generate aria-label based on header content |
| 19 |
var header_text = element.textContent || 'element'; |
| 20 |
var current_direction = (_a = element.getAttribute('aria-sort')) !== null && _a !== void 0 ? _a : ''; |
| 21 |
var new_direction = 'descending'; |
| 22 |
if (current_direction === 'descending' || (default_direction && current_direction !== 'ascending')) { |
| 23 |
new_direction = 'ascending'; |
| 24 |
} |
| 25 |
var aria_label = "Click to sort table by ".concat(header_text, " in ").concat(new_direction, " order"); |
| 26 |
element.setAttribute('aria-label', aria_label); |
| 27 |
// element.setAttribute('title', aria_label) REMEMBER TO COMMENT OUT WHEN NOT TESTING!! |
| 28 |
} |
| 29 |
/** |
| 30 |
* Handles keyboard events on table header cells and triggers a click event when the Enter key is pressed. |
| 31 |
* @param event - The keyboard event to handle. |
| 32 |
*/ |
| 33 |
function handleKeyDown(event) { |
| 34 |
if (event.key === 'Enter') { |
| 35 |
var element = event.target; |
| 36 |
element.click(); |
| 37 |
} |
| 38 |
} |
| 39 |
// Iterate over each table in the input list |
| 40 |
tables.forEach(function (table) { |
| 41 |
var default_direction = table.classList.contains('asc') ? 'ascending' : ''; |
| 42 |
var headers = table.querySelectorAll('th'); |
| 43 |
// Iterate over each header cell in the table |
| 44 |
headers.forEach(function (header) { |
| 45 |
var element = header; |
| 46 |
// Skip if the header cell already has a tabindex attribute |
| 47 |
if (element.hasAttribute('tabindex')) |
| 48 |
return; |
| 49 |
var update = function () { |
| 50 |
updateAriaLabel(element, default_direction); |
| 51 |
}; |
| 52 |
// Add tabindex attribute and generate initial aria-label attribute |
| 53 |
element.setAttribute('tabindex', '0'); |
| 54 |
update(); |
| 55 |
// Attach click event listener to update aria-label attribute |
| 56 |
element.addEventListener('click', function () { |
| 57 |
// Add a delay to allow the new sort order to be applied |
| 58 |
setTimeout(update, 50); |
| 59 |
}); |
| 60 |
// Attach focus event listener to update aria-label attribute |
| 61 |
element.addEventListener('focus', update); |
| 62 |
// Attach keyboard event listener to trigger click event |
| 63 |
element.addEventListener('keydown', handleKeyDown); |
| 64 |
}); |
| 65 |
}); |
| 66 |
}; |
| 67 |
|
| 68 |
// Attach function to DOMContentLoaded event to execute when page is loaded |
| 69 |
document.addEventListener('DOMContentLoaded', function () { |
| 70 |
enhanceSortableAccessibility(document.querySelectorAll('.sortable')); |
| 71 |
}); |
| 72 |
|