Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Sortable table example #2046

Merged
merged 57 commits into from
Oct 31, 2021
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
4372458
updated reference table
jongund Sep 21, 2021
19b33e1
added initial implementation of a sortable table
jongund Sep 27, 2021
14daa3f
fixed linting bug
jongund Sep 27, 2021
0e3f3c3
fixed linting bug
jongund Sep 27, 2021
068857f
fixed linting bug
jongund Sep 27, 2021
effd1ce
editorial changes
jongund Sep 27, 2021
c1051fc
updated unsorted column icon
jongund Sep 27, 2021
4ea5a98
updated documentation
jongund Sep 27, 2021
3714af6
updated documentation
jongund Sep 27, 2021
f9d7e88
updated documentation
jongund Sep 27, 2021
de25a8c
update example to iser aria-describedby, instead of aria-label for th…
jongund Sep 28, 2021
b05cace
Merge branch 'main' of github.com:w3c/aria-practices
jongund Sep 28, 2021
608e9ed
fixed bug in file reference
jongund Sep 28, 2021
ac7b3e2
updated accessibility documentation
jongund Sep 28, 2021
f9bb2de
improved JS
jongund Sep 29, 2021
6044a71
Merge branch 'main' of github.com:w3c/aria-practices
jongund Oct 5, 2021
cd04cb7
Editorial revisions to intro
mcking65 Oct 10, 2021
8bd0124
Editorial revision to keyboard section
mcking65 Oct 10, 2021
00625c3
updated button descriptions
jongund Oct 10, 2021
9b7e77c
Removed aria-label on th for last name
jongund Oct 12, 2021
1a0c8df
updated example based on feedback at APG meeting today
jongund Oct 12, 2021
9869fca
updated regression tests
jongund Oct 12, 2021
240c2f3
fixed linting bugs
jongund Oct 12, 2021
2aecf00
fixed linting bugs
jongund Oct 12, 2021
7ffaaba
updated regression test
jongund Oct 12, 2021
820e0c1
added example option for showing a different shaped icon for column t…
jongund Oct 13, 2021
b9258de
udpated css
jongund Oct 13, 2021
bcc77df
adjusted css
jongund Oct 13, 2021
65a516a
adjusted css
jongund Oct 13, 2021
b3efa67
update description of example option
jongund Oct 14, 2021
e0e5938
Merge in main and fix conflicts in index.html
mcking65 Oct 17, 2021
5aa92f8
Editorial revision to option description
mcking65 Oct 17, 2021
d20ba41
Editorial revisions to accessibility features
mcking65 Oct 17, 2021
7590fb4
white space consistency
mcking65 Oct 17, 2021
f65e9e1
editorial revisin to states and props documentation
mcking65 Oct 17, 2021
47041ce
Merge branch 'main' of github.com:w3c/aria-practices
jongund Oct 18, 2021
8ca743a
merged from main
jongund Oct 18, 2021
ed038a6
Merge branch 'sortable-table' of github.com:w3c/aria-practices into s…
jongund Oct 18, 2021
0926219
updated the description of the Example Option
jongund Oct 18, 2021
5bd3587
updated the description of the Example Option
jongund Oct 18, 2021
13351af
Merge branch 'main' of github.com:w3c/aria-practices
jongund Oct 26, 2021
88733e1
Merge branch 'main' of github.com:w3c/aria-practices
jongund Oct 29, 2021
e6ddf3b
Merge branch 'main' into sortable-table
jongund Oct 29, 2021
120ead1
updated discription for optional icon on columns that can be sorted
jongund Oct 29, 2021
bd33c36
removed confusing role='cell' on TD elements
jongund Oct 29, 2021
fa1b930
removed documentation related to synchronizing the visual state with …
jongund Oct 29, 2021
ed9ff40
fixed html linting bug
jongund Oct 29, 2021
f14b67b
fixed spacing bug
jongund Oct 29, 2021
59d568a
Merge remote-tracking branch 'origin/main' into sortable-table
mcking65 Oct 31, 2021
9ab0639
Clarify wording of example option description
mcking65 Oct 31, 2021
33b23b8
Add sortability to cspell.json
mcking65 Oct 31, 2021
ac426b1
Merge branch 'main' of github.com:w3c/aria-practices
jongund Oct 31, 2021
a152cd8
updated the example option description, removed the section on using …
jongund Oct 31, 2021
886f344
Merge branch 'main' into sortable-table
jongund Oct 31, 2021
b25bb20
Merge remote-tracking branch 'origin/main' into sortable-table
mcking65 Oct 31, 2021
767dfd4
Minor editorial corrections
mcking65 Oct 31, 2021
511c27d
Add links to example page
mcking65 Oct 31, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
"shizzle",
"Shopify",
"Smorgeni",
"sortability",
"sourcecode",
"Spinbuttons",
"Starkrimson",
Expand Down
8 changes: 7 additions & 1 deletion examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ <h2 id="examples_by_props_label">Examples By Properties and States</h2>
<li><a href="spinbutton/datepicker-spinbuttons.html">Date Picker Spin Button</a></li>
<li><a href="switch/switch-button.html">Switch Using HTML Button</a> (<abbr title="High Contrast Support">HC</abbr>)</li>
<li><a href="switch/switch.html">Switch</a> (<abbr title="High Contrast Support">HC</abbr>)</li>
<li><a href="table/sortable-table.html">Sortable Table</a> (<abbr title="High Contrast Support">HC</abbr>)</li>
<li><a href="toolbar/toolbar.html">Toolbar</a></li>
</ul>
</td>
Expand Down Expand Up @@ -823,7 +824,12 @@ <h2 id="examples_by_props_label">Examples By Properties and States</h2>
</tr>
<tr>
<td><code>aria-sort</code></td>
<td><a href="grid/dataGrids.html">Data Grid</a></td>
<td>
<ul>
<li><a href="grid/dataGrids.html">Data Grid</a></li>
<li><a href="table/sortable-table.html">Sortable Table</a> (<abbr title="High Contrast Support">HC</abbr>)</li>
</ul>
</td>
</tr>
<tr>
<td><code>aria-valuemax</code></td>
Expand Down
101 changes: 101 additions & 0 deletions examples/table/css/sortable-table.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
.sr-only {
position: absolute;
top: -30em;
}

