Skip to content

Commit 2e93b27

Browse files
Feature: dates-ymd-sort iso 8061 yyyy/mm/dd sort! :=) (#85)
* Implemented iso 8061 yyyy/mm/dd sort! :=) * Refactor: dateSort to be less verbose. * Remove iso date inference with . delim as could be decimal etc... * Update docs for yyyy/mm/dd ISO date.
1 parent 9bb6870 commit 2e93b27

File tree

4 files changed

+71
-50
lines changed

4 files changed

+71
-50
lines changed

README.md

+14-13
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,23 @@ Refer to the documenation for examples on how to use table-sort-js with [HTML](h
4545
| <table> classes | Description |
4646
| --------------------- | ------------------------------------------------------------------------------------------------------------- |
4747
| "table-sort" | Make the table sortable! (Words, numbers, dates, file sizes)... |
48-
| "table-arrows" | Display ascending or descending triangles. |
4948
| "no-class-infer" | Turns off inference for adding sort classes automatically i.e (file-size-sort, runtime-sort, dates-dmy-sort). |
49+
| "table-arrows" | Display ascending or descending triangles. |
5050
| "remember-sort" | If clicking on different columns remembers sort of the original column. |
5151

52-
| <th> classes | Description |
53-
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
54-
| "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"> |
55-
| "onload-sort" | Sort column on loading of the page. Simulates a click from the user. (can only sort onload for one column) |
56-
| "disable-sort" | Disallow sorting the table by this specific column. |
57-
| "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. |
58-
59-
| <th> Inferred Classes. | Description |
60-
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------- |
61-
| "dates-dmy-sort" | Sorts dates in dd/mm/yyyy format. e.g (18/10/1995). Can use "/" or "-" or "." as separator. |
62-
| "runtime-sort" | Sorts runtime in hours minutes and seconds e.g (10h 1m 20s). Useful for sorting the GitHub actions Run time column... |
63-
| "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) |
52+
| <th> classes | Description |
53+
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
54+
| "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"> |
55+
| "dates-mdy-sort" | Sorts dates in US style mm/dd/yyyy format;. e.g (12/28/2023). Can use "/" or "-" as separator. Overides inferred "dates-dmy-sort" class. |
56+
| "onload-sort" | Sort column on loading of the page. Simulates a click from the user. (can only sort onload for one column) |
57+
| "disable-sort" | Disallow sorting the table by this specific column. |
58+
59+
| <th> Inferred Classes. | Description |
60+
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
61+
| "dates-dmy-sort" | Sorts dates in dd/mm/yyyy format. e.g (18/10/1995). Can use "/" or "-" as separator. |
62+
| "dates-ymd-sort" | Sorts dates in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) yyyy/mm/dd format. e.g (2021/10/28). Use "/" or "-" as separator. |
63+
| "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) |
64+
| "runtime-sort" | Sorts runtime in hours minutes and seconds e.g (10h 1m 20s). Useful for sorting the GitHub actions Run time column... |
6465

6566
| <th> Classes that change defaults. | Description |
6667
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |

public/index.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ <h1>Manual testing of table sort js</h1>
2323
<tr>
2424
<td>Franklin</td>
2525
<td>Benjamin</td>
26-
<td>1706,1,17</td>
26+
<td>1706/1/17</td>
2727
<td>1</td>
2828
<td>k-level</td>
2929
<td>1h 1m 17s</td>
@@ -33,7 +33,7 @@ <h1>Manual testing of table sort js</h1>
3333
<tr>
3434
<td>da Vinci</td>
3535
<td>Zarlo</td>
36-
<td>1452.4.15</td>
36+
<td>1452-4-15</td>
3737
<td>13000</td>
3838
<td></td>
3939
<td>1m 45s</td>

public/table-sort.js

