Full-featured Interactive Data Table JavaScript Library – simple-datatables

Category: Javascript , Recommended , Table | April 12, 2024
Author:fiduswriter
Views Total:108 views
Official Page:Go to website
Last Update:April 12, 2024
License:MIT

Preview:

Full-featured Interactive Data Table JavaScript Library – simple-datatables

Description:

This is a JavaScript data table library that helps you create interactive tables on your website.

simple-datatables provides a range of features, including sortable/filterable columns, pagination, searchability, customizable layout and labels, and the ability to customize column rendering.

It also supports exporting data to common formats like CSV, TXT, JSON, and SQL, as well as importing CSV and JSON data. Users can also control column visibility and reorder or swap columns.

Additionally, the library integrates with dayjs for sorting columns with datetime strings and uses diffDOM for faster DOM updates.

How to use it:

1. Install and import the simple-datatables with NPM.

# NPM
$ npm install simple-datatables
<script type="module">
import {DataTable} from "./dist/module.js"
</script>

2. Or directly load the simple-datatables from a CDN.

<script src="
https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/simple-datatables.min.js
"></script>
<link href="
https://cdn.jsdelivr.net/npm/[email protected]/dist/style.min.css
" rel="stylesheet">

3. Initialize the DataTable on your existing HTML table.

<table id="demo">
...
</table>
window.dt = new DataTable("#demo", {
  // options here
})

4. Or load tabular data from an external JSON using Fetch.

fetch("data.json")
  .then(response => response.json())
  .then(data => {
    if (!data || !data.length) {
      return
    }
    window.datatable = new window.simpleDatatables.DataTable("#demo", {
      data: {
        headings: Object.keys(data[0]),
        data: data.map(item => Object.values(item))
      }
    })
  })

5. Or directly define your data in the data option.

window.dt = new DataTable("#demo", {
  data: {[/* data here */]}
})

6. Available HTML data attributes.

  • data-type: Set the type of the column: html (default), string, date, number, boolean, other
  • data-hidden: Hide the column. True or false.
  • data-searchable: Enable searchable. True or false.
  • data-sortable: Enable sortable. True or false.
<th>Name</th>
<th data-hidden="true">Ext.</th>
<th data-searchable="false">City</th>
<th data-type="date" data-format="YYYY/DD/MM">Start Date</th>
<th data-sortable="false">Completion</th>

7. Available options to customize the date table.

/**
 * Display a table caption with [<caption>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption).
 * No caption is displayed by default.
 */
caption: string | undefined;
classes: {
  active: string;
  ascending: string;
  bottom: string;
  container: string;
  cursor: string;
  descending: string;
  disabled: string;
  dropdown: string;
  ellipsis: string;
  empty: string;
  filter: string;
  filterActive: string;
  headercontainer: string;
  hidden: string;
  info: string;
  input: string;
  loading: string;
  pagination: string;
  paginationList: string;
  paginationListItem: string;
  paginationListItemLink: string;
  search: string;
  selector: string;
  sorter: string;
  table: string;
  top: string;
  wrapper: string;
};
columns: {
  /**An integer or array of integers representing the column(s) to be manipulated. */
  select: number | number[];
  /**Automatically sort the selected column. Can only be applied if a single column is selected. */
  sort?: "asc" | "desc";
  /**When set to false the column(s) cannot be sorted. */
  sortable?: boolean;
  /** An array of "asc" and "desc" describing the order sort will be executed as the user clicks on the column header. Note that each can only be mentioned up to one time. */
  sortSequence?: ("asc" | "desc")[];
  /** Default: true (boolean). Influences how string sorting is done. If true multiple numbers will be seen as just one so that "file 1.jpg" will come before "file 100.jpg". */
  numeric?: boolean;
  /**
   * Default: "false" Options: ["false", "upper", "lower"]. Influences how string sorting is done and whether upper or lower case letters are sorted first.
   * If "false" is selected, will use the chosen locale’s default sorting order.
   */
  caseFirst?: "false" | "upper" | "lower";
  /**When set to true the column(s) will not be visible and will be excluded from search results. */
  hidden?: boolean;
  /**
   * A string representing the type of data in the column(s) cells. Choose from the following options:
  string - lexical ordering (default)
  number - any string with currency symbols, . or , thousand separators, %, etc
  date - a valid datetime string
   */
  type?: string;
  /**A string representing the datetime format when using the date type. */
  format?: string;
  /**
   * A callback to customise the rendering of the column(s) cell content. The function takes 3 parameters and should return the formatted cell content.
   *
   */
  render?: renderType;
  /**
   * A filter to be used instead of sorting for the selected column(s).
   */
  filter?: (string | number | boolean | ((arg: (string | number | boolean)) => boolean))[];
  /** CSS classes to apply to the header cell. */
  headerClass?: string;
  /** CSS classes to apply to the body cell. */
  cellClass?: string;
  /**
   * Default: "base". Options: ["base", "accent", "case", "variant"].
   * Influences how searching is done. "base" and "accent" will ignore case differences. "base" and "case" will ignore differences in accent symbols
   * */
  sensitivity?: string;
  /** Default: true (boolean). Influences how sorting and searching is done. */
  ignorePunctuation?: boolean;
  /** Default: " ". Influences searching. When performing search, the cell content is split up using this separator.*/
  searchItemSeparator?: string;
  /**
   * Default: "en-US" (string). Set a locale such as en-UK or de for the column.
   * Influences how string sorting is done. Allows even for specification of specific subvariants such as de-DE-u-co-phonebk.
   */
  locale?: string;
};
/**Controls various aspects of individual or groups of columns. Should be an array of objects with the following properties:
 */
