table-sort-js
Advanced tools
Comparing version 1.2.7 to 1.3.7
{ | ||
"name": "table-sort-js", | ||
"version": "1.2.7", | ||
"version": "1.3.7", | ||
"description": "A JavaScript client-side HTML table sorting library with no dependencies required.", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
156
README.md
@@ -1,69 +0,111 @@ | ||
![table-sort-js](https://img.shields.io/npm/v/table-sort-js) : https://www.npmjs.com/package/table-sort-js | ||
![table-sort-js](https://img.shields.io/npm/v/table-sort-js) | ||
![table-sort-js](https://img.shields.io/npm/dt/table-sort-js) | ||
![table-sort-js](https://img.shields.io/github/repo-size/leewannacott/table-sort-js) | ||
![table-sort-js](https://img.shields.io/github/license/LeeWannacott/table-sort-js) | ||
![table-sort-js](https://img.shields.io/github/workflow/status/leewannacott/table-sort-js/Jest%20CI%20-%20Automated%20testing%20of%20table%20sorting.?label=tests) | ||
* Description: A JavaScript client-side HTML table sorting library with no dependencies required. | ||
## table-sort-js. | ||
* Demo: https://leewannacott.github.io/Portfolio/#/GitHub | ||
- Description: A JavaScript client-side HTML table sorting library with no dependencies required. | ||
* Backend: `npm install table-sort-js` and require("../node_modules/table-sort-js/table-sort.js") | ||
- Demo: https://leewannacott.github.io/Portfolio/#/GitHub. | ||
* Frontend: `<script src="https://leewannacott.github.io/table-sort-js/table-sort.js"></script>` | ||
- Download: https://leewannacott.github.io/table-sort-js/table-sort.js | ||
* Instructions: Add class "table-sort" to HTML table tags. Click on column headers to sort. | ||
- NPM: https://www.npmjs.com/package/table-sort-js. | ||
Example: | ||
#### Instructions: | ||
- Add `class="table-sort"` to HTML table tags. Click on column headers to sort. | ||
#### Classes: | ||
| table classes | Description | | ||
| -------------- | ------------------------------------------------ | | ||
| "table-sort" | Make the table sortable! (Words, numbers, dates) | | ||
| "table-arrows" | Display ascending or descending triangle. | | ||
| th classes | Description | | ||
| --------------- | ----------------------------------------------------------- | | ||
| "order-by-desc" | Order by descending on first click. (default is aescending) | | ||
| "file-size" | Sort file sizes(B->TiB) uses the binary prefix. (e.g KiB) | | ||
#### Example using npm and ReactJS: | ||
##### Install :`npm install table-sort-js` | ||
```javascript | ||
import React, { Component } from "react"; | ||
import tableSort from "table-sort-js/table-sort.js"; | ||
export class App extends Component { | ||
componentDidMount() { | ||
tableSort() | ||
} | ||
render(){ | ||
return( | ||
<div> | ||
<table className="table-sort"> | ||
<thead> | ||
<tr> | ||
<th>Alphabet</th> | ||
<th className="order-by-desc">Order</th> | ||
</tr> | ||
</thead> | ||
<tbody className="table-hover"> | ||
<tr> | ||
<td>Alpha</td> | ||
<td>1</td> | ||
</tr> | ||
<tr> | ||
<td>Bravo</td> | ||
<td>2</td> | ||
</tr> | ||
<tr> | ||
<td>Charlie</td> | ||
<td>3</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
</div> | ||
); | ||
} | ||
} | ||
export default App; | ||
``` | ||
##### HTML Example: | ||
Download: https://leewannacott.github.io/table-sort-js/table-sort.js | ||
```html | ||
<script src="https://leewannacott.github.io/table-sort-js/table-sort.js"></script> | ||
<script src="table-sort.js"></script> | ||
<table class="table-sort"> | ||
<thead> | ||
<tr> | ||
<th>Last Name</th> | ||
<th>First Name</th> | ||
<th class="order-by-desc">Birth Date</th> | ||
<th>Employee ID</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td>Smith</td> | ||
<td>John</td> | ||
<td>1977/12/4</td> | ||
<td>1</td> | ||
</tr> | ||
<tr> | ||
<td>Bach</td> | ||
<td>Frank</td> | ||
<td>1976/10/27</td> | ||
<td>10</td> | ||
</tr> | ||
<tr> | ||
<td>Doe</td> | ||
<td>Jason</td> | ||
<td>1978/4/6</td> | ||
<td>100</td> | ||
</tr> | ||
<tr> | ||
<td>Michael</td> | ||
<td>Jackson</td> | ||
<td>1958/8/29</td> | ||
<td>54</td> | ||
</tr> | ||
<tr> | ||
<td>Ben</td> | ||
<td>Tenison</td> | ||
<td>1994/7/21</td> | ||
<td>134</td> | ||
</tr> | ||
</tbody> | ||
<thead> | ||
<tr> | ||
<th>Last Name</th> | ||
<th>First Name</th> | ||
<th class="order-by-desc">Birth Date</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td>Franklin</td> | ||
<td>Benjamin</td> | ||
<td>1706/1/17</td> | ||
</tr> | ||
<tr> | ||
<td>Carnegie</td> | ||
<td>Andew</td> | ||
<td>1835/11/25</td> | ||
</tr> | ||
<tr> | ||
<td>Twain</td> | ||
<td>Mark</td> | ||
<td>1835/11/30</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
``` | ||
Notes: | ||
* Makes use of natural sorting to sort numerical values correctly. Sorts numbers, Dates, alphanumeric, etc. | ||
* `class="order-by-desc"` on `<th>` to change default sort to descending order on first click. | ||
* If `<thead>` does not exist it will be created by using data from first row. `<tbody>` is optional. | ||
#### Notes: | ||
* Example of use: https://www.cssscript.com/minimal-table-sorter/ | ||
* Add `table-arrows` class to display ascending or descending triangle. | ||
- Makes use of natural sorting to sort numerical values correctly. | ||
- If `<thead>` does not exist it will be created by using data from first row. `<tbody>` is optional. |
@@ -18,6 +18,18 @@ /* | ||
function tableSortJs() { | ||
function tableSortJs(test = false, domDocumentWindow = document) { | ||
function checkIfTesting() { | ||
if (test === true) { | ||
const getTagTable = domDocumentWindow.getElementsByTagName("table"); | ||
const createTableHead = domDocumentWindow.createElement("thead"); | ||
return [getTagTable, createTableHead]; | ||
} else { | ||
const getTagTable = document.getElementsByTagName("table"); | ||
const createTableHead = document.createElement("thead"); | ||
return [getTagTable, createTableHead]; | ||
} | ||
} | ||
const [getTagTable, createTableHead] = checkIfTesting(); | ||
const columnIndexAndTableRow = {}; | ||
for (let table of document.getElementsByTagName("table")) { | ||
const fileSizeColumnTextAndRow = {}; | ||
for (let table of getTagTable) { | ||
if (table.classList.contains("table-sort")) { | ||
@@ -30,3 +42,3 @@ makeTableSortable(table); | ||
if (sortableTable.getElementsByTagName("thead").length === 0) { | ||
const the = document.createElement("thead"); | ||
createTableHead; | ||
the.appendChild(sortableTable.rows[0]); | ||
@@ -39,6 +51,5 @@ sortableTable.insertBefore(the, sortableTable.firstChild); | ||
const tableHeadHeaders = tableHead.querySelectorAll("th"); | ||
tableHead.style.cursor = "pointer"; | ||
let columnIndexesClicked= []; | ||
let columnIndexesClicked = []; | ||
for (let [columnIndex, th] of tableHeadHeaders.entries()) { | ||
@@ -48,14 +59,100 @@ let timesClickedColumn = 0; | ||
th.addEventListener("click", function () { | ||
const tableRows = tableBody.querySelectorAll("tr"); | ||
const columnData = []; | ||
// Handle filesize sorting (e.g KB, MB, GB, TB) - Turns data into KiB. | ||
let isFileSize = th.classList.contains("file-size"); | ||
if (isFileSize) { | ||
const numberWithUnitType = /[.0-9]+(\s?B|\s?KB|\s?KiB|\s?MB|\s?MiB|\s?GB|\s?GiB|T\s?B|\s?TiB)/i; | ||
const unitType = /(\s?B|\s?KB|\s?KiB|\s?MB|\s?MiB|\s?GB|G\s?iB|\s?TB|\s?TiB)/i; | ||
const fileSizes = { | ||
Kibibyte: 1024, | ||
Mebibyte: 1.049e6, | ||
Gibibyte: 1.074e9, | ||
Tebibyte: 1.1e12, | ||
Pebibyte: 1.126e15, | ||
Kilobyte: 1000, | ||
Megabyte: 1e6, | ||
Gigabyte: 1e9, | ||
Terabyte: 1e12, | ||
}; | ||
for (let [i, tr] of tableRows.entries()) { | ||
let fileSizeTd = tr.querySelectorAll("td").item(columnIndex) | ||
.textContent; | ||
if (fileSizeTd.match(numberWithUnitType)) { | ||
if (fileSizeTd.match(/\s?KB/i)) { | ||
fileSizeTd = fileSizeTd.replace(unitType, ""); | ||
fileSizeTd = fileSizeTd.replace( | ||
fileSizeTd, | ||
fileSizeTd * fileSizes.Kilobyte | ||
); | ||
columnData.push(fileSizeTd); | ||
} else if (fileSizeTd.match(/\s?KiB/i)) { | ||
fileSizeTd = fileSizeTd.replace(unitType, ""); | ||
fileSizeTd = fileSizeTd.replace( | ||
fileSizeTd, | ||
fileSizeTd * fileSizes.Kibibyte | ||
); | ||
columnData.push(fileSizeTd); | ||
} else if (fileSizeTd.match(/\s?MB/i)) { | ||
fileSizeTd = fileSizeTd.replace(unitType, ""); | ||
fileSizeTd = fileSizeTd.replace( | ||
fileSizeTd, | ||
fileSizeTd * fileSizes.Megabyte | ||
); | ||
columnData.push(fileSizeTd); | ||
} else if (fileSizeTd.match(/\s?MiB/i)) { | ||
fileSizeTd = fileSizeTd.replace(unitType, ""); | ||
fileSizeTd = fileSizeTd.replace( | ||
fileSizeTd, | ||
fileSizeTd * fileSizes.Mebibyte | ||
); | ||
columnData.push(fileSizeTd); | ||
} else if (fileSizeTd.match(/\s?GB/i)) { | ||
fileSizeTd = fileSizeTd.replace(unitType, ""); | ||
fileSizeTd = fileSizeTd.replace( | ||
fileSizeTd, | ||
fileSizeTd * fileSizes.Gigabyte | ||
); | ||
columnData.push(fileSizeTd); | ||
} else if (fileSizeTd.match(/\s?GiB/i)) { | ||
fileSizeTd = fileSizeTd.replace(unitType, ""); | ||
fileSizeTd = fileSizeTd.replace( | ||
fileSizeTd, | ||
fileSizeTd * fileSizes.Gibibyte | ||
); | ||
columnData.push(fileSizeTd); | ||
} else if (fileSizeTd.match(/\s?TB/i)) { | ||
fileSizeTd = fileSizeTd.replace(unitType, ""); | ||
fileSizeTd = fileSizeTd.replace( | ||
fileSizeTd, | ||
fileSizeTd * fileSizes.Terabyte | ||
); | ||
columnData.push(fileSizeTd); | ||
} else if (fileSizeTd.match(/\s?TiB/i)) { | ||
fileSizeTd = fileSizeTd.replace(unitType, ""); | ||
fileSizeTd = fileSizeTd.replace( | ||
fileSizeTd, | ||
fileSizeTd * fileSizes.Tebibyte | ||
); | ||
columnData.push(fileSizeTd); | ||
} else if (fileSizeTd.match(/\s?B/i)) { | ||
fileSizeTd = fileSizeTd.replace(unitType, ""); | ||
columnData.push(fileSizeTd); | ||
} | ||
} else { | ||
columnData.push("!X!Y!Z!#" + i); | ||
} | ||
} | ||
} | ||
// Checking if user has clicked different column from the first column if yes 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) { | ||
if (timesClickedColumn === 1 && columnIndexesClicked.length > 1) { | ||
const lastColumnClicked = | ||
columnIndexesClicked[columnIndexesClicked.length - 1]; | ||
const secondLastColumnClicked = | ||
columnIndexesClicked[columnIndexesClicked.length - 2]; | ||
if (lastColumnClicked !== secondLastColumnClicked) { | ||
timesClickedColumn = 0; | ||
columnIndexesClicked.shift() | ||
columnIndexesClicked.shift(); | ||
} | ||
@@ -65,2 +162,3 @@ } | ||
timesClickedColumn += 1; | ||
getTableData(); | ||
@@ -71,3 +169,66 @@ updateTable(); | ||
for (let [i, tr] of tableRows.entries()) { | ||
tr.innerHTML = columnIndexAndTableRow[columnData[i]]; | ||
if (isFileSize) { | ||
tr.innerHTML = fileSizeColumnTextAndRow[columnData[i]]; | ||
let fileSizeInBytesHTML = tr | ||
.querySelectorAll("td") | ||
.item(columnIndex).innerHTML; | ||
let fileSizeInBytesText = tr | ||
.querySelectorAll("td") | ||
.item(columnIndex).textContent; | ||
const fileSizes = { | ||
Kibibyte: 1024, | ||
Mebibyte: 1.049e6, | ||
Gibibyte: 1.074e9, | ||
Tebibyte: 1.1e12, | ||
Pebibyte: 1.126e15, | ||
}; | ||
if (columnData[i] < fileSizes.Kibibyte) { | ||
fileSizeInBytesHTML = fileSizeInBytesHTML.replace( | ||
fileSizeInBytesText, | ||
`${parseFloat(columnData[i]).toFixed(2)} B` | ||
); | ||
} else if ( | ||
columnData[i] >= fileSizes.Kibibyte && | ||
columnData[i] < fileSizes.Mebibyte | ||
) { | ||
fileSizeInBytesHTML = fileSizeInBytesHTML.replace( | ||
fileSizeInBytesText, | ||
`${(columnData[i] / fileSizes.Kibibyte).toFixed(2)} KiB` | ||
); | ||
} else if ( | ||
columnData[i] >= fileSizes.Mebibyte && | ||
columnData[i] < fileSizes.Gibibyte | ||
) { | ||
fileSizeInBytesHTML = fileSizeInBytesHTML.replace( | ||
fileSizeInBytesText, | ||
`${(columnData[i] / fileSizes.Mebibyte).toFixed(2)} MiB` | ||
); | ||
} else if ( | ||
columnData[i] >= fileSizes.Gibibyte && | ||
columnData[i] < fileSizes.Tebibyte | ||
) { | ||
fileSizeInBytesHTML = fileSizeInBytesHTML.replace( | ||
fileSizeInBytesText, | ||
`${(columnData[i] / fileSizes.Gibibyte).toFixed(2)} GiB` | ||
); | ||
} else if ( | ||
columnData[i] >= fileSizes.Tebibyte && | ||
columnData[i] < fileSizes.Pebibyte | ||
) { | ||
fileSizeInBytesHTML = fileSizeInBytesHTML.replace( | ||
fileSizeInBytesText, | ||
`${(columnData[i] / fileSizes.Tebibyte).toFixed(2)} TiB` | ||
); | ||
} else { | ||
fileSizeInBytesHTML = fileSizeInBytesHTML.replace( | ||
fileSizeInBytesText, | ||
"NaN" | ||
); | ||
} | ||
tr | ||
.querySelectorAll("td") | ||
.item(columnIndex).innerHTML = fileSizeInBytesHTML; | ||
} else if (!isFileSize) { | ||
tr.innerHTML = columnIndexAndTableRow[columnData[i]]; | ||
} | ||
} | ||
@@ -78,6 +239,15 @@ } | ||
for (let [i, tr] of tableRows.entries()) { | ||
let tdInnerHTML = tr.querySelectorAll('td').item(columnIndex).innerHTML; | ||
if (tdInnerHTML.trim() !== "") { | ||
columnData.push(tdInnerHTML+ '#' + i); | ||
columnIndexAndTableRow[tdInnerHTML+ '#' + i] = tr.innerHTML; | ||
// inner text for column we click on | ||
let tdTextContent = tr.querySelectorAll("td").item(columnIndex) | ||
.textContent; | ||
if (tdTextContent.length === 0) { | ||
tdTextContent = ""; | ||
} | ||
if (tdTextContent.trim() !== "") { | ||
if (!isFileSize) { | ||
columnData.push(tdTextContent + "#" + i); | ||
columnIndexAndTableRow[tdTextContent + "#" + i] = tr.innerHTML; | ||
} else if (isFileSize) { | ||
fileSizeColumnTextAndRow[columnData[i]] = tr.innerHTML; | ||
} | ||
} else { | ||
@@ -121,4 +291,4 @@ // Fill in blank table cells dict key with filler value. | ||
let desc = th.classList.contains('order-by-desc'); | ||
let tableArrows = sortableTable.classList.contains('table-arrows'); | ||
let desc = th.classList.contains("order-by-desc"); | ||
let tableArrows = sortableTable.classList.contains("table-arrows"); | ||
@@ -174,2 +344,5 @@ if (timesClickedColumn === 1) { | ||
document.addEventListener("DOMContentLoaded", tableSortJs, false); | ||
} | ||
} | ||
if (typeof module == "object") { | ||
module.exports = tableSortJs; | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19173
320
112