table.sortable td,
table.sortable th {
padding: 0.125em 0.25em;
width: 8em;
}

table.sortable th {
font-weight: bold;
border-bottom: thin solid #888;
position: relative;
}

table.sortable th.no-sort {
padding-top: 0.35em;
}

table.sortable th:nth-child(5) {
width: 10em;
}

table.sortable th button {
position: absolute;
padding: 4px;
margin: 1px;
font-size: 100%;
font-weight: bold;
background: transparent;
border: none;
display: inline;
right: 0;
left: 0;
top: 0;
bottom: 0;
width: 100%;
text-align: left;
outline: none;
cursor: pointer;
}

table.sortable th button span {
position: absolute;
right: 4px;
}

table.sortable th[aria-sort="descending"] span::after {
content: "▼";
color: currentColor;
font-size: 100%;
top: 0;
}

table.sortable th[aria-sort="ascending"] span::after {
content: "▲";
color: currentColor;
font-size: 100%;
top: 0;
}

table.show-unsorted-icon th:not([aria-sort]) button span::after {
content: "♢";
color: currentColor;
font-size: 100%;
position: relative;
top: -3px;
left: -4px;
}

table.sortable td.num {
text-align: right;
}

table.sortable tbody tr:nth-child(odd) {
background-color: #ddd;
}

/* Focus and hover styling */

table.sortable th button:focus,
table.sortable th button:hover {
padding: 2px;
border: 2px solid currentColor;
background-color: #e5f4ff;
}

table.sortable th button:focus span,
table.sortable th button:hover span {
right: 2px;
}

table.sortable th:not([aria-sort]) button:focus span::after,
table.sortable th:not([aria-sort]) button:hover span::after {
content: "▼";
color: currentColor;
font-size: 100%;
top: 0;
}
167 changes: 167 additions & 0 deletions examples/table/js/sortable-table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* This content is licensed according to the W3C Software License at
* https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
*
* File: sortable-table.js
*
* Desc: Adds sorting to a HTML data table that implements ARIA Authoring Practices
*/

