You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

simple-datatables

Package Overview
Dependencies
Maintainers
1
Versions
99
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

simple-datatables - npm Package Compare versions

Comparing version

to
7.1.0

docs/demos/20-column-filters/index.html

17

dist/dts/datatable.d.ts

@@ -20,3 +20,2 @@ import { cellType, DataTableConfiguration, DataTableOptions, inputCellType, elementNodeType, renderOptions, TableDataType } from "./types";

initialized: boolean;
_input: HTMLInputElement;
_label: HTMLElement;

@@ -42,3 +41,6 @@ lastPage: number;

_searchData: number[];
_searchQuery: string;
_searchQueries: {
term: string;
columns: (number[] | undefined);
}[];
_tableAttributes: {

@@ -96,6 +98,13 @@ [key: string]: string;

/**
* Perform a search of the data set
* Perform a simple search of the data set
*/
search(query: string): boolean;
search(term: string, columns?: (number[] | undefined)): boolean;
/**
* Perform a search of the data set seraching for up to multiple strings in various columns
*/
multiSearch(queries: {
term: string;
columns: (number[] | undefined);
}[]): boolean;
/**
* Change page

@@ -102,0 +111,0 @@ */

@@ -1,1 +0,1 @@

export declare const layoutTemplate: (options: any) => string;
export declare const layoutTemplate: (options: any, dom: any) => string;

@@ -77,6 +77,9 @@ interface elementNodeType {

/**
* default: '{select} entries per page'
* default: 'Search within table'
* Sets the title of the search input.
*/
searchTitle: string;
/**
* default: 'entries per page'
* Sets the per-page dropdown's label
*
* {select} - the per-page dropdown (required)
*/

@@ -217,3 +220,4 @@ perPage: string;

placeholder: "Search...",
perPage: "{select} entries per page",
searchTitle: "Search within table",
perPage: "entries per page",
noRows: "No entries to found",

@@ -225,3 +229,3 @@ info: "Showing {start} to {end} of {rows} entries",

*/
template: (DataTableConfiguration: any) => string;
template: (DataTableConfiguration: any, HTMLTableElement: any) => string;
/**

@@ -228,0 +232,0 @@ * Allows for custom arranging of the DOM elements in the top and bottom containers. There are for 4 variables you can utilize:

@@ -79,6 +79,9 @@ import { DiffDOM } from 'diff-dom';

/**
* default: '{select} entries per page'
* default: 'Search within table'
* Sets the title of the search input.
*/
searchTitle: string;
/**
* default: 'entries per page'
* Sets the per-page dropdown's label
*
* {select} - the per-page dropdown (required)
*/

@@ -219,3 +222,4 @@ perPage: string;

placeholder: "Search...",
perPage: "{select} entries per page",
searchTitle: "Search within table",
perPage: "entries per page",
noRows: "No entries to found",

@@ -227,3 +231,3 @@ info: "Showing {start} to {end} of {rows} entries",

*/
template: (DataTableConfiguration: any) => string;
template: (DataTableConfiguration: any, HTMLTableElement: any) => string;
/**

@@ -467,3 +471,2 @@ * Allows for custom arranging of the DOM elements in the top and bottom containers. There are for 4 variables you can utilize:

initialized: boolean;
_input: HTMLInputElement;
_label: HTMLElement;

@@ -489,3 +492,6 @@ lastPage: number;

_searchData: number[];
_searchQuery: string;
_searchQueries: {
term: string;
columns: (number[] | undefined);
}[];
_tableAttributes: {

@@ -543,6 +549,13 @@ [key: string]: string;

/**
* Perform a search of the data set
* Perform a simple search of the data set
*/
search(query: string): boolean;
search(term: string, columns?: (number[] | undefined)): boolean;
/**
* Perform a search of the data set seraching for up to multiple strings in various columns
*/
multiSearch(queries: {
term: string;
columns: (number[] | undefined);
}[]): boolean;
/**
* Change page

@@ -549,0 +562,0 @@ */

@@ -115,2 +115,3 @@ #### Type: `array`

select: 6,
type: 'string',
render: function(data, td, rowIndex, cellIndex) {

@@ -117,0 +118,0 @@ return `${data}<button type='button' data-row='${rowIndex}'>Select</button>`;

@@ -20,2 +20,3 @@ #### Getting Started

* [datatable.search](Events#datatablesearch)
* [datatable.multisearch](Events#datatablesearch)
* [datatable.selectrow](Events#datatableselectrow)

@@ -82,1 +83,3 @@

* [print()](print())
* [search()](search())
* [multiSearch()](multiSearch())

@@ -10,3 +10,4 @@ ### `labels`

placeholder: "Search...",
perPage: "{select} entries per page",
searchTitle: "Search within table",
perPage: "entries per page",
noRows: "No entries to found",

@@ -35,5 +36,10 @@ info: "Showing {start} to {end} of {rows} entries",

<tr>
<td><code>searchTitle</code></td>
<td>Sets the title of the search input</td>
<td>None</td>
</tr>
<tr>
<td><code>perPage</code></td>
<td>Sets the per-page dropdown's label</td>
<td><code>{select}</code> - the per-page dropdown (<code class="danger">required</code>)</td>
<td>None</td>
</tr>

@@ -64,3 +70,4 @@ <tr>

placeholder: "Search employees...",
perPage: "Show {select} employees per page",
searchTitle: "Search within employees",
perPage: "employees per page",
noRows: "No employees to display",

@@ -67,0 +74,0 @@ info: "Showing {start} to {end} of {rows} employees (Page {page} of {pages} pages)",

@@ -7,3 +7,3 @@ ### `template`

```javascript
(options) => `<div class='${options.classes.top}'>
(options, dom) => `<div class='${options.classes.top}'>
${

@@ -21,3 +21,3 @@ options.paging && options.perPageSelect ?

`<div class='${options.classes.search}'>
<input class='${options.classes.input}' placeholder='${options.labels.placeholder}' type='text'>
<input class='${options.classes.input}' placeholder='${options.labels.placeholder}' type='search' title='${options.labels.searchTitle}'${dom.id ? ` aria-controls="${dom.id}"` : ""}>
</div>` :

@@ -24,0 +24,0 @@ ""

### Upgrading
## From 7.0.x to 7.1.x
* The [search()](search()) methods allows to specify which columns are to be searched. And the [multiSearch()](multiSearch()) method allows specifying multiple simultaneous searches.
## From 6.0.x to 7.0.x

@@ -4,0 +8,0 @@

{
"name": "simple-datatables",
"version": "7.0.3",
"version": "7.1.0",
"description": "A lightweight, dependency-free JavaScript HTML table plugin.",

@@ -18,6 +18,6 @@ "main": "dist/index.js",

"build_js_umd": "browserify dist/index.js --standalone simpleDatatables -o dist/umd/simple-datatables.js",
"build_css": "cp -R src/css/* dist/",
"build_demos": "npm run build_demos_js && cp -R src/css docs/demos/dist/",
"build_css": "shx cp -R src/css/* dist/",
"build_demos": "npm run build_demos_js && shx cp -R src/css docs/demos/dist/",
"build_demos_js": "rollup -c rollup.demos.config.mjs",
"postbuild_demos": "cp -r dist/umd/simple-datatables.js docs/demos/dist/umd.js",
"postbuild_demos": "shx cp -r dist/umd/simple-datatables.js docs/demos/dist/umd.js",
"prepare": "npm run build"

@@ -72,2 +72,3 @@ },

"selenium-webdriver": "^4.7.1",
"shx": "^0.3.4",
"tslib": "^2.4.1",

@@ -78,4 +79,4 @@ "typescript": "^4.9.4"

"dayjs": "^1.11.7",
"diff-dom": "5.0.2"
"diff-dom": "5.0.3"
}
}

@@ -302,4 +302,4 @@ import {readDataCell, readHeaderCell} from "./read_data"

dir}
if (this.dt._searchQuery) {
this.dt.search(this.dt._searchQuery)
if (this.dt._searchQueries.length) {
this.dt.multiSearch(this.dt._searchQueries)
this.dt.emit("datatable.sort", index, dir)

@@ -306,0 +306,0 @@ } else if (!init) {

@@ -59,2 +59,3 @@ import {DataTableConfiguration} from "./types"

placeholder: "Search...", // The search input placeholder
searchTitle: "Search within table", // The search input title
perPage: "entries per page", // per-page dropdown label

@@ -61,0 +62,0 @@ noRows: "No entries found", // Message shown when there are no records to show

@@ -53,4 +53,2 @@ import {

_input: HTMLInputElement
_label: HTMLElement

@@ -80,3 +78,3 @@

_searchQuery: string
_searchQueries: {term: string, columns: (number[] | undefined)}[]

@@ -137,3 +135,3 @@ _tableAttributes: { [key: string]: string}

this._dd = new DiffDOM()
this._dd = new DiffDOM({valueDiffing: false})

@@ -147,2 +145,3 @@ this.initialized = false

this.hasRows = false
this._searchQueries = []

@@ -188,3 +187,3 @@ this.init()

this.wrapperDOM.innerHTML = this.options.template(this.options)
this.wrapperDOM.innerHTML = this.options.template(this.options, this.dom)

@@ -280,3 +279,3 @@ const selector = this.wrapperDOM.querySelector(`select.${this.options.classes.selector}`)

this.data.headings,
(this.options.paging || this._searchQuery) && this._currentPage && this.pages.length && !renderOptions.noPaging ?
(this.options.paging || this._searchQueries.length) && this._currentPage && this.pages.length && !renderOptions.noPaging ?
this.pages[this._currentPage - 1] :

@@ -300,3 +299,2 @@ this.data.data.map((row, index) => ({

}
const diff = this._dd.diff(this._virtualDOM, newVirtualDOM)

@@ -338,3 +336,3 @@ this._dd.apply(this.dom, diff)

f = f + 1
items = this._searchQuery ? this._searchData.length : this.data.data.length
items = this._searchQueries.length ? this._searchData.length : this.data.data.length
}

@@ -486,6 +484,25 @@

if (this.options.searchable) {
this._input = this.wrapperDOM.querySelector(`.${this.options.classes.input}`)
if (this._input) {
this._input.addEventListener("keyup", () => this.search(this._input.value), false)
}
this.wrapperDOM.addEventListener("keyup", (event: KeyboardEvent) => {
const target = event.target
if (!(target instanceof HTMLInputElement) || !target.matches(`.${this.options.classes.input}`)) {
return
}
event.preventDefault()
const searches : {term: string, columns: (number[] | undefined)}[] = (Array.from(this.wrapperDOM.querySelectorAll(`.${this.options.classes.input}`)) as HTMLInputElement[]).filter(
el => el.value.length
).map(
el => el.dataset.columns ?
{term: el.value,
columns: (JSON.parse(el.dataset.columns) as number[])} :
{term: el.value,
columns: undefined}
)
if (searches.length === 1) {
const search = searches[0]
this.search(search.term, search.columns)
} else {
this.multiSearch(searches)
}
})
}

@@ -654,3 +671,3 @@

if (this._searchQuery) {
if (this._searchQueries.length) {
rows = []

@@ -704,24 +721,49 @@

/**
* Perform a search of the data set
* Perform a simple search of the data set
*/
search(query: string) {
search(term: string, columns: (number[] | undefined ) = undefined) {
if (!term.length) {
this._currentPage = 1
this._searchQueries = []
this._searchData = []
this.update()
this.emit("datatable.search", "", [])
this.wrapperDOM.classList.remove("search-results")
return false
}
this.multiSearch([
{term,
columns: columns ? columns : undefined}
])
this.emit("datatable.search", term, this._searchData)
}
/**
* Perform a search of the data set seraching for up to multiple strings in various columns
*/
multiSearch(queries : {term: string, columns: (number[] | undefined)}[]) {
if (!this.hasRows) return false
this._currentPage = 1
this._searchQuery = query
this._searchQueries = queries
this._searchData = []
if (!query.length) {
queries = queries.filter(query => query.term.length)
if (!queries.length) {
this.update()
this.emit("datatable.search", query, this._searchData)
this.emit("datatable.multisearch", queries, this._searchData)
this.wrapperDOM.classList.remove("search-results")
return false
}
const queryWords : (string | false)[]= this.columns.settings.map(
column => {
if (column.hidden || !column.searchable) {
const queryWords = queries.map(query => this.columns.settings.map(
(column, index) => {
if (column.hidden || !column.searchable || (query.columns && !query.columns.includes(index))) {
return false
}
let columnQuery = query
let columnQuery = query.term
const sensitivity = column.sensitivity || this.options.sensitivity

@@ -741,29 +783,34 @@ if (["base", "accent"].includes(sensitivity)) {

)
)
this.data.data.forEach((row: cellType[], idx: number) => {
for (let i=0; i<row.length; i++) {
const query = queryWords[i]
if (query) {
const cell = row[i]
let content = (cell.text || String(cell.data)).trim()
if (content.length) {
const column = this.columns.settings[i]
const sensitivity = column.sensitivity || this.options.sensitivity
if (["base", "accent"].includes(sensitivity)) {
content = content.toLowerCase()
}
if (["base", "case"].includes(sensitivity)) {
content = content.normalize("NFD").replace(/\p{Diacritic}/gu, "")
}
const ignorePunctuation = column.ignorePunctuation || this.options.ignorePunctuation
if (ignorePunctuation) {
content = content.replace(/[.,/#!$%^&*;:{}=-_`~()]/g, "")
}
if (query.split(" ").find(queryWord => content.includes(queryWord))) {
this._searchData.push(idx)
break
}
const searchRow = row.map((cell, i) => {
let content = (cell.text || String(cell.data)).trim()
if (content.length) {
const column = this.columns.settings[i]
const sensitivity = column.sensitivity || this.options.sensitivity
if (["base", "accent"].includes(sensitivity)) {
content = content.toLowerCase()
}
if (["base", "case"].includes(sensitivity)) {
content = content.normalize("NFD").replace(/\p{Diacritic}/gu, "")
}
const ignorePunctuation = column.ignorePunctuation || this.options.ignorePunctuation
if (ignorePunctuation) {
content = content.replace(/[.,/#!$%^&*;:{}=-_`~()]/g, "")
}
}
return content
})
if (
queryWords.every(
queries => queries.find(
(query, index) => query ?
query.split(" ").find(queryWord => searchRow[index].includes(queryWord)) :
false
)
)
) {
this._searchData.push(idx)
}
})

@@ -780,3 +827,3 @@

this.emit("datatable.search", query, this._searchData)
this.emit("datatable.multisearch", queries, this._searchData)
}

@@ -855,4 +902,8 @@

if (this.options.searchable) {
this._input.value = ""
this._searchQuery = ""
(Array.from(this.wrapperDOM.querySelectorAll(`.${this.options.classes.input}`)) as HTMLInputElement[]).forEach(
el => {
el.value = ""
}
)
this._searchQueries = []
}

@@ -924,32 +975,42 @@ this._currentPage = 1

let newVirtualDOM = structuredClone(this._virtualDOM)
let newVirtualDOM : elementNodeType = {
nodeName: "TABLE",
attributes: {
class: this.options.classes.table
},
childNodes: [
{
nodeName: "THEAD",
childNodes: [
headingsToVirtualHeaderRowDOM(
this.data.headings, this.columns.settings, this.columns._state, this.options, {})
]
},
{
nodeName: "TBODY",
childNodes: [
{
nodeName: "TR",
childNodes: [
{
nodeName: "TD",
attributes: {
class: this.options.classes.empty,
colspan: String(colspan)
},
childNodes: [
{
nodeName: "#text",
data: message
}
]
}
]
}
]
}
let tbody : elementNodeType = newVirtualDOM.childNodes?.find((node: elementNodeType) => node.nodeName === "TBODY") as elementNodeType
if (!tbody) {
tbody = {nodeName: "TBODY"}
newVirtualDOM.childNodes = [tbody]
]
}
tbody.childNodes = [
{
nodeName: "TR",
childNodes: [
{
nodeName: "TD",
attributes: {
class: this.options.classes.empty,
colspan: String(colspan)
},
childNodes: [
{
nodeName: "#text",
data: message
}
]
}
]
}
]
if (this.options.tableRender) {

@@ -956,0 +1017,0 @@ const renderedTableVirtualDOM : (elementNodeType | void) = this.options.tableRender(this.data, newVirtualDOM, "message")

// Template for custom layouts
export const layoutTemplate = options => `<div class='${options.classes.top}'>
export const layoutTemplate = (options, dom) => `<div class='${options.classes.top}'>
${

@@ -15,3 +15,3 @@ options.paging && options.perPageSelect ?

`<div class='${options.classes.search}'>
<input class='${options.classes.input}' placeholder='${options.labels.placeholder}' type='text'>
<input class='${options.classes.input}' placeholder='${options.labels.placeholder}' type='search' title='${options.labels.searchTitle}'${dom.id ? ` aria-controls="${dom.id}"` : ""}>
</div>` :

@@ -18,0 +18,0 @@ ""

@@ -92,6 +92,9 @@ // Same definitions as in diff-dom

/**
* default: '{select} entries per page'
* default: 'Search within table'
* Sets the title of the search input.
*/
searchTitle: string;
/**
* default: 'entries per page'
* Sets the per-page dropdown's label
*
* {select} - the per-page dropdown (required)
*/

@@ -239,3 +242,4 @@ perPage: string;

placeholder: "Search...",
perPage: "{select} entries per page",
searchTitle: "Search within table",
perPage: "entries per page",
noRows: "No entries to found",

@@ -247,3 +251,3 @@ info: "Showing {start} to {end} of {rows} entries",

*/
template: (DataTableConfiguration) => string;
template: (DataTableConfiguration, HTMLTableElement) => string;
/**

@@ -250,0 +254,0 @@ * Allows for custom arranging of the DOM elements in the top and bottom containers. There are for 4 variables you can utilize:

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet