Add DataManager
- refactor datatable to use datamanager
This commit is contained in:
parent
b409b849d4
commit
11407c2efd
@ -27,7 +27,7 @@
|
||||
"parser": "babel-eslint",
|
||||
|
||||
"plugins": [
|
||||
|
||||
|
||||
],
|
||||
|
||||
"rules": {
|
||||
@ -150,7 +150,7 @@
|
||||
"no-unreachable": 2,
|
||||
"no-unused-expressions": 0,
|
||||
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
|
||||
"no-use-before-define": 2,
|
||||
"no-use-before-define": 0,
|
||||
"no-var": 0,
|
||||
"no-void": 0,
|
||||
"no-warning-comments": 0,
|
||||
|
||||
@ -115,8 +115,14 @@ var _createClass = function () { function defineProperties(target, props) { for
|
||||
|
||||
var _utils = __webpack_require__(2);
|
||||
|
||||
var _datamanager = __webpack_require__(9);
|
||||
|
||||
var _datamanager2 = _interopRequireDefault(_datamanager);
|
||||
|
||||
__webpack_require__(3);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var DEFAULT_OPTIONS = {
|
||||
@ -127,9 +133,9 @@ var DEFAULT_OPTIONS = {
|
||||
},
|
||||
editing: null,
|
||||
addSerialNoColumn: true,
|
||||
addCheckboxColumn: true,
|
||||
enableClusterize: true,
|
||||
enableLogs: false,
|
||||
addCheckbox: true
|
||||
enableLogs: false
|
||||
};
|
||||
|
||||
var DataTable = function () {
|
||||
@ -144,6 +150,8 @@ var DataTable = function () {
|
||||
this.options = Object.assign({}, DEFAULT_OPTIONS, options);
|
||||
this.events = this.options.events;
|
||||
|
||||
this.datamanager = new _datamanager2.default(this.options);
|
||||
|
||||
if (this.options.data) {
|
||||
this.refresh(this.options.data);
|
||||
}
|
||||
@ -162,7 +170,13 @@ var DataTable = function () {
|
||||
}, {
|
||||
key: 'refresh',
|
||||
value: function refresh(data) {
|
||||
this.data = this.prepareData(data);
|
||||
this.datamanager.init(data);
|
||||
this.render();
|
||||
}
|
||||
}, {
|
||||
key: 'appendRows',
|
||||
value: function appendRows(rows) {
|
||||
this.datamanager.appendRows(rows);
|
||||
this.render();
|
||||
}
|
||||
}, {
|
||||
@ -181,8 +195,9 @@ var DataTable = function () {
|
||||
}, {
|
||||
key: 'renderHeader',
|
||||
value: function renderHeader() {
|
||||
// fixed header
|
||||
this.header.html((0, _utils.getHeaderHTML)(this.data.columns));
|
||||
var columns = this.datamanager.getColumns();
|
||||
|
||||
this.header.html((0, _utils.getHeaderHTML)(columns));
|
||||
}
|
||||
}, {
|
||||
key: 'renderBody',
|
||||
@ -196,12 +211,15 @@ var DataTable = function () {
|
||||
}, {
|
||||
key: 'renderBodyHTML',
|
||||
value: function renderBodyHTML() {
|
||||
// scrollable body
|
||||
this.bodyScrollable.html('\n <table class="data-table-body table table-bordered">\n ' + (0, _utils.getBodyHTML)(this.data.rows) + '\n </table>\n ');
|
||||
var rows = this.datamanager.getRows();
|
||||
|
||||
this.bodyScrollable.html('\n <table class="data-table-body table table-bordered">\n ' + (0, _utils.getBodyHTML)(rows) + '\n </table>\n ');
|
||||
}
|
||||
}, {
|
||||
key: 'renderBodyWithClusterize',
|
||||
value: function renderBodyWithClusterize() {
|
||||
var self = this;
|
||||
|
||||
// empty body
|
||||
this.bodyScrollable.html('\n <table class="data-table-body table table-bordered">\n ' + (0, _utils.getBodyHTML)([]) + '\n </table>\n ');
|
||||
|
||||
@ -209,12 +227,10 @@ var DataTable = function () {
|
||||
this.pageLength = 1000;
|
||||
this.end = this.start + this.pageLength;
|
||||
|
||||
var initialData = this.getDataForClusterize(
|
||||
// only append ${this.pageLength} rows in the beginning
|
||||
// defer remaining rows
|
||||
this.data.rows.slice(this.start, this.end));
|
||||
|
||||
var self = this;
|
||||
// only append ${this.pageLength} rows in the beginning,
|
||||
// defer remaining
|
||||
var rows = this.datamanager.getRows(this.start, this.end);
|
||||
var initialData = this.getDataForClusterize(rows);
|
||||
|
||||
this.clusterize = new Clusterize({
|
||||
rows: initialData,
|
||||
@ -234,15 +250,16 @@ var DataTable = function () {
|
||||
value: function appendRemainingData() {
|
||||
var dataAppended = this.pageLength;
|
||||
var promises = [];
|
||||
var rowCount = this.datamanager.getRowCount();
|
||||
|
||||
while (dataAppended + this.pageLength < this.data.rows.length) {
|
||||
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 (this.data.rows.length % this.pageLength > 0) {
|
||||
if (rowCount % this.pageLength > 0) {
|
||||
// last page
|
||||
this.start = this.end;
|
||||
this.end = this.start + this.pageLength;
|
||||
@ -260,7 +277,7 @@ var DataTable = function () {
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
setTimeout(function () {
|
||||
var rows = _this.data.rows.slice(start, end);
|
||||
var rows = _this.datamanager.getRows(start, end);
|
||||
var data = _this.getDataForClusterize(rows);
|
||||
|
||||
_this.clusterize.append(data);
|
||||
@ -299,56 +316,6 @@ var DataTable = function () {
|
||||
|
||||
$cell.replaceWith($newCell);
|
||||
}
|
||||
}, {
|
||||
key: 'prepareData',
|
||||
value: function prepareData(data) {
|
||||
// cache original data passed
|
||||
this._data = data;
|
||||
var columns = data.columns,
|
||||
rows = data.rows;
|
||||
|
||||
|
||||
if (this.options.addSerialNoColumn) {
|
||||
var serialNoColumn = {
|
||||
content: 'Sr. No',
|
||||
resizable: false
|
||||
};
|
||||
|
||||
columns.unshift(serialNoColumn);
|
||||
|
||||
rows = rows.map(function (row, i) {
|
||||
var val = i + 1 + '';
|
||||
|
||||
return [val].concat(row);
|
||||
});
|
||||
}
|
||||
|
||||
if (this.options.addCheckbox) {
|
||||
var addCheckboxColumn = {
|
||||
content: '<input type="checkbox" />',
|
||||
resizable: false,
|
||||
sortable: false,
|
||||
editable: false
|
||||
};
|
||||
|
||||
columns.unshift(addCheckboxColumn);
|
||||
|
||||
rows = rows.map(function (row, i) {
|
||||
// make copy of object, else it will be mutated
|
||||
var val = Object.assign({}, addCheckboxColumn);
|
||||
|
||||
return [val].concat(row);
|
||||
});
|
||||
}
|
||||
|
||||
var _columns = (0, _utils.prepareRowHeader)(columns);
|
||||
var _rows = (0, _utils.prepareRows)(rows);
|
||||
|
||||
return {
|
||||
columns: _columns,
|
||||
rows: _rows
|
||||
};
|
||||
}
|
||||
}, {
|
||||
key: 'bindEvents',
|
||||
value: function bindEvents() {
|
||||
@ -657,26 +624,7 @@ var DataTable = function () {
|
||||
var sortAction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'none';
|
||||
|
||||
colIndex = +colIndex;
|
||||
|
||||
this.data.rows.sort(function (a, b) {
|
||||
var _aIndex = a[0].rowIndex;
|
||||
var _bIndex = b[0].rowIndex;
|
||||
var _a = a[colIndex].content;
|
||||
var _b = b[colIndex].content;
|
||||
|
||||
if (sortAction === 'none') {
|
||||
return _aIndex - _bIndex;
|
||||
} else if (sortAction === 'asc') {
|
||||
if (_a < _b) return -1;
|
||||
if (_a > _b) return 1;
|
||||
if (_a === _b) return 0;
|
||||
} else if (sortAction === 'desc') {
|
||||
if (_a < _b) return 1;
|
||||
if (_a > _b) return -1;
|
||||
if (_a === _b) return 0;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
this.datamanager.sortRows(colIndex, sortAction);
|
||||
}
|
||||
}, {
|
||||
key: 'bindCheckbox',
|
||||
@ -707,6 +655,8 @@ var DataTable = function () {
|
||||
}, {
|
||||
key: 'getCheckedRows',
|
||||
value: function getCheckedRows() {
|
||||
this.checkMap = this.checkMap || [];
|
||||
|
||||
return this.checkMap.map(function (c, rowIndex) {
|
||||
if (c) {
|
||||
return rowIndex;
|
||||
@ -1009,7 +959,7 @@ function prepareColumns(columns) {
|
||||
var _columns = columns.map(prepareColumn);
|
||||
|
||||
return _columns.map(function (col) {
|
||||
return Object.assign(col, props);
|
||||
return Object.assign({}, col, props);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1706,6 +1656,229 @@ module.exports = function (css) {
|
||||
|
||||
module.exports = {"name":"frappe-datatable","version":"0.0.1","description":"A modern datatable library for the web","main":"lib/frappe-datatable.js","scripts":{"build":"webpack --env build","dev":"webpack --progress --colors --watch --env dev","test":"mocha --compilers js:babel-core/register --colors ./test/*.spec.js","test:watch":"mocha --compilers js:babel-core/register --colors -w ./test/*.spec.js"},"devDependencies":{"babel-cli":"6.24.1","babel-core":"6.24.1","babel-eslint":"7.2.3","babel-loader":"7.0.0","babel-plugin-add-module-exports":"0.2.1","babel-preset-es2015":"6.24.1","chai":"3.5.0","css-loader":"^0.28.7","eslint":"3.19.0","eslint-loader":"1.7.1","mocha":"3.3.0","node-sass":"^4.5.3","sass-loader":"^6.0.6","style-loader":"^0.18.2","webpack":"^3.1.0","yargs":"7.1.0"},"repository":{"type":"git","url":"https://github.com/frappe/datatable.git"},"keywords":["webpack","es6","starter","library","universal","umd","commonjs"],"author":"Faris Ansari","license":"MIT","bugs":{"url":"https://github.com/frappe/datatable/issues"},"homepage":"https://frappe.github.io/datatable","dependencies":{"bootstrap":"^4.0.0-beta","popper.js":"^1.12.5"}}
|
||||
|
||||
/***/ }),
|
||||
/* 9 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var DataManager = function () {
|
||||
function DataManager(options) {
|
||||
_classCallCheck(this, DataManager);
|
||||
|
||||
this.options = options;
|
||||
this._data = {};
|
||||
this.rowCount = 0;
|
||||
}
|
||||
|
||||
_createClass(DataManager, [{
|
||||
key: 'init',
|
||||
value: function init(data) {
|
||||
var columns = data.columns,
|
||||
rows = data.rows;
|
||||
|
||||
|
||||
this.columns = this.prepareColumns(columns);
|
||||
this.rows = this.prepareRows(rows);
|
||||
}
|
||||
}, {
|
||||
key: 'prepareColumns',
|
||||
value: function prepareColumns(columns) {
|
||||
if (!Array.isArray(columns)) {
|
||||
throw new TypeError('`columns` must be an array');
|
||||
}
|
||||
|
||||
if (this.options.addSerialNoColumn && !this._serialNoColumnAdded) {
|
||||
var val = {
|
||||
content: 'Sr. No',
|
||||
resizable: false
|
||||
};
|
||||
|
||||
columns = [val].concat(columns);
|
||||
this._serialNoColumnAdded = true;
|
||||
}
|
||||
|
||||
if (this.options.addCheckboxColumn && !this._checkboxColumnAdded) {
|
||||
var _val = {
|
||||
content: '<input type="checkbox" />',
|
||||
resizable: false
|
||||
};
|
||||
|
||||
columns = [_val].concat(columns);
|
||||
this._checkboxColumnAdded = true;
|
||||
}
|
||||
|
||||
// wrap the title in span
|
||||
columns = columns.map(function (column) {
|
||||
if (typeof column === 'string') {
|
||||
column = '<span>' + column + '</span>';
|
||||
} else if ((typeof column === 'undefined' ? 'undefined' : _typeof(column)) === 'object') {
|
||||
column.content = '<span>' + column.content + '</span>';
|
||||
}
|
||||
|
||||
return column;
|
||||
});
|
||||
|
||||
return _prepareColumns(columns, {
|
||||
isHeader: 1
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'prepareRows',
|
||||
value: function prepareRows(rows) {
|
||||
var _this = this;
|
||||
|
||||
if (!Array.isArray(rows) || !Array.isArray(rows[0])) {
|
||||
throw new TypeError('`rows` must be an array of arrays');
|
||||
}
|
||||
|
||||
rows = rows.map(function (row, i) {
|
||||
var index = _this._getNextRowCount();
|
||||
|
||||
if (row.length < _this.columns.length) {
|
||||
if (_this._serialNoColumnAdded) {
|
||||
var val = index + 1 + '';
|
||||
|
||||
row = [val].concat(row);
|
||||
}
|
||||
|
||||
if (_this._checkboxColumnAdded) {
|
||||
var _val2 = '<input type="checkbox" />';
|
||||
|
||||
row = [_val2].concat(row);
|
||||
}
|
||||
}
|
||||
|
||||
return prepareRow(row, index);
|
||||
});
|
||||
|
||||
return rows;
|
||||
}
|
||||
}, {
|
||||
key: 'appendRows',
|
||||
value: function appendRows(rows) {
|
||||
if (Array.isArray(rows) && !Array.isArray(rows[0])) {
|
||||
rows = [rows];
|
||||
}
|
||||
var _rows = this.prepareRows(rows);
|
||||
|
||||
this.rows = this.rows.concat(_rows);
|
||||
}
|
||||
}, {
|
||||
key: 'sortRows',
|
||||
value: function sortRows(colIndex, sortAction) {
|
||||
|
||||
this.rows.sort(function (a, b) {
|
||||
var _aIndex = a[0].rowIndex;
|
||||
var _bIndex = b[0].rowIndex;
|
||||
var _a = a[colIndex].content;
|
||||
var _b = b[colIndex].content;
|
||||
|
||||
if (sortAction === 'none') {
|
||||
return _aIndex - _bIndex;
|
||||
} else if (sortAction === 'asc') {
|
||||
if (_a < _b) return -1;
|
||||
if (_a > _b) return 1;
|
||||
if (_a === _b) return 0;
|
||||
} else if (sortAction === 'desc') {
|
||||
if (_a < _b) return 1;
|
||||
if (_a > _b) return -1;
|
||||
if (_a === _b) return 0;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'reverseArray',
|
||||
value: function reverseArray(array) {
|
||||
var left = null;
|
||||
var right = null;
|
||||
|
||||
for (left = 0, right = length - 1; left < right; left += 1, right -= 1) {
|
||||
var temporary = array[left];
|
||||
|
||||
array[left] = array[right];
|
||||
array[right] = temporary;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'getRowCount',
|
||||
value: function getRowCount() {
|
||||
return this.rowCount;
|
||||
}
|
||||
}, {
|
||||
key: '_getNextRowCount',
|
||||
value: function _getNextRowCount() {
|
||||
var val = this.rowCount;
|
||||
|
||||
this.rowCount++;
|
||||
return val;
|
||||
}
|
||||
}, {
|
||||
key: 'getRows',
|
||||
value: function getRows(start, end) {
|
||||
return this.rows.slice(start, end);
|
||||
}
|
||||
}, {
|
||||
key: 'getColumns',
|
||||
value: function getColumns() {
|
||||
return this.columns;
|
||||
}
|
||||
}, {
|
||||
key: 'get',
|
||||
value: function get() {
|
||||
return {
|
||||
columns: this.columns,
|
||||
rows: this.rows
|
||||
};
|
||||
}
|
||||
}]);
|
||||
|
||||
return DataManager;
|
||||
}();
|
||||
|
||||
exports.default = DataManager;
|
||||
|
||||
|
||||
function _prepareColumns(columns) {
|
||||
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
var _columns = columns.map(prepareCell);
|
||||
|
||||
return _columns.map(function (col) {
|
||||
return Object.assign({}, col, props);
|
||||
});
|
||||
}
|
||||
|
||||
function prepareRow(row, i) {
|
||||
return _prepareColumns(row, {
|
||||
rowIndex: i
|
||||
});
|
||||
}
|
||||
|
||||
function prepareCell(col, i) {
|
||||
if (typeof col === 'string') {
|
||||
col = {
|
||||
content: col
|
||||
};
|
||||
}
|
||||
return Object.assign(col, {
|
||||
colIndex: i
|
||||
});
|
||||
}
|
||||
module.exports = exports['default'];
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
177
src/datamanager.js
Normal file
177
src/datamanager.js
Normal file
@ -0,0 +1,177 @@
|
||||
|
||||
export default class DataManager {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
this._data = {};
|
||||
this.rowCount = 0;
|
||||
}
|
||||
|
||||
init(data) {
|
||||
let { columns, rows } = data;
|
||||
|
||||
this.columns = this.prepareColumns(columns);
|
||||
this.rows = this.prepareRows(rows);
|
||||
}
|
||||
|
||||
prepareColumns(columns) {
|
||||
if (!Array.isArray(columns)) {
|
||||
throw new TypeError('`columns` must be an array');
|
||||
}
|
||||
|
||||
if (this.options.addSerialNoColumn && !this._serialNoColumnAdded) {
|
||||
const val = {
|
||||
content: 'Sr. No',
|
||||
resizable: false
|
||||
};
|
||||
|
||||
columns = [val].concat(columns);
|
||||
this._serialNoColumnAdded = true;
|
||||
}
|
||||
|
||||
if (this.options.addCheckboxColumn && !this._checkboxColumnAdded) {
|
||||
const val = {
|
||||
content: '<input type="checkbox" />',
|
||||
resizable: false
|
||||
};
|
||||
|
||||
columns = [val].concat(columns);
|
||||
this._checkboxColumnAdded = true;
|
||||
}
|
||||
|
||||
// wrap the title in span
|
||||
columns = columns.map(column => {
|
||||
if (typeof column === 'string') {
|
||||
column = `<span>${column}</span>`;
|
||||
} else if (typeof column === 'object') {
|
||||
column.content = `<span>${column.content}</span>`;
|
||||
}
|
||||
|
||||
return column;
|
||||
});
|
||||
|
||||
return prepareColumns(columns, {
|
||||
isHeader: 1
|
||||
});
|
||||
}
|
||||
|
||||
prepareRows(rows) {
|
||||
if (!Array.isArray(rows) || !Array.isArray(rows[0])) {
|
||||
throw new TypeError('`rows` must be an array of arrays');
|
||||
}
|
||||
|
||||
rows = rows.map((row, i) => {
|
||||
const index = this._getNextRowCount();
|
||||
|
||||
if (row.length < this.columns.length) {
|
||||
if (this._serialNoColumnAdded) {
|
||||
const val = (index + 1) + '';
|
||||
|
||||
row = [val].concat(row);
|
||||
}
|
||||
|
||||
if (this._checkboxColumnAdded) {
|
||||
const val = '<input type="checkbox" />';
|
||||
|
||||
row = [val].concat(row);
|
||||
}
|
||||
}
|
||||
|
||||
return prepareRow(row, index);
|
||||
});
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
appendRows(rows) {
|
||||
if (Array.isArray(rows) && !Array.isArray(rows[0])) {
|
||||
rows = [rows];
|
||||
}
|
||||
const _rows = this.prepareRows(rows);
|
||||
|
||||
this.rows = this.rows.concat(_rows);
|
||||
}
|
||||
|
||||
sortRows(colIndex, sortAction) {
|
||||
|
||||
this.rows.sort((a, b) => {
|
||||
const _aIndex = a[0].rowIndex;
|
||||
const _bIndex = b[0].rowIndex;
|
||||
const _a = a[colIndex].content;
|
||||
const _b = b[colIndex].content;
|
||||
|
||||
if (sortAction === 'none') {
|
||||
return _aIndex - _bIndex;
|
||||
} else if (sortAction === 'asc') {
|
||||
if (_a < _b) return -1;
|
||||
if (_a > _b) return 1;
|
||||
if (_a === _b) return 0;
|
||||
} else if (sortAction === 'desc') {
|
||||
if (_a < _b) return 1;
|
||||
if (_a > _b) return -1;
|
||||
if (_a === _b) return 0;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
reverseArray(array) {
|
||||
let left = null;
|
||||
let right = null;
|
||||
|
||||
for (left = 0, right = length - 1; left < right; left += 1, right -= 1) {
|
||||
const temporary = array[left];
|
||||
|
||||
array[left] = array[right];
|
||||
array[right] = temporary;
|
||||
}
|
||||
}
|
||||
|
||||
getRowCount() {
|
||||
return this.rowCount;
|
||||
}
|
||||
|
||||
_getNextRowCount() {
|
||||
const val = this.rowCount;
|
||||
|
||||
this.rowCount++;
|
||||
return val;
|
||||
}
|
||||
|
||||
getRows(start, end) {
|
||||
return this.rows.slice(start, end);
|
||||
}
|
||||
|
||||
getColumns() {
|
||||
return this.columns;
|
||||
}
|
||||
|
||||
get() {
|
||||
return {
|
||||
columns: this.columns,
|
||||
rows: this.rows
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function prepareColumns(columns, props = {}) {
|
||||
const _columns = columns.map(prepareCell);
|
||||
|
||||
return _columns.map(col => Object.assign({}, col, props));
|
||||
}
|
||||
|
||||
function prepareRow(row, i) {
|
||||
return prepareColumns(row, {
|
||||
rowIndex: i
|
||||
});
|
||||
}
|
||||
|
||||
function prepareCell(col, i) {
|
||||
if (typeof col === 'string') {
|
||||
col = {
|
||||
content: col
|
||||
};
|
||||
}
|
||||
return Object.assign(col, {
|
||||
colIndex: i
|
||||
});
|
||||
}
|
||||
119
src/datatable.js
119
src/datatable.js
@ -4,11 +4,11 @@ import {
|
||||
getBodyHTML,
|
||||
getRowHTML,
|
||||
getColumnHTML,
|
||||
prepareRowHeader,
|
||||
buildCSSRule,
|
||||
prepareRows,
|
||||
getDefault
|
||||
} from './utils.js';
|
||||
} from './utils';
|
||||
|
||||
import DataManager from './datamanager';
|
||||
|
||||
import './style.scss';
|
||||
|
||||
@ -20,9 +20,9 @@ const DEFAULT_OPTIONS = {
|
||||
},
|
||||
editing: null,
|
||||
addSerialNoColumn: true,
|
||||
addCheckboxColumn: true,
|
||||
enableClusterize: true,
|
||||
enableLogs: false,
|
||||
addCheckbox: true
|
||||
enableLogs: false
|
||||
};
|
||||
|
||||
export default class DataTable {
|
||||
@ -36,6 +36,8 @@ export default class DataTable {
|
||||
this.options = Object.assign({}, DEFAULT_OPTIONS, options);
|
||||
this.events = this.options.events;
|
||||
|
||||
this.datamanager = new DataManager(this.options);
|
||||
|
||||
if (this.options.data) {
|
||||
this.refresh(this.options.data);
|
||||
}
|
||||
@ -63,7 +65,12 @@ export default class DataTable {
|
||||
}
|
||||
|
||||
refresh(data) {
|
||||
this.data = this.prepareData(data);
|
||||
this.datamanager.init(data);
|
||||
this.render();
|
||||
}
|
||||
|
||||
appendRows(rows) {
|
||||
this.datamanager.appendRows(rows);
|
||||
this.render();
|
||||
}
|
||||
|
||||
@ -80,8 +87,9 @@ export default class DataTable {
|
||||
}
|
||||
|
||||
renderHeader() {
|
||||
// fixed header
|
||||
this.header.html(getHeaderHTML(this.data.columns));
|
||||
const columns = this.datamanager.getColumns();
|
||||
|
||||
this.header.html(getHeaderHTML(columns));
|
||||
}
|
||||
|
||||
renderBody() {
|
||||
@ -93,15 +101,18 @@ export default class DataTable {
|
||||
}
|
||||
|
||||
renderBodyHTML() {
|
||||
// scrollable body
|
||||
const rows = this.datamanager.getRows();
|
||||
|
||||
this.bodyScrollable.html(`
|
||||
<table class="data-table-body table table-bordered">
|
||||
${getBodyHTML(this.data.rows)}
|
||||
${getBodyHTML(rows)}
|
||||
</table>
|
||||
`);
|
||||
}
|
||||
|
||||
renderBodyWithClusterize() {
|
||||
const self = this;
|
||||
|
||||
// empty body
|
||||
this.bodyScrollable.html(`
|
||||
<table class="data-table-body table table-bordered">
|
||||
@ -113,13 +124,10 @@ export default class DataTable {
|
||||
this.pageLength = 1000;
|
||||
this.end = this.start + this.pageLength;
|
||||
|
||||
const initialData = this.getDataForClusterize(
|
||||
// only append ${this.pageLength} rows in the beginning
|
||||
// defer remaining rows
|
||||
this.data.rows.slice(this.start, this.end)
|
||||
);
|
||||
|
||||
const self = this;
|
||||
// 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,
|
||||
@ -138,15 +146,16 @@ export default class DataTable {
|
||||
appendRemainingData() {
|
||||
let dataAppended = this.pageLength;
|
||||
const promises = [];
|
||||
const rowCount = this.datamanager.getRowCount();
|
||||
|
||||
while (dataAppended + this.pageLength < this.data.rows.length) {
|
||||
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 (this.data.rows.length % this.pageLength > 0) {
|
||||
if (rowCount % this.pageLength > 0) {
|
||||
// last page
|
||||
this.start = this.end;
|
||||
this.end = this.start + this.pageLength;
|
||||
@ -161,7 +170,7 @@ export default class DataTable {
|
||||
appendNextPagePromise(start, end) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
const rows = this.data.rows.slice(start, end);
|
||||
const rows = this.datamanager.getRows(start, end);
|
||||
const data = this.getDataForClusterize(rows);
|
||||
|
||||
this.clusterize.append(data);
|
||||
@ -195,53 +204,6 @@ export default class DataTable {
|
||||
$cell.replaceWith($newCell);
|
||||
}
|
||||
|
||||
prepareData(data) {
|
||||
// cache original data passed
|
||||
this._data = data;
|
||||
let { columns, rows } = data;
|
||||
|
||||
if (this.options.addSerialNoColumn) {
|
||||
const serialNoColumn = {
|
||||
content: 'Sr. No',
|
||||
resizable: false
|
||||
};
|
||||
|
||||
columns.unshift(serialNoColumn);
|
||||
|
||||
rows = rows.map((row, i) => {
|
||||
const val = (i + 1) + '';
|
||||
|
||||
return [val].concat(row);
|
||||
});
|
||||
}
|
||||
|
||||
if (this.options.addCheckbox) {
|
||||
const addCheckboxColumn = {
|
||||
content: '<input type="checkbox" />',
|
||||
resizable: false,
|
||||
sortable: false,
|
||||
editable: false
|
||||
};
|
||||
|
||||
columns.unshift(addCheckboxColumn);
|
||||
|
||||
rows = rows.map((row, i) => {
|
||||
// make copy of object, else it will be mutated
|
||||
const val = Object.assign({}, addCheckboxColumn);
|
||||
|
||||
return [val].concat(row);
|
||||
});
|
||||
}
|
||||
|
||||
const _columns = prepareRowHeader(columns);
|
||||
const _rows = prepareRows(rows);
|
||||
|
||||
return {
|
||||
columns: _columns,
|
||||
rows: _rows
|
||||
};
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
this.bindFocusCell();
|
||||
this.bindEditCell();
|
||||
@ -519,26 +481,7 @@ export default class DataTable {
|
||||
|
||||
sortRows(colIndex, sortAction = 'none') {
|
||||
colIndex = +colIndex;
|
||||
|
||||
this.data.rows.sort((a, b) => {
|
||||
const _aIndex = a[0].rowIndex;
|
||||
const _bIndex = b[0].rowIndex;
|
||||
const _a = a[colIndex].content;
|
||||
const _b = b[colIndex].content;
|
||||
|
||||
if (sortAction === 'none') {
|
||||
return _aIndex - _bIndex;
|
||||
} else if (sortAction === 'asc') {
|
||||
if (_a < _b) return -1;
|
||||
if (_a > _b) return 1;
|
||||
if (_a === _b) return 0;
|
||||
} else if (sortAction === 'desc') {
|
||||
if (_a < _b) return 1;
|
||||
if (_a > _b) return -1;
|
||||
if (_a === _b) return 0;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
this.datamanager.sortRows(colIndex, sortAction);
|
||||
}
|
||||
|
||||
bindCheckbox() {
|
||||
@ -563,6 +506,8 @@ export default class DataTable {
|
||||
}
|
||||
|
||||
getCheckedRows() {
|
||||
this.checkMap = this.checkMap || [];
|
||||
|
||||
return this.checkMap
|
||||
.map((c, rowIndex) => {
|
||||
if (c) {
|
||||
|
||||
@ -95,7 +95,7 @@ function prepareColumn(col, i) {
|
||||
function prepareColumns(columns, props = {}) {
|
||||
const _columns = columns.map(prepareColumn);
|
||||
|
||||
return _columns.map(col => Object.assign(col, props));
|
||||
return _columns.map(col => Object.assign({}, col, props));
|
||||
}
|
||||
|
||||
function prepareRowHeader(columns) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user