Skip to content

Commit

Permalink
Support tables that have multiple tbodies. (#110)
Browse files Browse the repository at this point in the history
* First hash at multiple tbodies seems to work

* Fix remember sort bug.

* Update manual testing table.

* Add test for tables that have multiple tbodies and associated theads.

* Add test for tables that have multiple tbodies and associated theads.

* Add test for tables that have multiple tbodies and associated theads.
  • Loading branch information
LeeWannacott committed May 26, 2023
1 parent 864747c commit 319b795
Show file tree
Hide file tree
Showing 4 changed files with 266 additions and 35 deletions.
139 changes: 138 additions & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ <h1>Manual testing of table sort js</h1>
<td>8/6/1978</td>
</tr>
</table>
<h2>Testing table containing colspan and data-sort</h2>
<h2>Testing table containing colspan and data-sort and multiple tbodies</h2>
<table class="available table-sort table-arrows">
<thead>
<tr>
Expand Down Expand Up @@ -162,6 +162,143 @@ <h2>Testing table containing colspan and data-sort</h2>
<td>2022-07-31</td>
</tr>
</tbody>
<thead>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th class="order-by-desc">Birth Date</th>
<th>Employee ID</th>
<th>Department</th>
<th>Runtime</th>
<th class="onload-sort">File Size</th>
<th class="data-sort">data-sort days</th>
<th>dates in dd/mm/yyyy</th>
</tr>
</thead>
<tr class="table-row-1">
<td>Franklin</td>
<td>Benjamin</td>
<td>1706-1-17</td>
<td>1</td>
<td>k-level</td>
<td>1h 1m 17s</td>
<td>10b</td>
<td data-sort="2">Tuesday</td>
<td>17/6/1978</td>
</tr>
<tr class="table-row-2">
<td>da Vinci</td>
<td>Zarlo</td>
<td>1452-4-15</td>
<td>13000</td>
<td></td>
<td>1m 45s</td>
<td>192038998987021b</td>
<td data-sort="3">Wednesday</td>
<td>18/10/2027</td>
</tr>
<tr>
<td>Statham</td>
<td>Jason</td>
<td>1967-7-26</td>
<td></td>
<td>HR</td>
<td>11m 40s</td>
<td>134809b</td>
<td data-sort="5">Friday</td>
<td>4/9/2008</td>
</tr>
<tr>
<td>Micheal</td>
<td>Angelo</td>
<td>1958-8-21</td>
<td>54</td>
<td>Marketing</td>
<td>29s</td>
<td>30980980b</td>
<td data-sort="4">Thursday</td>
<td>2/3/1879</td>
</tr>
<tr>
<td>Ben</td>
<td></td>
<td>1994/9/23</td>
<td>134</td>
<td>Marketing</td>
<td>41s</td>
<td>902938402398b</td>
<td data-sort="1">Monday</td>
<td>8/6/1978</td>
</tr>
<thead>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th class="order-by-desc">Birth Date</th>
<th>Employee ID</th>
<th>Department</th>
<th>Runtime</th>
<th class="onload-sort">File Size</th>
<th class="data-sort">data-sort days</th>
<th>dates in dd/mm/yyyy</th>
</tr>
</thead>
<tr class="table-row-1">
<td>Franklin</td>
<td>Benjamin</td>
<td>1706-1-17</td>
<td>1</td>
<td>k-level</td>
<td>1h 1m 17s</td>
<td>10b</td>
<td data-sort="2">Tuesday</td>
<td>17/6/1978</td>
</tr>
<tr class="table-row-2">
<td>da Vinci</td>
<td>Zarlo</td>
<td>1452-4-15</td>
<td>13000</td>
<td></td>
<td>1m 45s</td>
<td>192038998987021b</td>
<td data-sort="3">Wednesday</td>
<td>18/10/2027</td>
</tr>
<tr>
<td>Statham</td>
<td>Jason</td>
<td>1967-7-26</td>
<td></td>
<td>HR</td>
<td>11m 40s</td>
<td>134809b</td>
<td data-sort="5">Friday</td>
<td>4/9/2008</td>
</tr>
<tr>
<td>Micheal</td>
<td>Angelo</td>
<td>1958-8-21</td>
<td>54</td>
<td>Marketing</td>
<td>29s</td>
<td>30980980b</td>
<td data-sort="4">Thursday</td>
<td>2/3/1879</td>
</tr>

<tr>
<td>Ben</td>
<td></td>
<td>1994/9/23</td>
<td>134</td>
<td>Marketing</td>
<td>41s</td>
<td>902938402398b</td>
<td data-sort="1">Monday</td>
<td>8/6/1978</td>
</tr>
</table>
</body>
</html>
71 changes: 37 additions & 34 deletions public/table-sort.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,18 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
sortableTable.insertBefore(createTableHead, sortableTable.firstChild);
}

