Accessible Expandable Tree Table In JavaScript

Category: Javascript , Table | August 30, 2019
AuthorAdrian Roselli
Last UpdateAugust 30, 2019
LicenseMIT
Views4,046 views
Accessible Expandable Tree Table In JavaScript

An accessible expandable HTML enhancement script that allows the user to toggle (expand/collapse) table rows just like a tree structure.

How to use it:

Add the class="hidden" to the table rows which should be hidden on init. Note that each tr must have a unique ID.

<tr id="MS01b" class="hidden">
  <td></td>
  <td>Mary Shelley</td>
  <td>Valperga: Or, the Life and Adventures of Castruccio, Prince of Lucca</td>
  <td>1823</td>
  <td></td>
  <td></td>
</tr>
<tr id="MS02b" class="hidden">
  <td></td>
  <td>Mary Shelley</td>
  <td>The Last Man</td>
  <td>1826</td>
  <td></td>
  <td></td>
</tr>
<tr id="MS03b" class="hidden">
  <td></td>
  <td>Mary Shelley</td>
  <td>The Fortunes of Perkin Warbeck, A Romance</td>
  <td>1830</td>
  <td></td>
  <td></td>
</tr>

Add a toggle button to the parent table row and specify the row IDs in the toggle method.

<td>
  <button type="button" id="btnMSb" aria-expanded="false" onclick="toggle(this.id,'#MS01b,#MS02b,#MS03b');" aria-controls="MS01b MS02b MS03b" aria-label="3 more from" aria-labelledby="btnMSb lblMSb">
    <svg xmlns="\http://www.w3.org/2000/svg&quot;" viewBox="0 0 80 80" focusable="false"><path d="M70.3 13.8L40 66.3 9.7 13.8z"></path></svg>
  </button>
</td>

The required CSS rules.

tr.shown, tr.hidden {
  display: table-row;
}
tr.hidden {
  display: none;
}
.row button {
  background-color: transparent;
  border: .1em solid transparent;
  font: inherit;
  padding: 0.25em 0.5em 0.25em .25em;
  width: 100%;
  text-align: left;
}
.row button:focus, .row button:hover {
  background-color: #ddd;
  outline: .2em solid #00f;
}
.row button svg {
  width: .8em;
  height: .8em;
  margin: 0 0 -.05em 0;
  fill: #66f;
  transition: transform 0.25s ease-in;
  transform-origin: center 45%;
}
.row button:hover svg,
.row button:focus svg {
  fill: #00c;
}
/* Lean on programmatic state for styling */
.row button[aria-expanded="true"] svg {
  transform: rotate(180deg);
}
.cell button {
  font-size: 60%;
  color: #000;
  background-color: #00f;
  padding: 0.3em 0.2em 0 0.2em;
  border: 0.2em solid #00f;
  border-radius: 50%;
  line-height: 1;
  text-align: center;
  text-indent: 0;
  transform: rotate(270deg);
}
.cell button svg {
  width: 1.25em;
  height: 1.25em;
  fill: #fff;
  transition: transform 0.25s ease-in;
  transform-origin: center 45%;
}
.cell button:hover,
.cell button:focus {
  background-color: #fff;
  outline: none;
}
.cell button:hover svg,
.cell button:focus svg {
  fill: #00f;
}
/* Lean on programmatic state for styling */
.cell button[aria-expanded="true"] svg {
  transform: rotate(90deg);
}
/* Proven method to visually hide something but */
/* still make it available to assistive technology */
.visually-hidden {
  position: absolute;
  top: auto;
  overflow: hidden;
  clip: rect(1px 1px 1px 1px); /* IE 6/7 */
  clip: rect(1px, 1px, 1px, 1px);
  width: 1px;
  height: 1px;
  white-space: nowrap;
}

The main function to expand/collapse the table rows when you click on the toggle button.

function toggle(btnID, eIDs) {
  // Feed the list of ids as a selector
  var theRows = document.querySelectorAll(eIDs);
  // Get the button that triggered this
  var theButton = document.getElementById(btnID);
  // If the button is not expanded...
  if (theButton.getAttribute("aria-expanded") == "false") {
    // Loop through the rows and show them
    for (var i = 0; i < theRows.length; i++) {
      theRows[i].classList.add("shown");
      theRows[i].classList.remove("hidden");
    }
    // Now set the button to expanded
    theButton.setAttribute("aria-expanded", "true");
  // Otherwise button is not expanded...
  } else {
    // Loop through the rows and hide them
    for (var i = 0; i < theRows.length; i++) {
      theRows[i].classList.add("hidden");
      theRows[i].classList.remove("shown");
    }
    // Now set the button to collapsed
    theButton.setAttribute("aria-expanded", "false");
  }
}

You Might Be Interested In:


Leave a Reply