HTML table sort ES2015

Client side table sorting 201807: updated 2 es2018

by KooiInc MeHere

HTML

<h2>Table sort</h2>
<p>
  Click a yellow column header to sort the table on [the values of] that column ascending. Click the same hader to switch the sort direction.
</p>
<table>
  <tr>
    <th data-sortable="numeric" data-fulltext="#"></th>
    <th data-sortable="string">Name</th>
    <th data-sortable="datetime">Birth date</th>
    <th data-sortable="numeric">Shoe size</th>
    <th>Did vote</th>
  </tr>
  <tr>
    <td></td>
    <td>John</td>
    <td data-rawdate="2001/01/03">03-01-2001</td>
    <td>37</td>
    <td>no</td>
  </tr>
  <tr>
    <td></td>
    <td>Mary</td>
    <td data-rawdate="1997/05/04">04-05-1997</td>
    <td>43</td>
    <td>yes</td>
  </tr>
  <tr>
    <td></td>
    <td>Wui Chi</td>
    <td data-rawdate="1999/07/01">01-07-1999</td>
    <td>41</td>
    <td>yes</td>
  </tr>
  <tr>
    <td></td>
    <td>Anne</td>
    <td data-rawdate="1959/03/19">19-03-1959</td>
    <td>40.5</td>
    <td>no</td>
  </tr>
  <tr>
    <td></td>
    <td>Otto</td>
    <td data-rawdate="1947/02/28">28-02-1947</td>
    <td>46</td>
    <td>no</td>
  </tr>
  <tr>
    <td></td>
    <td>Frankie</td>
    <td data-rawdate="2003/06/10">10-06-2003</td>
    <td>34</td>
    <td>no</td>
  </tr>
  <tr>
    <td></td>
    <td>Chloe</td>
    <td data-rawdate="1923/07/03">03-07-1923</td>
    <td>39</td>
    <td>no</td>
  </tr>
  <tr>
    <td></td>
    <td>Jeffrey</td>
    <td data-rawdate="1966/02/21">12-02-1966</td>
    <td>47.5</td>
    <td>no</td>
  </tr>
  <tr>
    <td></td>
    <td>Joey</td>
    <td data-rawdate="1986/05/01">02-05-1986</td>
    <td>41</td>
    <td>yes</td>
  </tr>
  <tr>
    <td></td>
    <td>Missy</td>
    <td data-rawdate="1986/08/21">21-08-1986</td>
    <td>40</td>
    <td>no</td>
  </tr>
</table>

CSS

body {
  margin: 2em;
  font: normal 0.8em verdana, arial;
}

th {
  background-color: #000;
  color: #fff;
  padding: 1px 5px;
  text-align: left;
  vertical-align: middle;
  border-right: 1px solid #BBB;
  line-height: 1.2em;
}

th:before {
  content: attr(data-fulltext);
}

th[data-sortable] {
  color: yellow !important;
  cursor: pointer;
}

th[data-sortable]:after {
  content: '\a0\26AA';
  font-size: 0.9em;
}

th[data-direction="asc"]:after {
  content: '\a0\25BC';
  font-size: 0.9em;
}

th[data-direction="desc"]:after {
  content: '\a0\25B2';
  font-size: 0.9em;
}

td:nth-child(3),
td:nth-child(4),
td:nth-child(5) {
  text-align: center;
}

td.center {
  text-align: center;
}

JavaScript

// 201806: removed JQuery dependency
((d) => {
  const utils = init();
  d.addEventListener("click", utils.doSort);
  utils.numberRows(1);
  d.querySelector("table tr th:first-child").click();

  function sortColumn(evt) {
    const origin = utils.findParentEl(evt.target, "th");
    const columnIndex = origin && parseInt(origin.cellIndex);
    const sortingOn = origin && origin.dataset.sortable || null;
    return !origin || isNaN(columnIndex) || !sortingOn ? true : doSort();

    function doSort() {
      const forTable = utils.findParentEl(origin, "table") || null;
      const currentDirection = utils.getCurrentDirection(origin);
      const cells2Sort = Array.from(forTable.querySelectorAll(`tr td:nth-child(${
            columnIndex + 1})`)) || null;

      // are all value types in column the right type?
      if (!utils.checkColumnValueTypes(cells2Sort, sortingOn)) {
        origin.dataset.sortable = null;
        return alert(`Sorry, one or more of the values in this column are not of type [${
                sortingOn}]`);
      }

      // set current column properties
      Array.from(d.querySelectorAll("[data-sortable]")).forEach(utils.redoHeaders);
      origin.classList.add("sortedhere");

      // Note: this will take effect in the *next* sort if applicable
      // should happen before cloning
      origin.dataset.direction = utils.toggleDirection(currentDirection);

      let tableClone = forTable.cloneNode(true);
      let cloneRows = Array.from(tableClone.rows).slice(1);

      // No rows? do nothing
      if (!cloneRows.length) {
        return;
      }

      // extract column values and create sortable array
      let sortVals = utils.getSortValues(cloneRows, columnIndex, sortingOn);

      // assign sorting parameter and sort using factory method [sortHelper]
      sortVals = sortVals.sort(utils.sorter({
        key: "value",
        [sortingOn]: 1
      }, currentDirection));
      // reorder tablerows cf sorting
     ...