import $ from './dom'; import DataManager from './datamanager'; import CellManager from './cellmanager'; import ColumnManager from './columnmanager'; import RowManager from './rowmanager'; import Style from './style'; import { getRowHTML } from './rowmanager'; import './style.scss'; const DEFAULT_OPTIONS = { events: null, data: { columns: [], rows: [] }, editing: null, addSerialNoColumn: true, addCheckboxColumn: true, enableClusterize: true, enableLogs: false, takeAvailableSpace: false }; class DataTable { constructor(wrapper, options) { DataTable.instances++; if (typeof wrapper === 'string') { // css selector wrapper = document.querySelector(wrapper); } this.wrapper = wrapper; if (!this.wrapper) { throw new Error('Invalid argument given for `wrapper`'); } this.options = Object.assign({}, DEFAULT_OPTIONS, options); // custom user events this.events = this.options.events; this.prepare(); this.style = new Style(this); this.datamanager = new DataManager(this.options); this.rowmanager = new RowManager(this); this.columnmanager = new ColumnManager(this); this.cellmanager = new CellManager(this); if (this.options.data) { this.refresh(this.options.data); } } prepare() { this.prepareDom(); } prepareDom() { this.wrapper.innerHTML = `
`; this.datatableWrapper = $('.data-table', this.wrapper); this.header = $('.data-table-header', this.wrapper); this.bodyScrollable = $('.body-scrollable', this.wrapper); } refresh(data) { this.datamanager.init(data); this.render(); } destroy() { this.wrapper.innerHTML = ''; this.style.destroy(); } appendRows(rows) { this.datamanager.appendRows(rows); this.rowmanager.refreshRows(); } render() { this.renderHeader(); this.renderBody(); this.setDimensions(); } renderHeader() { this.columnmanager.renderHeader(); } renderBody() { if (this.options.enableClusterize) { this.renderBodyWithClusterize(); } else { this.renderBodyHTML(); } } renderBodyHTML() { const rows = this.datamanager.getRows(); this.bodyScrollable.innerHTML = ` ${getBodyHTML(rows)}
`; } renderBodyWithClusterize() { // empty body this.bodyScrollable.innerHTML = ` ${getBodyHTML([])}
`; this.start = 0; this.pageLength = 1000; this.end = this.start + this.pageLength; // only append ${this.pageLength} rows in the beginning, // defer remaining const rows = this.datamanager.getRows(this.start, this.end); const initialData = this.getDataForClusterize(rows); this.clusterize = new Clusterize({ rows: initialData, scrollElem: this.bodyScrollable, contentElem: $('tbody', this.bodyScrollable), callbacks: { clusterChanged: () => { this.rowmanager.highlightCheckedRows(); this.cellmanager.selectAreaOnClusterChanged(); this.cellmanager.focusCellOnClusterChanged(); } } }); this.log('dataAppended', this.pageLength); this.appendRemainingData(); } appendRemainingData() { let dataAppended = this.pageLength; const promises = []; const rowCount = this.datamanager.getRowCount(); while (dataAppended + this.pageLength < rowCount) { this.start = this.end; this.end = this.start + this.pageLength; promises.push(this.appendNextPagePromise(this.start, this.end)); dataAppended += this.pageLength; } if (rowCount % this.pageLength > 0) { // last page this.start = this.end; this.end = this.start + this.pageLength; promises.push(this.appendNextPagePromise(this.start, this.end)); } return promises.reduce( (prev, cur) => prev.then(cur), Promise.resolve() ); } appendNextPagePromise(start, end) { return new Promise(resolve => { setTimeout(() => { const rows = this.datamanager.getRows(start, end); const data = this.getDataForClusterize(rows); this.clusterize.append(data); this.log('dataAppended', rows.length); resolve(); }, 0); }); } getDataForClusterize(rows) { return rows.map((row) => getRowHTML(row, { rowIndex: row[0].rowIndex })); } setDimensions() { this.columnmanager.setDimensions(); this.setBodyWidth(); $.style(this.bodyScrollable, { marginTop: $.style(this.header, 'height') + 'px' }); $.style($('table', this.bodyScrollable), { margin: 0 }); } setBodyWidth() { const width = $.style(this.header, 'width'); $.style(this.bodyScrollable, { width: width + 'px' }); } getColumn(colIndex) { return this.datamanager.getColumn(colIndex); } getCell(colIndex, rowIndex) { return this.datamanager.getCell(colIndex, rowIndex); } getColumnHeaderElement(colIndex) { return this.columnmanager.getColumnHeaderElement(colIndex); } getViewportHeight() { if (!this.viewportHeight) { this.viewportHeight = $.style(this.bodyScrollable, 'height'); } return this.viewportHeight; } scrollToLastColumn() { this.datatableWrapper.scrollLeft = 9999; } log() { if (this.options.enableLogs) { console.log.apply(console, arguments); } } } DataTable.instances = 0; export default DataTable; export function getBodyHTML(rows) { return ` ${rows.map(row => getRowHTML(row, { rowIndex: row[0].rowIndex })).join('')} `; }