+42-35
Original file line numberDiff line numberDiff line change
@@ -71,49 +71,51 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
7171
const regexMinutesAndSeconds = /^(\d+h)?\s?(\d+m)?\s?(\d+s)?$/i;
7272
const regexFileSizeSort = /^([.0-9]+)\s?(B|KB|KiB|MB|MiB|GB|GiB|TB|TiB)/i;
7373
// Doesn't infer dates with delimiter "."; as could capture semantic version numbers.
74-
const regexDates = /^(\d\d?)[/-](\d\d?)[/-]((\d\d)?\d\d)$/;
75-
let runtimeSortCounter = 0,
76-
fileSizeSortCounter = 0,
77-
datesSortCounter = 0;
74+
const datesRegex = /^(\d\d?)[/-](\d\d?)[/-]((\d\d)?\d\d)/;
75+
const regexISODates = /^(\d\d\d\d)[/-](\d\d?)[/-](\d\d?)/;
76+
let runtimeCounter = 0,
77+
fileSizeCounter = 0,
78+
datesCounter = 0,
79+
isoDatesCounter = 0;
7880
let tableColumnLength = th.parentElement.childElementCount;
7981
for (let tr of tableRows) {
80-
let runtimeSortMatch, fileSizeSortMatch, datesSortMatch;
82+
let runtimeSortMatch, fileSizeSortMatch, datesMatch, isoDatesMatch;
8183
const tableColumn = tr.querySelectorAll("td").item(columnIndex);
8284
if (tableColumn.innerText) {
8385
runtimeSortMatch = tableColumn.innerText.match(
8486
regexMinutesAndSeconds
8587
);
8688
fileSizeSortMatch = tableColumn.innerText.match(regexFileSizeSort);
87-
datesSortMatch = tableColumn.innerText.match(regexDates);
89+
datesMatch = tableColumn.innerText.match(datesRegex);
90+
isoDatesMatch = tableColumn.innerText.match(regexISODates);
8891
}
8992
if (runtimeSortMatch) {
90-
runtimeSortCounter++;
93+
runtimeCounter++;
9194
}
9295
if (fileSizeSortMatch) {
93-
fileSizeSortCounter++;
96+
fileSizeCounter++;
9497
}
95-
if (datesSortMatch) {
96-
datesSortCounter++;
98+
if (datesMatch) {
99+
datesCounter++;
100+
}
101+
if (isoDatesMatch) {
102+
isoDatesCounter++;
97103
}
98104
}
99105
// TODO: refactor this into one function called addInferredClasses that loops over sort classes and counters
106+
addInferredClass(th, tableColumnLength, runtimeCounter, "runtime-sort");
100107
addInferredClass(
101108
th,
102109
tableColumnLength,
103-
runtimeSortCounter,
104-
"runtime-sort"
105-
);
106-
addInferredClass(
107-
th,
108-
tableColumnLength,
109-
fileSizeSortCounter,
110+
fileSizeCounter,
110111
"file-size-sort"
111112
);
113+
addInferredClass(th, tableColumnLength, datesCounter, "dates-dmy-sort");
112114
addInferredClass(
113115
th,
114116
tableColumnLength,
115-
datesSortCounter,
116-
"dates-dmy-sort"
117+
isoDatesCounter,
118+
"dates-ymd-sort"
117119
);
118120
}
119121
}
@@ -227,31 +229,30 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
227229
}
228230
}
229231

