Skip to content

Commit

Permalink
feat: improve sortable table example
Browse files Browse the repository at this point in the history
  • Loading branch information
ppvg committed Oct 2, 2023
1 parent 3510b7e commit c773f95
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 30 deletions.
113 changes: 83 additions & 30 deletions docs/documentation/components/table-sortable.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,63 +53,99 @@
<h1>Sorteerbare tabel</h1>
<p>
Om inzicht te krijgen in de data kan het behulpzaam zijn om de gebruiker de data te
laten sorteren. Bijvoorbeeld op basis van op of aflopende data.
laten sorteren.
</p>

<h2>Benodigde stappen:</h2>
<ol>
<li>
Voeg een <code>button</code> toe binnen de <code>th</code> om sorteerelemeent
klikbaar te maken.
Voeg een <code>&lt;button></code> toe binnen de <code>&lt;th></code> van elke sorteerbare kolom.
<ul>
<li>Voeg de <code>&lt;button></code> alleen toe aan sorteerbare kolommen. Niet elke kolom hoeft sorteerbaar te zijn.</li>
<li>Plaats de tekst van de kolomkop in de <code>&lt;button></code>, zodat de hele kolomkop klikbaar is.</li>
</ul>
</li>
<li>
Voeg binnen de knop een icoon toe indien gewenst. Voor meer informatie zie:
<a href="./button-icon.html">Icoonknoppen</a>
Voeg binnen de knop van elke sorteerbare kolom een icoon toe. Voor meer informatie zie:
<a href="./icons.html">Iconen</a>.
<ul>
<li>Zorg dat de gebruikte Icoonset iconen heeft voor ongesoorteerde data, oplopend gesorteerde data en aflopend gesorteerde data.</li>
<li>Gebruik bij voorkeur iconen met ingevulde driehoeken, bijvoorbeeld <span class="icon icon-sortable">driehoeken omhoog en omlaag</span> voor ongesorteerd, <span class="icon icon-ascending">driehoek omhoog</span> voor oplopend gesorteerd en <span class="icon icon-descending">driehoek omlaag</span> voor aflopend gesorteerd.</li>
</ul>
</li>
<li>
Voeg <code>abbr=""</code> toe aan de <code>&lt;th></code> met een korte duidelijke
omschrijving om de gebruikerservaring te verbeteren voor gebruikers die gebruik
maken van een screenreader.
Voeg een toelichting over de sorteerknoppen toe aan de <code>&lt;caption></code>. Bijvoorbeeld: "kolomkoppen met knoppen zijn sorteerbaar".
<ul>
<li>Indien gewenst kan deze tekst visueel verborgen worden met de <code>visually-hidden</code> class.</li>
<li>Zorg ervoor dat er een punt of komma staat tussen de bestaande caption-tekst en deze hint-tekst. Bij gebruik van een <code>visually-hidden</code> <code>&lt;>span></code> kan bijvoorbeeld een komma toegevoegd worden voorafgaand aan de hint-tekst.</li>
</ul>
</li>
<li>
Voeg een <code>abbr=""</code> toe aan de <code>&lt;th></code> indien de tekst in de <code>&lt;th></code> erg lang is.
<ul>
<li>De kortere omschrijving in de <code>abbr=""</code> wordt gebruikt door screenreaders bij het voorlezen van een cel in de bijbehorende kolom.</li>
</ul>
</li>
</ol>

<h2>Aandachtspunten</h2>
<ul>
<li>Dit element bevat momenteel geen JavaScript of logica voorbeeld.</li>
<li>Het is voor dit component nodig om het dynamische gedrag zelf via JavaScript te implementeren. De exacte implementatie is afhankelijk van de context.</li>
<li>Sorteer de inhoud van de tabel wanneer de gebruiker op één van de knoppen in de kolomkoppen klikt.</li>
<li>Draai de sorteervolgorde om, wanneer de gebruiker op de knop klikt van de kolom waar op dit moment op gesorteerd wordt.</li>
<li>Zorg ervoor dat elke kolomkop het juiste icoon heeft, afhankelijk van de huidige sortering van de tabel.</li>
<li>
Voeg <code>aria-sort=""</code> toe aan de <code>&lt;th></code> van de kolom waarop gesorteerd wordt.
<ul>
<li>Gebruik <code>aria-sort="ascending"</code> wanneer de sortering oplopend is.</li>
<li>Gebruik <code>aria-sort="descending"</code> wanneer de sortering aflopend is.</li>
</ul>
</li>
</ul>
</section>

<section id="examples">
<h2>Voorbeelden</h2>
<h3>Visueel voorbeeld:</h3>
<div class="horizontal-scroll">
<table>
<table id="sortable-table-example">
<caption>
Tabelvoorbeeld met sorteerbare data:
Tabelvoorbeeld met sorteerbare data
<span class="visually-hidden">, kolomkoppen met knoppen zijn sorteerbaar</span>
</caption>
<thead>
<tr>
<th scope="col" abbr="Ascending data">
<button title="Sort descending">
Descending <span class="icon icon-ascending"></span>
<th scope="col">
<button>
Voornaam
<span class="icon icon-sortable"></span>
</button>
</th>
<th scope="col" abbr="Descending data">
<button title="Sort ascending">
Ascending <span class="icon icon-descending"></span>
<th scope="col" abbr="Achternaam">
<button>
Achternaam (met tussenvoegsel)
<span class="icon icon-sortable"></span>
</button>
</th>
</tr>
</thead>

