From 319b795f97dfdf798b7e5c7aab6c1ade2de0da58 Mon Sep 17 00:00:00 2001 From: Lee Wannacott Date: Fri, 26 May 2023 21:58:13 +1200 Subject: [PATCH] Support tables that have multiple tbodies. (#110) * 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. --- public/index.html | 139 +++++++++++++++++++++++++++++++++- public/table-sort.js | 71 ++++++++--------- test/missingTableTags.js | 76 +++++++++++++++++++ test/missingTableTags.test.js | 15 ++++ 4 files changed, 266 insertions(+), 35 deletions(-) diff --git a/public/index.html b/public/index.html index 9f7789d..7ec7049 100644 --- a/public/index.html +++ b/public/index.html @@ -78,7 +78,7 @@

Manual testing of table sort js

8/6/1978 -

Testing table containing colspan and data-sort

+

Testing table containing colspan and data-sort and multiple tbodies

@@ -162,6 +162,143 @@

Testing table containing colspan and data-sort

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
2022-07-31
Last NameFirst NameBirth DateEmployee IDDepartmentRuntimeFile Sizedata-sort daysdates in dd/mm/yyyy
FranklinBenjamin1706-1-171k-level1h 1m 17s10bTuesday17/6/1978
da VinciZarlo1452-4-15130001m 45s192038998987021bWednesday18/10/2027
StathamJason1967-7-26HR11m 40s134809bFriday4/9/2008
MichealAngelo1958-8-2154Marketing29s30980980bThursday2/3/1879
Ben1994/9/23134Marketing41s902938402398bMonday8/6/1978
Last NameFirst NameBirth DateEmployee IDDepartmentRuntimeFile Sizedata-sort daysdates in dd/mm/yyyy
FranklinBenjamin1706-1-171k-level1h 1m 17s10bTuesday17/6/1978
da VinciZarlo1452-4-15130001m 45s192038998987021bWednesday18/10/2027
StathamJason1967-7-26HR11m 40s134809bFriday4/9/2008
MichealAngelo1958-8-2154Marketing29s30980980bThursday2/3/1879
Ben1994/9/23134Marketing41s902938402398bMonday8/6/1978
diff --git a/public/table-sort.js b/public/table-sort.js index 057d2c0..dbf75bd 100644 --- a/public/table-sort.js +++ b/public/table-sort.js @@ -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 or exists below the browser will make - return sortableTable.querySelector("tbody"); + return sortableTable.querySelectorAll("tbody"); } } @@ -108,14 +109,19 @@ 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"), @@ -123,15 +129,23 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) { 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); } } } @@ -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); } } } @@ -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); @@ -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); @@ -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); } } @@ -507,6 +509,7 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) { function makeEachColumnSortable( th, + headerIndex, columnIndex, table, columnIndexesClicked @@ -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"; } diff --git a/test/missingTableTags.js b/test/missingTableTags.js index 821dbd4..3b1d8e0 100644 --- a/test/missingTableTags.js +++ b/test/missingTableTags.js @@ -158,9 +158,85 @@ function createTestTableMissingBodyAndHeadTag(testTableData, classTags = "") { return testIfSortedList; } +function createTestTableMultipleTBodies( + testTableData, + testTableData2, + testTableData3, + classTags = "" +) { + let getClassTagsForTH = []; + let testTableThRow = `Testing Column`; + getClassTagsForTH.push(testTableThRow); + function makeTdRows(testTableData) { + let testTableTdRows = []; + for (let i = 0; i < testTableData.length; i++) { + let testTableTdRow = `${testTableData[i]}`; + testTableTdRows.push(testTableTdRow); + } + return testTableTdRows; + } + let testTableTdRows = makeTdRows(testTableData); + let testTableTdRows2 = makeTdRows(testTableData2); + let testTableTdRows3 = makeTdRows(testTableData3); + const tableWithMultipleTableBodies = new JSDOM(` + + + + + + + ${getClassTagsForTH} + + + ${testTableTdRows} + + + ${getClassTagsForTH} + + + ${testTableTdRows2} + + + ${getClassTagsForTH} + + + ${testTableTdRows3} + +
+ + `); + // 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, }; diff --git a/test/missingTableTags.test.js b/test/missingTableTags.test.js index 7433c8e..b777317 100644 --- a/test/missingTableTags.test.js +++ b/test/missingTableTags.test.js @@ -3,6 +3,7 @@ const { createTestTableMissingHeadTag, createTestTableMissingBodyAndHeadTag, createTestTableMissingBodyTag, + createTestTableMultipleTBodies, } = require("./missingTableTags"); // toBe for primitives like strings, numbers or booleans for everything else use toEqual(object) @@ -48,3 +49,17 @@ test("test with missing and tags", () => { ]) ).toStrictEqual(["Alpha", "Bravo", "Charlie", "Delta", "Echo"]); }); + +test("Multiple tags", () => { + expect( + createTestTableMultipleTBodies( + ["Echo", "Alpha", "Bravo", "Charlie", "Delta"], + [2, 1, 3, 5, 4], + ["diddly", "Jeremy", "squat", "Clarksons", "farm"] + ) + ).toStrictEqual([ + ["Alpha", "Bravo", "Charlie", "Delta", "Echo"], + ["1", "2", "3", "4", "5"], + ["Clarksons", "diddly", "farm", "Jeremy", "squat"], + ]); +});