Sort Data
Col 1 Col 2 Col 3
alfa foxtrot tango
charlie delta sierra
bravo echo hotel

HTML

<bitty-7-0 data-connect="SortColumns">
  <table>
    <thead>
      <tr data-init="makeButtons">
        <th>Col 1</th>
        <th>Col 2</th>
        <th>Col 3</th>
      </tr>
    </thead>
    <tbody data-receive="sortColumn">
      <tr>
        <td>alfa</td>
        <td>foxtrot</td>
        <td>tango</td>
      </tr>
      <tr>
        <td>charlie</td>
        <td>delta</td>
        <td>sierra</td>
      </tr>
      <tr>
        <td>bravo</td>
        <td>echo</td>
        <td>hotel</td>
      </tr>
    </tbody>
  </table>
</bitty-7-0>

JavaScript

const templates = {
  sortButton: `
<button 
  data-receive="selectButton"
  data-send="sortColumn selectButton" 
  data-index="INDEX">TEXT</button>`,

  row: `
  <tr><td>COL1</td><td>COL2</td><td>COL3</td></tr>`,
};

window.SortColumns = class {
  makeButtons(_ev, el) {
    el.querySelectorAll("th").forEach((cell, cellIndex) => {
      const subs = [
        ["INDEX", cellIndex],
        ["TEXT", cell.innerHTML],
      ];
      const output = this.api.makeHTML(templates.sortButton, subs);
      cell.replaceChildren(output);
    });
  }

  selectButton(_ev, el) {
    if (el.isTarget) {
      el.classList.add("active-button");
    } else {
      el.classList.remove("active-button");
    }
  }

  sortColumn(ev, el) {
    const rowToSortOn = ev.propToInt("index");
    let rows = [];
    el.querySelectorAll("tr").forEach((tr) => {
      const cells = [];
      tr.querySelectorAll("td").forEach((td) => {
        cells.push(td.innerHTML);
      });
      rows.push(cells);
    });

    rows.sort((a, b) => {
      const aCheck = a[rowToSortOn].toLowerCase();
      const bCheck = b[rowToSortOn].toLowerCase();
      if (aCheck < bCheck) {
        return -1;
      }
      if (aCheck > bCheck) {
        return 1;
      }
      return 0;
    });

    el.replaceChildren();
    rows.forEach((row) => {
      const subs = [
        ["COL1", row[0]],
        ["COL2", row[1]],
        ["COL3", row[2]],
      ];
      const updatedRow = this.api.makeHTML(templates.row, subs);
      el.appendChild(updatedRow);
    });
  }
};