230-
function sortDates(dateFormat, tableRows, columnData) {
232+
function sortDates(datesFormat, tableRows, columnData) {
231233
try {
232234
for (let [i, tr] of tableRows.entries()) {
233-
let columnOfTd;
234-
const regexDates = /^(\d\d?)[./-](\d\d?)[./-]((\d\d)?\d\d)$/;
235+
let columnOfTd, datesRegex;
236+
if (datesFormat === "mdy" || datesFormat === "dmy") {
237+
datesRegex = /^(\d\d?)[./-](\d\d?)[./-]((\d\d)?\d\d)/;
238+
} else if (datesFormat === "ymd") {
239+
datesRegex = /^(\d\d\d\d)[./-](\d\d?)[./-](\d\d?)/;
240+
}
235241
columnOfTd = tr.querySelectorAll("td").item(columnIndex).textContent;
236-
let match = columnOfTd.match(regexDates);
242+
let match = columnOfTd.match(datesRegex);
237243
let [years, days, months] = [0, 0, 0];
238244
let numberToSort = columnOfTd;
239245
if (match) {
240-
const regexFirstNumber = match[1];
241-
const regexSecondNumber = match[2];
242-
const regexYears = match[3];
243-
if (regexFirstNumber && regexSecondNumber) {
244-
if (dateFormat === "mdy") {
245-
days = regexSecondNumber;
246-
months = regexFirstNumber;
246+
const [regPos1, regPos2, regPos3] = [match[1], match[2], match[3]];
247+
if (regPos1 && regPos2 && regPos3) {
248+
if (datesFormat === "mdy") {
249+
[months, days, years] = [regPos1, regPos2, regPos3];
250+
} else if (datesFormat === "ymd") {
251+
[years, months, days] = [regPos1, regPos2, regPos3];
247252
} else {
248-
days = regexFirstNumber;
249-
months = regexSecondNumber;
253+
[days, months, years] = [regPos1, regPos2, regPos3];
250254
}
251255
}
252-
if (regexYears) {
253-
years = regexYears;
254-
}
255256
numberToSort = Number(
256257
years +
257258
String(months).padStart(2, "0") +
@@ -299,6 +300,7 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
299300
isTimeSort,
300301
isSortDateDayMonthYear,
301302
isSortDateMonthDayYear,
303+
isSortDateYearMonthDay,
302304
isDataAttribute,
303305
colSpanData,
304306
colSpanSum,
@@ -324,6 +326,7 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
324326
!isDataAttribute &&
325327
!isTimeSort &&
326328
!isSortDateDayMonthYear &&
329+
!isSortDateYearMonthDay &&
327330
!isSortDateMonthDayYear
328331
) {
329332
columnData.push(`${tdTextContent}#${i}`);
@@ -468,9 +471,12 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
468471

469472
const isSortDateDayMonthYear = th.classList.contains("dates-dmy-sort");
470473
const isSortDateMonthDayYear = th.classList.contains("dates-mdy-sort");
474+
const isSortDateYearMonthDay = th.classList.contains("dates-ymd-sort");
471475
// pick mdy first to override the inferred default class which is dmy.
472476
if (isSortDateMonthDayYear) {
473477
sortDates("mdy", visibleTableRows, columnData);
478+
} else if (isSortDateYearMonthDay) {
479+
sortDates("ymd", visibleTableRows, columnData);
474480
} else if (isSortDateDayMonthYear) {
475481
sortDates("dmy", visibleTableRows, columnData);
476482
}
@@ -489,6 +495,7 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
489495
isFileSize,
490496
isSortDateDayMonthYear,
491497
isSortDateMonthDayYear,
498+
isSortDateYearMonthDay,
492499
isDataAttribute,
493500
isTimeSort,
494501
colSpanData,

test/table.test.js

+13
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,16 @@ test("dates-mdy-sort: US style mm/dd/yyyy; delim . or / or -", () => {
352352
],
353353
});
354354
});
355+
356+
test("dates-ymd-sort: ISO 8601 style yyyy/mm/dd; delim . or / or -", () => {
357+
expect(
358+
createTestTable(
359+
{
360+
col0: ["2023/09/6", "2023-03-9", "2023.12.16", "2023/4/6", "2023/4/32"],
361+
},
362+
{ classTags: "dates-ymd-sort" }
363+
)
364+
).toStrictEqual({
365+
col0: ["2023-03-9", "2023/4/6", "2023/4/32", "2023/09/6", "2023.12.16"],
366+
});
367+
});

0 commit comments

Comments
 (0)