function getTableBody(sortableTable) {
function getTableBodies(sortableTable) {
if (sortableTable.getElementsByTagName("thead").length === 0) {
createMissingTableHead(sortableTable);
if (sortableTable.querySelectorAll("tbody").length > 1) {
// Why index 1?; I don't remember
return sortableTable.querySelectorAll("tbody")[1];
} else {
return sortableTable.querySelector("tbody");
return sortableTable.querySelectorAll("tbody");
}
} else {
// if <tr> or <td> exists below <thead> the browser will make <tbody>
return sortableTable.querySelector("tbody");
return sortableTable.querySelectorAll("tbody");
}
}

Expand Down Expand Up @@ -108,30 +109,43 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {

function makeTableSortable(sortableTable) {
const table = {
body: getTableBody(sortableTable),
head: sortableTable.querySelector("thead"),
bodies: getTableBodies(sortableTable),
theads: sortableTable.querySelectorAll("thead"),
rows: [],
headers: [],
};
if (table.body == null) {
return;
for (let index of table.bodies.keys()) {
if (table.bodies.item(index) == null) {
return;
}
table.headers.push(table.theads.item(index).querySelectorAll("th"));
table.rows.push(table.bodies.item(index).querySelectorAll("tr"));
}
table.headers = table.head.querySelectorAll("th");
table.rows = table.body.querySelectorAll("tr");

table.hasClass = {
noClassInfer: sortableTable.classList.contains("no-class-infer"),
cellsSort: sortableTable.classList.contains("cells-sort"),
tableArrows: sortableTable.classList.contains("table-arrows"),
rememberSort: sortableTable.classList.contains("remember-sort"),
};

let columnIndexesClicked = [];

for (let [columnIndex, th] of table.headers.entries()) {
if (!th.classList.contains("disable-sort")) {
th.style.cursor = "pointer";
if (!table.hasClass.noClassInfer) {
inferSortClasses(table.rows, columnIndex, th);
for ( let headerIndex = 0; headerIndex < table.theads.length; headerIndex++) {
let columnIndexesClicked = [];
for (let [columnIndex, th] of table.headers[headerIndex].entries()) {
if (!th.classList.contains("disable-sort")) {
th.style.cursor = "pointer";
if (!table.hasClass.noClassInfer) {
inferSortClasses(table.rows[headerIndex], columnIndex, th);
}
makeEachColumnSortable(
th,
headerIndex,
columnIndex,
table,
columnIndexesClicked
);
}
makeEachColumnSortable(th, columnIndex, table, columnIndexesClicked);
}
}
}
Expand Down Expand Up @@ -174,10 +188,7 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
let unit = match[2].toLowerCase();
let multiplier = unitToMultiplier[unit];
column.toBeSorted.push(`${number * multiplier}#${i}`);
columnIndexAndTableRow[column.toBeSorted[i]] = cellsOrRows(
table,
tr
);
columnIndexAndTableRow[column.toBeSorted[i]] = cellsOrRows(table, tr);
}
}
}
Expand Down Expand Up @@ -217,10 +228,7 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
);
}
column.toBeSorted.push(`${numberToSort}#${i}`);
columnIndexAndTableRow[column.toBeSorted[i]] = cellsOrRows(
table,
tr
);
columnIndexAndTableRow[column.toBeSorted[i]] = cellsOrRows(table, tr);
}
} catch (e) {
console.log(e);
Expand Down Expand Up @@ -265,10 +273,7 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
timeinSeconds = hours + minutesInSeconds + seconds;
}
column.toBeSorted.push(`${timeinSeconds}#${i}`);
columnIndexAndTableRow[column.toBeSorted[i]] = cellsOrRows(
table,
tr
);
columnIndexAndTableRow[column.toBeSorted[i]] = cellsOrRows(table, tr);
}
} catch (e) {
console.log(e);
Expand Down Expand Up @@ -315,10 +320,7 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
} else {
// Fill in blank table cells dict key with filler value.
column.toBeSorted.push(`${fillValue}#${i}`);
columnIndexAndTableRow[`${fillValue}#${i}`] = cellsOrRows(
table,
tr
);
columnIndexAndTableRow[`${fillValue}#${i}`] = cellsOrRows(table, tr);
}
}