<tbody>
<tr>
<td>Lorem</td>
<td>Ipsum</td>
<td>Janine</td>
<td>Hinde</td>
</tr>
<tr>
<td>Henk</td>
<td>de Vries</td>
</tr>
<tr>
<td>Lorem</td>
<td>Ipsum</td>
<td>Maria</td>
<td>Lin</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
</tr>
</tbody>
</table>
Expand All @@ -120,26 +156,43 @@ <h3>Html-voorbeeld:</h3>
<code>
&lt;div class="horizontal-scroll">
&lt;table>
&lt;caption>Tabelvoorbeeld met sorteerbare data:&lt;/caption>
&lt;caption>
Tabelvoorbeeld met sorteerbare data
&lt;span class="visually-hidden">, kolomkoppen met knoppen zijn sorteerbaar&lt;/span>
&lt;/caption>
&lt;thead>
&lt;tr>
&lt;th scope="col" abbr="Ascending data">
&lt;button title="Sort descending">Descending &lt;span class="icon icon-ascending">&lt;/button>
&lt;th scope="col">
&lt;button>
Voornaam
&lt;span class="icon icon-sortable">&lt;/span>
&lt;/button>
&lt;/th>
&lt;th scope="col" abbr="Descending data">
&lt;button title="Sort ascending">Ascending &lt;span class="icon icon-descending">&lt;/span>&lt;/button>
&lt;th scope="col" abbr="Achternaam">
&lt;button>
Achternaam (met tussenvoegsel)
&lt;span class="icon icon-sortable">&lt;/span>
&lt;/button>
&lt;/th>
&lt;/tr>
&lt;/thead>

&lt;tbody>
&lt;tr>
&lt;td>Lorem&lt;/td>
&lt;td>Ipsum&lt;/td>
&lt;td>Janine&lt;/td>
&lt;td>Hinde&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Henk&lt;/td>
&lt;td>de Vries&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Maria&lt;/td>
&lt;td>Lin&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Lorem&lt;/td>
&lt;td>Ipsum&lt;/td>
&lt;td>John&lt;/td>
&lt;td>Doe&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
Expand Down
1 change: 1 addition & 0 deletions docs/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ import "@minvws/manon/form-help.js";
import "@minvws/manon/collapsible.js";
import "@minvws/manon/sidemenu.js";
import "@minvws/manon/language-selector.js";
import "./sortable-table.js";
74 changes: 74 additions & 0 deletions docs/js/sortable-table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { onDomReady } from "@minvws/manon/utils.js";

onDomReady(initSortableTable);

function initSortableTable() {
var thead = document.querySelector("#sortable-table-example thead");
var tbody = document.querySelector("#sortable-table-example tbody");
if (!(thead instanceof HTMLTableSectionElement) || !(tbody instanceof HTMLTableSectionElement)) {
return;
}
thead.addEventListener("click", function(event) {
var button = event.target;
if (!(button instanceof HTMLButtonElement)) {
return;
}
var sortStatus = getSortStatus(thead);
var columnIndex = getColumnIndex(button.parentElement);
if (columnIndex === sortStatus.columnIndex) {
sortStatus.direction = sortStatus.direction === 'ascending' ? 'descending' : 'ascending';
} else {
sortStatus.columnIndex = columnIndex;
sortStatus.direction = 'ascending';
}
updateSortButtons(thead, sortStatus);
sortTableBody(tbody, sortStatus);
});
}

function getColumnIndex(th) {
return Array.prototype.indexOf.call(th.parentElement.children, th);
}

function getSortStatus(thead) {
var sorted = thead.querySelector("[aria-sort]");
if (!sorted) {
return { columnIndex: -1, direction: null };
}
return {
columnIndex: getColumnIndex(sorted),
direction: sorted.getAttribute("aria-sort")
}
}

function updateSortButtons(thead, sortStatus) {
var ths = thead.querySelectorAll("th");
var sorted = thead.querySelector("th[aria-sort]");
if (sorted && getColumnIndex(sorted) !== sortStatus.columnIndex) {
sorted.removeAttribute("aria-sort");
var icon = sorted.querySelector(".icon");
if (icon) {
icon.classList.remove("icon-sortable", "icon-ascending", "icon-descending");
icon.classList.add("icon-sortable");
}
}
var sort = ths[sortStatus.columnIndex];
if (sort) {
sort.setAttribute("aria-sort", sortStatus.direction);
var icon = sort.querySelector(".icon");
if (icon) {
icon.classList.remove("icon-sortable", "icon-ascending", "icon-descending");
icon.classList.add("icon-" + sortStatus.direction);
}
}
}

function sortTableBody(tbody, sortStatus) {
var cells = tbody.querySelectorAll("tr > td:nth-of-type(" + (sortStatus.columnIndex + 1) + ")");
var comparator = sortStatus.direction === "ascending"
? function (a, b) { return ('' + a.innerText).localeCompare(b.innerText); }
: function (a, b) { return ('' + b.innerText).localeCompare(a.innerText); };
Array.prototype.slice.call(cells).sort(comparator).forEach(function (cell) {
tbody.appendChild(cell.parentNode);
});
}

0 comments on commit c773f95

Please sign in to comment.