Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort dates with dates-dmy-sort dd/mm/yyyy and dates-mdy-sort mm/dd/yyyy #84

Merged
merged 4 commits into from
May 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,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",
],
});
});