data: {
  headings?: string[];
  data?: (inputRowType | inputCellType[])[];
};
/**
 * Pass an object of data to populate the table.
 *
 * You can set both the headings and rows with headings and data properties, respectively. The headings property is optional.
 *
 * Docs : https://fiduswriter.github.io/simple-datatable/documentation/data
 */
type: ("date" | "html" | "number" | "boolean" | "string" | "other");
/**
 * Default data type.
 * 'html' by default.
 */
format: string;
/**
 * Default date format.
 * 'YYYY-MM-DD' by default.
 */
destroyable: boolean;
/**
 * Default: true
 * Whether enough information should be retained to be able to recreate the initial dom state before the table was initiated.
 */
ellipsisText: string;
/**
 * Default: '…'
 * Text to be used for ellipsis.
 */
firstLast: boolean;
/**Toggle the skip to first page and skip to last page buttons.
 * Default: false
 */
firstText: string;
/**
 * default: '«'
 * Set the content of the skip to first page button.
 *
 */
fixedColumns: boolean;
/**
 * Default: true
 * Fix the width of the columns. This stops the columns changing width when loading a new page.
 */
fixedHeight: boolean;
/**
 * Default: false
 * Fix the height of the table. This is useful if your last page contains less rows than set in the perPage options and simply stops the table from changing size and affecting the layout of the page.
 */
footer: boolean;
/**
 * Default: false
 * Enable or disable the table footer.
 */
header: boolean;
/**
 * Default: true
 * Enable or disable the table header.
 */
hiddenHeader: boolean;
/**
 * Default: false
 * Whether to hide the table header.
 */
labels: {
  placeholder: string;
  /**
   * default: 'Search...'
   * Sets the placeholder of the search input.
   */
  searchTitle: string;
  /**
   * default: 'Search within table'
   * Sets the title of the search input.
   */
  perPage: string;
  /**
   * default: 'entries per page'
   * Sets the per-page dropdown's label
   */
  pageTitle: string;
  /**
   * default: 'Page {page}'
   * Displays current range as used in aria-labeel
   *
   * {page} - The current page number
   */
  noRows: string;
  /**
   * default: 'No entries found'
   * The message displayed when there are no search results
   */
  noResults: string;
  /**
   * default: 'No results match your search query'
   * The message displayed when there are no search results
   */
  info: string;
};
/**
 * Customise the displayed labels.
 *
 * Defaults :
 *
 * labels: {
 *
      placeholder: "Search...",
      searchTitle: "Search within table",
      perPage: "entries per page",
      noRows: "No entries to found",
      info: "Showing {start} to {end} of {rows} entries",
    }
 */
template: (DataTableConfiguration: any, HTMLTableElement: any) => string;
/**
 * Allows for custom arranging of the DOM elements in the top and bottom containers. There are for 4 variables you can utilize:
 */
lastText: string;
/**
 * default: '»'
 * Set the content of the skip to last page button.
 */
nextPrev: boolean;
/**
 * Default : true
 * Toggle the next and previous pagination buttons.
 */
nextText: string;
/**
 * default: '›'
 * Set the content on the next button.
 */
pagerDelta: number;
/**
 * Default: 2
 * Delta to use with pager
 */
pagerRender: false | pagerRenderType;
/**
* Default: false
* Method to call to modify pager rendering output.
*/
paging: boolean;
/**
 * Default : true
 * Whether or not paging is enabled for the table
 */
perPage: number;
/**
 * Default : 10
 * Sets the maximum number of rows to display on each page.
 */
perPageSelect: (number | [string, number])[];
/**
 * Default: [5, 10, 15, 20, 25]
 *
 * Sets the per page options in the dropdown. Must be an array of integers.
 *
 *   Setting this to false will hide the dropdown.
 */
prevText: string;
/**
 * default: '‹'
 * Set the content on the previous button.
 */
rowNavigation: boolean;
/**
 * Default: true
 * Whether to allow row based navigation
 */
rowRender: false | rowRenderType;
/**
 * Default: false
 * Method to call to modify row rendering output.
 */
scrollY: string;
/**
 * Default : ""
 *
 * Enable vertical scrolling. Vertical scrolling will constrain the DataTable to the given height, and enable scrolling for any data which overflows the current viewport. This can be used as an alternative to paging to display a lot of data in a small area.
 *
 * The value given here can be given in any CSS unit.
 */
searchable: boolean;
sensitivity: string;
ignorePunctuation: boolean;
searchItemSeparator: string;
searchQuerySeparator: string;
searchAnd: boolean;
/**
 * Default: true
 * Toggle the ability to sort the columns.
 *
 * This option will be forced to false if the table has no headings.
 */