Expand Down Expand Up @@ -507,6 +509,7 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {

function makeEachColumnSortable(
th,
headerIndex,
columnIndex,
table,
columnIndexesClicked
Expand Down Expand Up @@ -537,10 +540,10 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
column.toBeSorted = [];
column.span = {};
column.spanSum = {};
getColSpanData(table.headers, column);
getColSpanData(table.headers[headerIndex], column);

table.visibleRows = Array.prototype.filter.call(
table.body.querySelectorAll("tr"),
table.bodies.item(headerIndex).querySelectorAll("tr"),
(tr) => {
return tr.style.display !== "none";
}
Expand Down
76 changes: 76 additions & 0 deletions test/missingTableTags.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,85 @@ function createTestTableMissingBodyAndHeadTag(testTableData, classTags = "") {
return testIfSortedList;
}

function createTestTableMultipleTBodies(
testTableData,
testTableData2,
testTableData3,
classTags = ""
) {
let getClassTagsForTH = [];
let testTableThRow = `<tr><th class="${classTags}">Testing Column</th></tr>`;
getClassTagsForTH.push(testTableThRow);
function makeTdRows(testTableData) {
let testTableTdRows = [];
for (let i = 0; i < testTableData.length; i++) {
let testTableTdRow = `<tr><td>${testTableData[i]}</td></tr>`;
testTableTdRows.push(testTableTdRow);
}
return testTableTdRows;
}
let testTableTdRows = makeTdRows(testTableData);
let testTableTdRows2 = makeTdRows(testTableData2);
let testTableTdRows3 = makeTdRows(testTableData3);
const tableWithMultipleTableBodies = new JSDOM(`<!DOCTYPE html>
<html>
<head>
</head>
<body>
<table class="table-sort">
<thead>
${getClassTagsForTH}
</thead>
<tbody>
${testTableTdRows}
</tbody>
<thead>
${getClassTagsForTH}
</thead>
<tbody>
${testTableTdRows2}
</tbody>
<thead>
${getClassTagsForTH}
</thead>
<tbody>
${testTableTdRows3}
</tbody>
</table>
</body>
</html>`);
// Call tablesort and make table sortable and simulate click from a user.
tableSortJs((testing = true), tableWithMultipleTableBodies.window.document);
const tableTH =
tableWithMultipleTableBodies.window.document.querySelectorAll("table th");
for (let th of tableTH) {
th.click();
}
// Make an array from table contents to test if sorted correctly.
let table =
tableWithMultipleTableBodies.window.document.querySelector("table");
const tableBodies = table.querySelectorAll("tbody");
const tableHeads = table.querySelectorAll("thead");

let tableRowArray = [];
for (let i = 0; i < tableHeads.length; i++) {
let tableRows = [...tableBodies.item(i).querySelectorAll("tr")];
tableRowArray.push(tableRows);
}
let testIfSortedArray = [];
for (let i = 0; i < tableHeads.length; i++) {
let testIfSortedList = tableRowArray[i].map(
(tr) => tr.querySelectorAll("td").item(0).innerHTML
);
testIfSortedArray.push(testIfSortedList);
}
return [...testIfSortedArray];
}

module.exports = {
createTestTableNoMissingTags,
createTestTableMissingHeadTag,
createTestTableMissingBodyTag,
createTestTableMissingBodyAndHeadTag,
createTestTableMultipleTBodies,
};
Loading

0 comments on commit 319b795

Please sign in to comment.