'use strict';

class SortableTable {
constructor(tableNode) {
this.tableNode = tableNode;

this.columnHeaders = tableNode.querySelectorAll('thead th');

this.sortColumns = [];

for (var i = 0; i < this.columnHeaders.length; i++) {
var ch = this.columnHeaders[i];
var buttonNode = ch.querySelector('button');
if (buttonNode) {
this.sortColumns.push(i);
buttonNode.setAttribute('data-column-index', i);
buttonNode.addEventListener('click', this.handleClick.bind(this));
}
}

this.optionCheckbox = document.querySelector(
'input[type="checkbox"][value="show-unsorted-icon"]'
);

if (this.optionCheckbox) {
this.optionCheckbox.addEventListener(
'change',
this.handleOptionChange.bind(this)
);
if (this.optionCheckbox.checked) {
this.tableNode.classList.add('show-unsorted-icon');
}
}
}

setColumnHeaderSort(columnIndex) {
if (typeof columnIndex === 'string') {
columnIndex = parseInt(columnIndex);
}

for (var i = 0; i < this.columnHeaders.length; i++) {
var ch = this.columnHeaders[i];
var buttonNode = ch.querySelector('button');
if (i === columnIndex) {
var value = ch.getAttribute('aria-sort');
if (value === 'descending') {
ch.setAttribute('aria-sort', 'ascending');
this.sortColumn(
columnIndex,
'ascending',
ch.classList.contains('num')
);
} else {
ch.setAttribute('aria-sort', 'descending');
this.sortColumn(
columnIndex,
'descending',
ch.classList.contains('num')
);
}
} else {
if (ch.hasAttribute('aria-sort') && buttonNode) {
ch.removeAttribute('aria-sort');
}
}
}
}

sortColumn(columnIndex, sortValue, isNumber) {
function compareValues(a, b) {
if (sortValue === 'ascending') {
if (a.value === b.value) {
return 0;
} else {
if (isNumber) {
return a.value - b.value;
} else {
return a.value < b.value ? -1 : 1;
}
}
} else {
if (a.value === b.value) {
return 0;
} else {
if (isNumber) {
return b.value - a.value;
} else {
return a.value > b.value ? -1 : 1;
}
}
}
}

if (typeof isNumber !== 'boolean') {
isNumber = false;
}

var tbodyNode = this.tableNode.querySelector('tbody');
var rowNodes = [];
var dataCells = [];

var rowNode = tbodyNode.firstElementChild;

var index = 0;
while (rowNode) {
rowNodes.push(rowNode);
var rowCells = rowNode.querySelectorAll('th, td');
var dataCell = rowCells[columnIndex];

var data = {};
data.index = index;
data.value = dataCell.textContent.toLowerCase().trim();
if (isNumber) {
data.value = parseFloat(data.value);
}
dataCells.push(data);
rowNode = rowNode.nextElementSibling;
index += 1;
}

dataCells.sort(compareValues);

// remove rows
while (tbodyNode.firstChild) {
tbodyNode.removeChild(tbodyNode.lastChild);
}

// add sorted rows
for (var i = 0; i < dataCells.length; i += 1) {
tbodyNode.appendChild(rowNodes[dataCells[i].index]);
}
}

/* EVENT HANDLERS */

handleClick(event) {
var tgt = event.currentTarget;
this.setColumnHeaderSort(tgt.getAttribute('data-column-index'));
}

handleOptionChange(event) {
var tgt = event.currentTarget;

if (tgt.checked) {
this.tableNode.classList.add('show-unsorted-icon');
} else {
this.tableNode.classList.remove('show-unsorted-icon');
}
}
}

// Initialize sortable table buttons
window.addEventListener('load', function () {
var sortableTables = document.querySelectorAll('table.sortable');
for (var i = 0; i < sortableTables.length; i++) {
new SortableTable(sortableTables[i]);
}
});
Loading