sortable: boolean;
locale: string;
numeric: boolean;
caseFirst: "false" | "upper" | "lower";
tabIndex: false | number;
/**
 * Default: false
 * A tab index number to be assigned to the table.
 */
tableRender: false | tableRenderType;
/**
 * Default: false
 * Method to call to modify table rendering output.
 */
diffDomOptions: object;
/**
 * Default: { valueDiffing: false }
 * Options to parse on to diffDOM.
 */
truncatePager: boolean;

8. Available API methods.

// add rows
let newRow = ["column1", "column2", ...];
datatable.rows.add(newRow);
// insert rows
let newRows = [
  ["column1", "column2",  ...],
  ["column1", "column2",  ...],
  ...
];
datatable.insert({data: newRows})
// remove the 2nd row
datatable.rows.remove(1);
// remove the first 3 rows
datatable.rows.remove([0,1,2]);
// go to page 3
datatable.page(3);
// add new a column
let newData = {
  heading: "Column Heading",
  data: [
    "Value 1",
    "Value 2",
    ...
  ]
};
datatable.columns.add(newData);
// get column data
datatable.columns.get(index);
// get the number of columns
datatable.columns.size();
// sort the selected column
datatable.columns.sort(column [integer], direction [string]);
// remove the 2rd column
datatable.columns.remove(1);
// remove the 1st and 2nd column
datatable.columns.remove([0,1]);
// remove the last column
datatable.columns.remove(datatable.headings.length - 1);
// show/hide columns
datatable.columns.show([0,1]);
datatable.columns.hide([0,1]);
// check visiblilty
datatable.columns.visible();
datatable.columns.visible(1);
datatable.columns.visible([0,1]);
// swap the 1st and 3rd columns
datatable.columns.swap([0,4]);
// re-order the columns
datatable.columns.order([1,3,4,2,0]);
// update the data table
datatable.update(measureWidths=false);
// refresh the data table
datatable.refresh();
// insert new data
datatable.insert(data);
// display a message in the table
dataTable.setMessage(message);
// destroy the data table
datatable.destroy();
// re-init the data table
datatable.init(options);
// print the data table
datatable.print();
// search the data table
datatable.search(term, columns);
// filter the table based on multiple queries
datatable.multiSearch(queries);
// available props
dom
wrapper
container
pagers
options
initialized
data
data-index
pages
hasRows
hasHeadings
currentPage
totalPages
onFirstPage
onLastPage
searching
searchData

9. Event handlers.

dataTable.on('datatable.init', function() {
  // do something
});
dataTable.on('datatable.page', function(page) {
  // do something
});
dataTable.on('datatable.perpage', function(perpage) {
  // do something
});
dataTable.on('datatable.refresh', function() {
  // do something
});
dataTable.on('datatable.search', function(query, matched) {
  // do something
});
dataTable.on("datatable.selectrow", (rowIndex, event) => {
  event.preventDefault();
  // do something
});
dataTable.on('datatable.sort', function(column, direction) {
  // do something
});
dataTable.on('datatable.update', function() {
  // do something
});

10. Export data to CSV, TXT, JSON, SQL, or custom Format.

import {
  DataTable,
  exportJSON,
  exportCSV,
  exportTXT,
  exportSQL
} from "./dist/module.js"
exportCSV(table, {
  download: true,
  lineDelimiter: "\n",
  columnDelimiter: ";"
})
exportSQL(table, {
  download: true,
  tableName: "export_table"
})
exportTXT(table, {
  download: true
});
exportJSON(table, {
  download: true,
  space: 3
});
// Custom Export
const exportCustomCSV = function(dataTable, userOptions = {}) {
  // A modified CSV export that includes a row of minuses at the start and end.
  const clonedUserOptions = {
      ...userOptions
  }
  clonedUserOptions.download = false
  const csv = exportCSV(dataTable, clonedUserOptions)
  // If CSV didn't work, exit.
  if (!csv) {
      return false
  }
  const defaults = {
      download: true,
      lineDelimiter: "\n",
      columnDelimiter: ";"
  }
  const options = {
      ...defaults,
      ...clonedUserOptions
  }
  const separatorRow = Array(dataTable.data.headings.filter((_heading, index) => !dataTable.columns.settings[index]?.hidden).length)
      .fill("-")
      .join(options.columnDelimiter)
  const str = `${separatorRow}${options.lineDelimiter}${csv}${options.lineDelimiter}${separatorRow}`
  if (userOptions.download) {
      // Create a link to trigger the download
      const link = document.createElement("a")
      link.href = encodeURI(`data:text/csv;charset=utf-8,${str}`)
      link.download = `${options.filename || "datatable_export"}.txt`
      // Append the link
      document.body.appendChild(link)
      // Trigger the download
      link.click()
      // Remove the link
      document.body.removeChild(link)
  }
  return str
}
// Export
exportCustomCSV(table, {
  download: true
})

Changelog:

v9.0.3 (04/12/2024)

  • Bugfixes

v9.0.2 (04/10/2024)

  • Bugfixes

You Might Be Interested In:


Leave a Reply