New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

table-sort-js

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

table-sort-js - npm Package Compare versions

Comparing version 1.16.0 to 1.17.0

2

package.json
{
"name": "table-sort-js",
"version": "1.16.0",
"version": "1.17.0",
"description": "A JavaScript client-side HTML table sorting library with no dependencies required.",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -6,2 +6,3 @@ ![npm version](https://img.shields.io/npm/v/table-sort-js)

![MIT licence](https://img.shields.io/github/license/LeeWannacott/table-sort-js)
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
![build status](https://img.shields.io/github/actions/workflow/status/leewannacott/table-sort-js/jest.yml?branch=master)

@@ -21,36 +22,28 @@

- <b>Option 1:</b> Install from npm:
- <b>Option 1</b>: Load as script from a Content Delivery Network (CDN):
```javascript
npm install table-sort-js
<script src="https://cdn.jsdelivr.net/npm/table-sort-js/table-sort.js"></script>
```
Or Minified (smaller size, but harder to debug!):
```javascript
import tableSort from "table-sort-js/table-sort.js";
<script src="https://cdn.jsdelivr.net/npm/table-sort-js/table-sort.min.js"></script>
```
Examples on using table-sort-js with frontend frameworks such as [React.js](https://leewannacott.github.io/table-sort-js/docs/react.html) and [Vue.js](https://leewannacott.github.io/table-sort-js/docs/vue.html)
Example on how to use table-sort-js with [HTML](https://leewannacott.github.io/table-sort-js/docs/html5.html)
- <b>Option 2</b>: Load as script from a Content Delivery Network (CDN):
- <b>Option 2:</b> Install from npm:
```javascript
<script src="https://cdn.jsdelivr.net/npm/table-sort-js@latest/table-sort.js"></script>
npm install table-sort-js
```
Or Minified (smaller size, but harder to debug!):
```javascript
<script src="https://cdn.jsdelivr.net/npm/table-sort-js@latest/table-sort.min.js"></script>
import tableSort from "table-sort-js/table-sort.js";
```
Refer to the documenation for examples on how to use table-sort-js with [HTML](https://leewannacott.github.io/table-sort-js/docs/html5.html)
Examples on using table-sort-js with frontend frameworks such as [React.js](https://leewannacott.github.io/table-sort-js/docs/react.html) and [Vue.js](https://leewannacott.github.io/table-sort-js/docs/vue.html)
- <b>Option 3:</b> Download [table-sort.js](https://cdn.jsdelivr.net/npm/table-sort-js@latest/table-sort.js) (Select save as.), or download a [minified version](https://cdn.jsdelivr.net/npm/table-sort-js@latest/table-sort.min.js) (~5kB)
Then rename and add the following script before your HTML table:
```html
<script src="table-sort.js"></script>
```
## To make tables sortable:

@@ -69,2 +62,3 @@

| "remember-sort" | If clicking on different columns remembers sort of the original column. |
| "cells-sort" | sort cells (td) rather than table rows (tr); useful for keeping table rows with classes/attributes in place. |

@@ -71,0 +65,0 @@ <br>

@@ -31,3 +31,2 @@ /*

const columnIndexAndTableRow = {};
const fileSizeColumnTextAndRow = {};
for (let table of getTagTable) {

@@ -50,12 +49,14 @@ if (table.classList.contains("table-sort")) {

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 {
return sortableTable.querySelector("tbody");
// if <tr> or <td> exists below <thead> the browser will make <tbody>
return sortableTable.querySelectorAll("tbody");
}

@@ -113,26 +114,42 @@ }

const table = {
body: getTableBody(sortableTable),
head: sortableTable.querySelector("thead"),
bodies: getTableBodies(sortableTable),
theads: sortableTable.querySelectorAll("thead"),
rows: [],
headers: [],
};
table.headers = table.head.querySelectorAll("th");
table.rows = table.body.querySelectorAll("tr");
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"));
}
let columnIndexesClicked = [];
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"),
};
const isNoSortClassInference =
sortableTable.classList.contains("no-class-infer");
for (let [columnIndex, th] of table.headers.entries()) {
if (!th.classList.contains("disable-sort")) {
th.style.cursor = "pointer";
if (!isNoSortClassInference) {
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,
sortableTable,
columnIndexesClicked
);
}

@@ -142,347 +159,396 @@ }

function makeEachColumnSortable(
th,
columnIndex,
table,
sortableTable,
columnIndexesClicked
) {
const desc = th.classList.contains("order-by-desc");
const tableArrows = sortableTable.classList.contains("table-arrows");
const [arrowUp, arrowDown] = [" ▲", " ▼"];
const fillValue = "!X!Y!Z!";
function cellsOrRows(table, tr) {
if (table.hasClass.cellsSort) {
return tr.innerHTML;
} else {
return tr.outerHTML;
}
}
if (desc && tableArrows) {
th.insertAdjacentText("beforeend", arrowDown);
} else if (tableArrows) {
th.insertAdjacentText("beforeend", arrowUp);
function sortDataAttributes(table, column) {
for (let [i, tr] of table.visibleRows.entries()) {
let dataAttributeTd = column.getColumn(tr, column.spanSum, column.span)
.dataset.sort;
column.toBeSorted.push(`${dataAttributeTd}#${i}`);
columnIndexAndTableRow[column.toBeSorted[i]] = cellsOrRows(table, tr);
}
}
function sortDataAttributes(tableRows, column) {
for (let [i, tr] of tableRows.entries()) {
let dataAttributeTd = getColumn(tr, column.spanSum, column.span).dataset
.sort;
column.toBeSorted.push(`${dataAttributeTd}#${i}`);
columnIndexAndTableRow[column.toBeSorted[i]] = tr.outerHTML;
function sortFileSize(table, column, columnIndex) {
let unitToMultiplier = {
b: 1,
kb: 1000,
kib: 2 ** 10,
mb: 1e6,
mib: 2 ** 20,
gb: 1e9,
gib: 2 ** 30,
tb: 1e12,
tib: 2 ** 40,
};
const numberWithUnitType = /([.0-9]+)\s?(B|KB|KiB|MB|MiB|GB|GiB|TB|TiB)/i;
for (let [i, tr] of table.visibleRows.entries()) {
let fileSizeTd = tr.querySelectorAll("td").item(columnIndex).textContent;
let match = fileSizeTd.match(numberWithUnitType);
if (match) {
let number = parseFloat(match[1]);
let unit = match[2].toLowerCase();
let multiplier = unitToMultiplier[unit];
column.toBeSorted.push(`${number * multiplier}#${i}`);
columnIndexAndTableRow[column.toBeSorted[i]] = cellsOrRows(table, tr);
}
}
}
function sortFileSize(tableRows, column) {
let unitToMultiplier = {
b: 1,
kb: 1000,
kib: 2 ** 10,
mb: 1e6,
mib: 2 ** 20,
gb: 1e9,
gib: 2 ** 30,
tb: 1e12,
tib: 2 ** 40,
};
const numberWithUnitType = /([.0-9]+)\s?(B|KB|KiB|MB|MiB|GB|GiB|TB|TiB)/i;
for (let [i, tr] of tableRows.entries()) {
let fileSizeTd = tr
.querySelectorAll("td")
.item(columnIndex).textContent;
let match = fileSizeTd.match(numberWithUnitType);
function sortDates(datesFormat, table, column) {
try {
for (let [i, tr] of table.visibleRows.entries()) {
let columnOfTd, datesRegex;
if (datesFormat === "mdy" || datesFormat === "dmy") {
datesRegex = /^(\d\d?)[./-](\d\d?)[./-]((\d\d)?\d\d)/;
} else if (datesFormat === "ymd") {
datesRegex = /^(\d\d\d\d)[./-](\d\d?)[./-](\d\d?)/;
}
columnOfTd = column.getColumn(
tr,
column.spanSum,
column.span
).textContent;
let match = columnOfTd.match(datesRegex);
let [years, days, months] = [0, 0, 0];
let numberToSort = columnOfTd;
if (match) {
let number = parseFloat(match[1]);
let unit = match[2].toLowerCase();
let multiplier = unitToMultiplier[unit];
column.toBeSorted.push(`${number * multiplier}#${i}`);
} else {
column.toBeSorted.push(`${fillValue}#${i}`);
}
}
}
function sortByRuntime(tableRows, column) {
try {
for (let [i, tr] of tableRows.entries()) {
const regexMinutesAndSeconds = /^(\d+h)?\s?(\d+m)?\s?(\d+s)?$/i;
let columnOfTd = "";
// TODO: github actions runtime didn't like textContent, tests didn't like innerText?
if (testingTableSortJS) {
columnOfTd = getColumn(tr, column.spanSum, column.span).textContent;
} else {
columnOfTd = getColumn(tr, column.spanSum, column.span).innerText;
}
let match = columnOfTd.match(regexMinutesAndSeconds);
let [minutesInSeconds, hours, seconds] = [0, 0, 0];
let timeinSeconds = columnOfTd;
if (match) {
const regexHours = match[1];
if (regexHours) {
hours = Number(regexHours.replace("h", "")) * 60 * 60;
const [regPos1, regPos2, regPos3] = [match[1], match[2], match[3]];
if (regPos1 && regPos2 && regPos3) {
if (datesFormat === "mdy") {
[months, days, years] = [regPos1, regPos2, regPos3];
} else if (datesFormat === "ymd") {
[years, months, days] = [regPos1, regPos2, regPos3];
} else {
[days, months, years] = [regPos1, regPos2, regPos3];
}
const regexMinutes = match[2];
if (regexMinutes) {
minutesInSeconds = Number(regexMinutes.replace("m", "")) * 60;
}
const regexSeconds = match[3];
if (regexSeconds) {
seconds = Number(regexSeconds.replace("s", ""));
}
timeinSeconds = hours + minutesInSeconds + seconds;
}
column.toBeSorted.push(`${timeinSeconds}#${i}`);
columnIndexAndTableRow[column.toBeSorted[i]] = tr.outerHTML;
numberToSort = Number(
years +
String(months).padStart(2, "0") +
String(days).padStart(2, "0")
);
}
} catch (e) {
console.log(e);
column.toBeSorted.push(`${numberToSort}#${i}`);
columnIndexAndTableRow[column.toBeSorted[i]] = cellsOrRows(table, tr);
}
} catch (e) {
console.log(e);
}
}
function sortDates(datesFormat, tableRows, column) {
try {
for (let [i, tr] of tableRows.entries()) {
let columnOfTd, datesRegex;
if (datesFormat === "mdy" || datesFormat === "dmy") {
datesRegex = /^(\d\d?)[./-](\d\d?)[./-]((\d\d)?\d\d)/;
} else if (datesFormat === "ymd") {
datesRegex = /^(\d\d\d\d)[./-](\d\d?)[./-](\d\d?)/;
function sortByRuntime(table, column) {
try {
for (let [i, tr] of table.visibleRows.entries()) {
const regexMinutesAndSeconds = /^(\d+h)?\s?(\d+m)?\s?(\d+s)?$/i;
let columnOfTd = "";
// TODO: github actions runtime didn't like textContent, tests didn't like innerText?
if (testingTableSortJS) {
columnOfTd = column.getColumn(
tr,
column.spanSum,
column.span
).textContent;
} else {
columnOfTd = column.getColumn(
tr,
column.spanSum,
column.span
).innerText;
}
let match = columnOfTd.match(regexMinutesAndSeconds);
let [minutesInSeconds, hours, seconds] = [0, 0, 0];
let timeinSeconds = columnOfTd;
if (match) {
const regexHours = match[1];
if (regexHours) {
hours = Number(regexHours.replace("h", "")) * 60 * 60;
}
columnOfTd = getColumn(tr, column.spanSum, column.span).textContent;
let match = columnOfTd.match(datesRegex);
let [years, days, months] = [0, 0, 0];
let numberToSort = columnOfTd;
if (match) {
const [regPos1, regPos2, regPos3] = [match[1], match[2], match[3]];
if (regPos1 && regPos2 && regPos3) {
if (datesFormat === "mdy") {
[months, days, years] = [regPos1, regPos2, regPos3];
} else if (datesFormat === "ymd") {
[years, months, days] = [regPos1, regPos2, regPos3];
} else {
[days, months, years] = [regPos1, regPos2, regPos3];
}
}
numberToSort = Number(
years +
String(months).padStart(2, "0") +
String(days).padStart(2, "0")
);
const regexMinutes = match[2];
if (regexMinutes) {
minutesInSeconds = Number(regexMinutes.replace("m", "")) * 60;
}
column.toBeSorted.push(`${numberToSort}#${i}`);
columnIndexAndTableRow[column.toBeSorted[i]] = tr.outerHTML;
const regexSeconds = match[3];
if (regexSeconds) {
seconds = Number(regexSeconds.replace("s", ""));
}
timeinSeconds = hours + minutesInSeconds + seconds;
}
} catch (e) {
console.log(e);
column.toBeSorted.push(`${timeinSeconds}#${i}`);
columnIndexAndTableRow[column.toBeSorted[i]] = cellsOrRows(table, tr);
}
} catch (e) {
console.log(e);
}
}
function rememberSort() {
// if user clicked different column from first column reset times clicked.
columnIndexesClicked.push(columnIndex);
if (timesClickedColumn === 1 && columnIndexesClicked.length > 1) {
const lastColumnClicked =
columnIndexesClicked[columnIndexesClicked.length - 1];
const secondLastColumnClicked =
columnIndexesClicked[columnIndexesClicked.length - 2];
if (lastColumnClicked !== secondLastColumnClicked) {
columnIndexesClicked.shift();
timesClickedColumn = 0;
function getTableData(tableProperties, timesClickedColumn) {
const {
table,
tableRows,
fillValue,
column,
th,
hasThClass,
isSortDates,
desc,
arrow,
} = tableProperties;
for (let [i, tr] of tableRows.entries()) {
let tdTextContent = column.getColumn(
tr,
column.spanSum,
column.span
).textContent;
if (tdTextContent.length === 0) {
tdTextContent = "";
}
if (tdTextContent.trim() !== "") {
if (
!hasThClass.fileSize &&
!hasThClass.dataSort &&
!hasThClass.runtime &&
!hasThClass.filesize &&
!isSortDates.dayMonthYear &&
!isSortDates.yearMonthDay &&
!isSortDates.monthDayYear
) {
column.toBeSorted.push(`${tdTextContent}#${i}`);
columnIndexAndTableRow[`${tdTextContent}#${i}`] = cellsOrRows(
table,
tr
);
}
} else {
// Fill in blank table cells dict key with filler value.
column.toBeSorted.push(`${fillValue}#${i}`);
columnIndexAndTableRow[`${fillValue}#${i}`] = cellsOrRows(table, tr);
}
return timesClickedColumn;
}
function getColSpanData(headers, column) {
headers.forEach((th, index) => {
column.span[index] = th.colSpan;
if (index === 0) column.spanSum[index] = th.colSpan;
else column.spanSum[index] = column.spanSum[index - 1] + th.colSpan;
});
const isPunctSort = th.classList.contains("punct-sort");
const isAlphaSort = th.classList.contains("alpha-sort");
const isNumericSort = th.classList.contains("numeric-sort");
function parseNumberFromString(str) {
let num;
str = str.slice(0, str.indexOf("#"));
if (str.match(/^\((\d+(?:\.\d+)?)\)$/)) {
num = -1 * Number(str.slice(1, -1));
} else {
num = Number(str);
}
return num;
}
function getColumn(tr, colSpanSum, colSpanData) {
return tr
.querySelectorAll("td")
.item(
colSpanData[columnIndex] === 1
? colSpanSum[columnIndex] - 1
: colSpanSum[columnIndex] - colSpanData[columnIndex]
);
function strLocaleCompare(str1, str2) {
return str1.localeCompare(
str2,
navigator.languages[0] || navigator.language,
{ numeric: !isAlphaSort, ignorePunctuation: !isPunctSort }
);
}
function getTableData(tableProperties) {
const { tableRows, column, hasThClass, isSortDates } = tableProperties;
for (let [i, tr] of tableRows.entries()) {
let tdTextContent = getColumn(
tr,
column.spanSum,
column.span
).textContent;
if (tdTextContent.length === 0) {
tdTextContent = "";
}
if (tdTextContent.trim() !== "") {
if (hasThClass.fileSize) {
fileSizeColumnTextAndRow[column.toBeSorted[i]] = tr.outerHTML;
}
// These classes already handle pushing to column and setting the tr html.
if (
!hasThClass.fileSize &&
!hasThClass.dataSort &&
!hasThClass.runtime &&
!isSortDates.dayMonthYear &&
!isSortDates.yearMonthDay &&
!isSortDates.monthDayYear
) {
column.toBeSorted.push(`${tdTextContent}#${i}`);
columnIndexAndTableRow[`${tdTextContent}#${i}`] = tr.outerHTML;
}
} else {
// Fill in blank table cells dict key with filler value.
column.toBeSorted.push(`${fillValue}#${i}`);
columnIndexAndTableRow[`${fillValue}#${i}`] = tr.outerHTML;
}
}
function handleNumbers(str1, str2) {
let num1, num2;
num1 = parseNumberFromString(str1);
num2 = parseNumberFromString(str2);
const isPunctSort = th.classList.contains("punct-sort");
const isAlphaSort = th.classList.contains("alpha-sort");
const isNumericSort = th.classList.contains("numeric-sort");
function parseNumberFromString(str) {
let num;
str = str.slice(0, str.indexOf("#"));
if (str.match(/^\((\d+(?:\.\d+)?)\)$/)) {
num = -1 * Number(str.slice(1, -1));
} else {
num = Number(str);
}
return num;
if (!isNaN(num1) && !isNaN(num2)) {
return num1 - num2;
} else {
return strLocaleCompare(str1, str2);
}
}
function strLocaleCompare(str1, str2) {
return str1.localeCompare(
str2,
navigator.languages[0] || navigator.language,
{ numeric: !isAlphaSort, ignorePunctuation: !isPunctSort }
);
function sortAscending(a, b) {
if (a.includes(`${fillValue}#`)) {
return 1;
} else if (b.includes(`${fillValue}#`)) {
return -1;
} else if (isNumericSort) {
return handleNumbers(a, b);
} else {
return strLocaleCompare(a, b);
}
}
function handleNumbers(str1, str2) {
let num1, num2;
num1 = parseNumberFromString(str1);
num2 = parseNumberFromString(str2);
function sortDescending(a, b) {
return sortAscending(b, a);
}
if (!isNaN(num1) && !isNaN(num2)) {
return num1 - num2;
} else {
return strLocaleCompare(str1, str2);
}
}
function clearArrows(arrowUp = "▲", arrowDown = "▼") {
th.innerHTML = th.innerHTML.replace(arrowUp, "");
th.innerHTML = th.innerHTML.replace(arrowDown, "");
}
function sortAscending(a, b) {
if (a.includes(`${fillValue}#`)) {
return 1;
} else if (b.includes(`${fillValue}#`)) {
return -1;
} else if (isNumericSort) {
return handleNumbers(a, b);
} else {
return strLocaleCompare(a, b);
}
}
if (column.toBeSorted[0] === undefined) {
return;
}
function sortDescending(a, b) {
return sortAscending(b, a);
function changeTableArrow(arrowDirection) {
if (table.hasClass.tableArrows) {
clearArrows(arrow.up, arrow.down);
th.insertAdjacentText("beforeend", arrowDirection);
}
}
function clearArrows(arrowUp = "▲", arrowDown = "▼") {
th.innerHTML = th.innerHTML.replace(arrowUp, "");
th.innerHTML = th.innerHTML.replace(arrowDown, "");
}
function sortColumn(sortDirection) {
column.toBeSorted.sort(sortDirection, {
numeric: !isAlphaSort,
ignorePunctuation: !isPunctSort,
});
}
if (column.toBeSorted[0] === undefined) {
return;
if (timesClickedColumn === 1) {
if (desc) {
changeTableArrow(arrow.down);
sortColumn(sortDescending);
} else {
changeTableArrow(arrow.up);
sortColumn(sortAscending);
}
function changeTableArrow(arrowDirection) {
if (tableArrows) {
clearArrows(arrowUp, arrowDown);
th.insertAdjacentText("beforeend", arrowDirection);
}
} else if (timesClickedColumn === 2) {
timesClickedColumn = 0;
if (desc) {
changeTableArrow(arrow.up);
sortColumn(sortAscending);
} else {
changeTableArrow(arrow.down);
sortColumn(sortDescending);
}
}
return timesClickedColumn;
}
function sortColumn(sortDirection) {
column.toBeSorted.sort(sortDirection, {
numeric: !isAlphaSort,
ignorePunctuation: !isPunctSort,
});
function updateFilesize(i, table, tr, column, columnIndex) {
if (table.hasClass.cellsSort) {
tr.innerHTML = columnIndexAndTableRow[column.toBeSorted[i]];
} else {
// We do this to sort rows rather than cells:
const template = document.createElement("template");
template.innerHTML = columnIndexAndTableRow[column.toBeSorted[i]];
tr = template.content.firstChild;
}
let fileSizeInBytesHTML = column.getColumn(
tr,
column.spanSum,
column.span
).outerHTML;
const fileSizeInBytesText = column.getColumn(
tr,
column.spanSum,
column.span
).textContent;
const fileSize = column.toBeSorted[i].replace(/#[0-9]*/, "");
let prefixes = ["", "Ki", "Mi", "Gi", "Ti", "Pi"];
let replaced = false;
for (let i = 0; i < prefixes.length; ++i) {
let nextPrefixMultiplier = 2 ** (10 * (i + 1));
if (fileSize < nextPrefixMultiplier) {
let prefixMultiplier = 2 ** (10 * i);
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
fileSizeInBytesText,
`${(fileSize / prefixMultiplier).toFixed(2)} ${prefixes[i]}B`
);
replaced = true;
break;
}
}
if (!replaced) {
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
fileSizeInBytesText,
"NaN"
);
}
tr.querySelectorAll("td").item(columnIndex).innerHTML = fileSizeInBytesHTML;
return table.hasClass.cellsSort ? tr.innerHTML : tr.outerHTML;
}
if (timesClickedColumn === 1) {
if (desc) {
changeTableArrow(arrowDown);
sortColumn(sortDescending);
function updateTable(tableProperties) {
const { column, table, columnIndex, hasThClass } = tableProperties;
for (let [i, tr] of table.visibleRows.entries()) {
if (hasThClass.fileSize) {
if (table.hasClass.cellsSort) {
tr.innerHTML = updateFilesize(i, table, tr, column, columnIndex);
} else {
changeTableArrow(arrowUp);
sortColumn(sortAscending);
tr.outerHTML = updateFilesize(i, table, tr, column, columnIndex);
}
} else if (timesClickedColumn === 2) {
timesClickedColumn = 0;
if (desc) {
changeTableArrow(arrowUp);
sortColumn(sortAscending);
} else if (!hasThClass.fileSize) {
if (table.hasClass.cellsSort) {
tr.innerHTML = columnIndexAndTableRow[column.toBeSorted[i]];
} else {
changeTableArrow(arrowDown);
sortColumn(sortDescending);
tr.outerHTML = columnIndexAndTableRow[column.toBeSorted[i]];
}
}
}
}
function updateTable(tableProperties) {
const { tableRows, column, hasThClass } = tableProperties;
for (let [i, tr] of tableRows.entries()) {
if (hasThClass.fileSize) {
tr.innerHTML = fileSizeColumnTextAndRow[column.toBeSorted[i]];
let fileSizeInBytesHTML = tr
.querySelectorAll("td")
.item(columnIndex).innerHTML;
const fileSizeInBytesText = tr
.querySelectorAll("td")
.item(columnIndex).textContent;
// Remove the unique identifyer for duplicate values(#number).
column.toBeSorted[i] = column.toBeSorted[i].replace(/#[0-9]*/, "");
const fileSize = parseFloat(column.toBeSorted[i]);
let prefixes = ["", "Ki", "Mi", "Gi", "Ti", "Pi"];
let replaced = false;
for (let i = 0; i < prefixes.length; ++i) {
let nextPrefixMultiplier = 2 ** (10 * (i + 1));
if (fileSize < nextPrefixMultiplier) {
let prefixMultiplier = 2 ** (10 * i);
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
fileSizeInBytesText,
`${(fileSize / prefixMultiplier).toFixed(2)} ${prefixes[i]}B`
);
replaced = true;
break;
}
}
if (!replaced) {
fileSizeInBytesHTML = fileSizeInBytesHTML.replace(
fileSizeInBytesText,
"NaN"
);
}
tr.querySelectorAll("td").item(columnIndex).innerHTML =
fileSizeInBytesHTML;
} else if (!hasThClass.fileSize) {
tr.outerHTML = columnIndexAndTableRow[column.toBeSorted[i]];
}
function getColSpanData(headers, column) {
headers.forEach((th, index) => {
column.span[index] = th.colSpan;
if (index === 0) column.spanSum[index] = th.colSpan;
else column.spanSum[index] = column.spanSum[index - 1] + th.colSpan;
});
}
function rememberSort(columnIndexesClicked, timesClickedColumn, columnIndex) {
// if user clicked different column from first column reset times clicked.
columnIndexesClicked.push(columnIndex);
if (timesClickedColumn === 1 && columnIndexesClicked.length > 1) {
const lastColumnClicked =
columnIndexesClicked[columnIndexesClicked.length - 1];
const secondLastColumnClicked =
columnIndexesClicked[columnIndexesClicked.length - 2];
if (lastColumnClicked !== secondLastColumnClicked) {
columnIndexesClicked.shift();
timesClickedColumn = 0;
}
}
return timesClickedColumn;
}
function makeEachColumnSortable(
th,
headerIndex,
columnIndex,
table,
columnIndexesClicked
) {
const desc = th.classList.contains("order-by-desc");
const arrow = { up: " ▲", down: " ▼" };
const fillValue = "!X!Y!Z!";
if (desc && table.hasClass.tableArrows) {
th.insertAdjacentText("beforeend", arrow.down);
} else if (table.hasClass.tableArrows) {
th.insertAdjacentText("beforeend", arrow.up);
}
let timesClickedColumn = 0;
const column = {
getColumn: function getColumn(tr, colSpanSum, colSpanData) {
return tr
.querySelectorAll("td")
.item(
colSpanData[columnIndex] === 1
? colSpanSum[columnIndex] - 1
: colSpanSum[columnIndex] - colSpanData[columnIndex]
);
},
};
th.addEventListener("click", function () {
const column = {
toBeSorted: [],
span: {},
spanSum: {},
};
column.toBeSorted = [];
column.span = {};
column.spanSum = {};
getColSpanData(table.headers[headerIndex], column);
table.visibleRows = Array.prototype.filter.call(
table.body.querySelectorAll("tr"),
table.bodies.item(headerIndex).querySelectorAll("tr"),
(tr) => {

@@ -493,7 +559,8 @@ return tr.style.display !== "none";

getColSpanData(table.headers, column);
const isRememberSort = sortableTable.classList.contains("remember-sort");
if (!isRememberSort) {
timesClickedColumn = rememberSort();
if (!table.hasClass.rememberSort) {
timesClickedColumn = rememberSort(
columnIndexesClicked,
timesClickedColumn,
columnIndex
);
}

@@ -509,9 +576,9 @@ timesClickedColumn += 1;

if (hasThClass.dataSort) {
sortDataAttributes(table.visibleRows, column);
sortDataAttributes(table, column);
}
if (hasThClass.fileSize) {
sortFileSize(table.visibleRows, column);
sortFileSize(table, column, columnIndex, fillValue);
}
if (hasThClass.runtime) {
sortByRuntime(table.visibleRows, column);
sortByRuntime(table, column);
}

@@ -526,16 +593,23 @@

if (isSortDates.monthDayYear) {
sortDates("mdy", table.visibleRows, column);
sortDates("mdy", table, column);
} else if (isSortDates.yearMonthDay) {
sortDates("ymd", table.visibleRows, column);
sortDates("ymd", table, column);
} else if (isSortDates.dayMonthYear) {
sortDates("dmy", table.visibleRows, column);
sortDates("dmy", table, column);
}
const tableProperties = {
table,
tableRows: table.visibleRows,
fillValue,
column,
columnIndex,
th,
hasThClass,
isSortDates,
desc,
timesClickedColumn,
arrow,
};
getTableData(tableProperties);
timesClickedColumn = getTableData(tableProperties, timesClickedColumn);
updateTable(tableProperties);

@@ -542,0 +616,0 @@ });

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc