Skip to content

Commit

Permalink
Sort dates with dates-dmy-sort dd/mm/yyyy and dates-mdy-sort mm/dd/yy…
Browse files Browse the repository at this point in the history
…yy (#84)

* WIP 1: sort dates...

* WIP 2: sort dates...; might need separate class for metric and imperial...

* WIP 4 pretty much done need to figure out differentation for US mm/dd/yyyy vs rest of world dd/mm/yyyy.

* date-dmy-sort and date-dmy-sort completed tests written and readme updated
  • Loading branch information
LeeWannacott committed May 11, 2023
1 parent 8a8f0f9 commit b33d3c3
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 24 deletions.
30 changes: 19 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,31 @@ Refer to the documenation for examples on how to use table-sort-js with [HTML](h

#### Classes:

| <table> classes | Description |
| --------------------- | -------------------------------------------------------------------------------------------- |
| "table-sort" | Make the table sortable! (Words, numbers)... |
| "table-arrows" | Display ascending or descending triangles. |
| "no-class-infer" | Turns off inference for adding sort classes automatically (file-size-sort and runtime-sort). |
| "remember-sort" | If clicking on different columns remembers sort of the original column. |
| <table> classes | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------- |
| "table-sort" | Make the table sortable! (Words, numbers, dates, file sizes)... |
| "table-arrows" | Display ascending or descending triangles. |
| "no-class-infer" | Turns off inference for adding sort classes automatically i.e (file-size-sort, runtime-sort, dates-dmy-sort). |
| "remember-sort" | If clicking on different columns remembers sort of the original column. |

| <th> classes | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| "order-by-desc" | Order by descending on first click. (default is aescending) |
| "data-sort" | Sort by [data attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes), e.g <td data-sort="42"> |
| "onload-sort" | Sort column on loading of the page. Simulates a click from the user. (can only sort onload for one column) |
| "file-size-sort" | Sort file sizes(B->TiB) uses the binary prefix. (e.g KiB) |
| "runtime-sort" | Sorts runtime in minutes and seconds e.g (1m 20s). Useful for sorting the GitHub actions Run time column... |
| "disable-sort" | Disallow sorting the table by this specific column. |
| "alpha-sort" | Sort alphabetically (z11,z2); default is [natural sort](https://en.wikipedia.org/wiki/Natural_sort_order) (z2,z11). |
| "punct-sort" | Sort punctuation; default ignores punctuation. |
| "dates-mdy-sort" | Sorts dates in mm/dd/yyyy format. e.g (12/28/2023). Can use "/" or "-" or "." as separator. Overides inferred "dates-dmy-sort" class. |

| <th> Inferred Classes. | Description |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| "dates-dmy-sort" | Sorts dates in dd/mm/yyyy format. e.g (18/10/1995). Can use "/" or "-" or "." as separator. |
| "runtime-sort" | Sorts runtime in hours minutes and seconds e.g (10h 1m 20s). Useful for sorting the GitHub actions Run time column... |
| "file-size-sort" | Sorts file sizes(B->TiB) uses the binary prefix. (e.g KiB). Input data ideally in Bytes e.g (10b or 10B) |

| <th> Classes that change defaults. | Description |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| "order-by-desc" | Order by descending on first click. (default is aescending) |
| "alpha-sort" | Sort alphabetically (z11,z2); default is [natural sort](https://en.wikipedia.org/wiki/Natural_sort_order) (z2,z11). |
| "punct-sort" | Sort punctuation; default ignores punctuation. |

#### Development:

Expand Down
3 changes: 2 additions & 1 deletion deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ cp Contributors.md npm/Contributors.md
npx prettier --write .
npm run deploy
npm run test
echo "Reminder: Update npm package to new version in npm/package.json and npm publish"
echo "Reminder: Update npm package to new version in npm/package.json and npm publish."
echo "Reminder: Update firefox browser extension manifest."
18 changes: 12 additions & 6 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<div id="display"></div>
<script src="../public//table-sort.js"></script>

<h1>Testing table sort js</h1>
<h1>Manual testing of table sort js</h1>
<table class="table-sort table-arrows">
<thead>
<tr>
Expand All @@ -17,43 +17,48 @@ <h1>Testing table sort js</h1>
<th>Department</th>
<th>Runtime</th>
<th class="onload-sort">File Size</th>
<th>dates in dd/mm/yyyy</th>
</tr>
</thead>
<tr>
<td>Franklin</td>
<td>benjamin</td>
<td>Benjamin</td>
<td>1706,1,17</td>
<td></td>
<td>1</td>
<td>k-level</td>
<td>1h 1m 17s</td>
<td>10b</td>
<td>17/6/1978</td>
</tr>
<tr>
<td>da Vinci</td>
<td>Zarlo</td>
<td>1452.4.15</td>
<td></td>
<td>13000</td>
<td></td>
<td>1m 45s</td>
<td>192038998987021b</td>
<td>18/10/2027</td>
</tr>
<tr>
<td>Statham</td>
<td></td>
<td>Jason</td>
<td>1967-7-26</td>
<td></td>
<td>HR</td>
<td>11m 40s</td>
<td>134809b</td>
<td>4/9/2008</td>
</tr>
<tr>
<td>Micheal</td>
<td></td>
<td>Angelo</td>
<td>1958/8/21</td>
<td>54</td>
<td>Marketing</td>
<td>29s</td>
<td>30980980b</td>
<td>2/3/1879</td>
</tr>

<tr>
Expand All @@ -64,6 +69,7 @@ <h1>Testing table sort js</h1>
<td>Marketing</td>
<td>41s</td>
<td>902938402398b</td>
<td>8/6/1978</td>
</tr>
</table>
</body>
Expand Down
81 changes: 76 additions & 5 deletions public/table-sort.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,25 +70,30 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
for (let [columnIndex, th] of tableHeadHeaders.entries()) {
const regexMinutesAndSeconds = /^(\d+h)?\s?(\d+m)?\s?(\d+s)?$/i;
const regexFileSizeSort = /^([.0-9]+)\s?(B|KB|KiB|MB|MiB|GB|GiB|TB|TiB)/i;
const regexDates = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
let runtimeSortCounter = 0,
fileSizeSortCounter = 0;

fileSizeSortCounter = 0,
datesSortCounter = 0;
let tableColumnLength = th.parentElement.childElementCount;
for (let tr of tableRows) {
let runtimeSortMatch, fileSizeSortMatch;
let runtimeSortMatch, fileSizeSortMatch, datesSortMatch;
const tableColumn = tr.querySelectorAll("td").item(columnIndex);
if (tableColumn.innerText) {
runtimeSortMatch = tableColumn.innerText.match(
regexMinutesAndSeconds
);
fileSizeSortMatch = tableColumn.innerText.match(regexFileSizeSort);
datesSortMatch = tableColumn.innerText.match(regexDates);
}
if (runtimeSortMatch) {
runtimeSortCounter++;
}
if (fileSizeSortMatch) {
fileSizeSortCounter++;
}
if (datesSortMatch) {
datesSortCounter++;
}
}
// TODO: refactor this into one function called addInferredClasses that loops over sort classes and counters
addInferredClass(
Expand All @@ -103,6 +108,12 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
fileSizeSortCounter,
"file-size-sort"
);
addInferredClass(
th,
tableColumnLength,
datesSortCounter,
"dates-dmy-sort"
);
}
}

Expand Down Expand Up @@ -190,7 +201,8 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
columnOfTd = tr.querySelectorAll("td").item(columnIndex).innerText;
}
let match = columnOfTd.match(regexMinutesAndSeconds);
let [minutesInSeconds, hours, seconds, timeinSeconds] = [0, 0, 0, 0];
let [minutesInSeconds, hours, seconds] = [0, 0, 0];
let timeinSeconds = columnOfTd;
if (match) {
const regexHours = match[1];
if (regexHours) {
Expand All @@ -214,6 +226,45 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
}
}

function sortDates(dateFormat, tableRows, columnData) {
try {
for (let [i, tr] of tableRows.entries()) {
let columnOfTd;
const regexDate = /^(\d\d?)[./-](\d\d?)[./-]((\d\d)?\d\d)$/;
columnOfTd = tr.querySelectorAll("td").item(columnIndex).textContent;
let match = columnOfTd.match(regexDate);
let [years, days, months] = [0, 0, 0];
let numberToSort = columnOfTd;
if (match) {
const regexFirstNumber = match[1];
const regexSecondNumber = match[2];
const regexYears = match[3];
if (regexFirstNumber && regexSecondNumber) {
if (dateFormat === "mdy") {
days = regexSecondNumber;
months = regexFirstNumber;
} else {
days = regexFirstNumber;
months = regexSecondNumber;
}
}
if (regexYears) {
years = regexYears;
}
numberToSort = Number(
years +
String(months).padStart(2, "0") +
String(days).padStart(2, "0")
);
}
columnData.push(`${numberToSort}#${i}`);
columnIndexAndTableRow[columnData[i]] = tr.innerHTML;
}
} catch (e) {
console.log(e);
}
}

let [timesClickedColumn, columnIndexesClicked] = [0, []];

function rememberSort(timesClickedColumn, columnIndexesClicked) {
Expand Down Expand Up @@ -245,6 +296,8 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
columnData,
isFileSize,
isTimeSort,
isSortDateDayMonthYear,
isSortDateMonthDayYear,
isDataAttribute,
colSpanData,
colSpanSum,
Expand All @@ -264,7 +317,14 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
if (isFileSize) {
fileSizeColumnTextAndRow[columnData[i]] = tr.innerHTML;
}
if (!isFileSize && !isDataAttribute && !isTimeSort) {
// These classes already handle pushing to column and setting the tr html.
if (
!isFileSize &&
!isDataAttribute &&
!isTimeSort &&
!isSortDateDayMonthYear &&
!isSortDateMonthDayYear
) {
columnData.push(`${tdTextContent}#${i}`);
columnIndexAndTableRow[`${tdTextContent}#${i}`] = tr.innerHTML;
}
Expand Down Expand Up @@ -405,6 +465,15 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
sortByRuntime(visibleTableRows, columnData);
}

const isSortDateDayMonthYear = th.classList.contains("dates-dmy-sort");
const isSortDateMonthDayYear = th.classList.contains("dates-mdy-sort");
// pick mdy first to override the inferred default class which is dmy.
if (isSortDateMonthDayYear) {
sortDates("mdy", visibleTableRows, columnData);
} else if (isSortDateDayMonthYear) {
sortDates("dmy", visibleTableRows, columnData);
}

const isRememberSort = sortableTable.classList.contains("remember-sort");
if (!isRememberSort) {
rememberSort(timesClickedColumn, columnIndexesClicked);
Expand All @@ -417,6 +486,8 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
tableRows: visibleTableRows,
columnData,
isFileSize,
isSortDateDayMonthYear,
isSortDateMonthDayYear,
isDataAttribute,
isTimeSort,
colSpanData,
Expand Down
62 changes: 61 additions & 1 deletion test/table.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ test("Clicking multiple times (>2) doesn't break sorting", () => {
});
});

test("time-sort class", () => {
test("runtime-sort", () => {
expect(
createTestTable(
{
Expand Down Expand Up @@ -292,3 +292,63 @@ test("time-sort class", () => {
],
});
});

test("dates-dmy-sort: UK style dd/mm/yyyy; delim . or / or -", () => {
expect(
createTestTable(
{
col0: [
"17/6/1978",
"18.10.2027",
"10-12-2017",
"13/12/2017",
"4.9.2008",
"2.3.1879",
"22.3.1879",
"8/6/1978",
"4/6/1978",
],
},
{ classTags: "dates-dmy-sort" }
)
).toStrictEqual({
col0: [
"2.3.1879",
"22.3.1879",
"4/6/1978",
"8/6/1978",
"17/6/1978",
"4.9.2008",
"10-12-2017",
"13/12/2017",
"18.10.2027",
],
});
});

test("dates-mdy-sort: US style mm/dd/yyyy; delim . or / or -", () => {
expect(
createTestTable(
{
col0: [
"1-14-1992",
"1.13.1992",
"4.30.2008",
"1/20/1992",
"10-12-2017",
"2/14/1992",
],
},
{ classTags: "dates-mdy-sort" }
)
).toStrictEqual({
col0: [
"1.13.1992",
"1-14-1992",
"1/20/1992",
"2/14/1992",
"4.30.2008",
"10-12-2017",
],
});
});

0 comments on commit b33d3c3

Please sign in to comment.