An accessible way to listen to the newly sorted headers of a horrible data table/list structure like so:
<div>
<dl>
<ul>
<li>
<a></a>
</li>
</ul>
</dl>
</div>
See the example.html
$(document).ready(function () {
$("div.listitemsort a").on("click", function () {
var $listElement = $(this).parent(),
$headerList = $listElement.parent();
if ($headerList.data("sortedColumn")) {
// new listitem selected, remove sort on existing item
if ($headerList.data("sortedColumn") !== $listElement.attr("id")) {
removeSort($headerList);
}
} else {
// ensure that original label doesn't change
$headerList.data({
"originalLabel": $listElement.attr("aria-label")
});
}
setSort($headerList, $listElement);
});
// WONTFIX: this means it'll fire every time we focus away, even if it's not sorted
// but due to old enterprise system, it is less expensive to throw this into the relevant lifecycle hook
$("div.listitemsort a").on("focusout", function () {
// if we have sorted item, remove the "currently sorted descending" if it's there
var $listElement = $(this).parent(),
$headerList = $listElement.parent();
if ($headerList.data("sortedColumn") == $listElement.attr("id")) {
$listElement.attr("aria-label", $headerList.data("originalLabel"))
}
});
function setSort($headerList, $listElement) {
// assumption that only one column can be sorted at a time
switch ($headerList.data("sort-direction")) {
case "descending":
// set ascending
setSortAttributes($headerList, $listElement, "ascending");
break;
default:
// undefined, must be first time clicked or is not descending/ascending algorithm
// fall-through
case "ascending":
// set descending
setSortAttributes($headerList, $listElement, "descending");
break;
}
};
function setSortAttributes($headerList, $listElement, direction) {
$headerList.data({
"sort-direction": direction,
"sortedColumn": $listElement.attr("id")
});
$listElement.attr({
"aria-sort": direction,
"sort-direction": direction,
"aria-label": $headerList.data("originalLabel") + " - " + "currently sorted " + direction
});
}
function removeSort($headerList) {
$("#" + $headerList.data("sortedColumn")).attr({
"aria-sort": "none",
"sort-direction": "default",
"aria-label": $headerList.data("originalLabel")
});
}
});