diff --git a/.eslintrc b/.eslintrc
index a0d671b..24853ac 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -21,7 +21,8 @@
"before": true,
"it": true,
"expect": true,
- "sinon": true
+ "sinon": true,
+ "$": true
},
"parser": "babel-eslint",
diff --git a/lib/frappe-datatable.js b/lib/frappe-datatable.js
index 374174d..0f468be 100644
--- a/lib/frappe-datatable.js
+++ b/lib/frappe-datatable.js
@@ -70,7 +70,7 @@ return /******/ (function(modules) { // webpackBootstrap
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
-/******/ return __webpack_require__(__webpack_require__.s = 0);
+/******/ return __webpack_require__(__webpack_require__.s = 1);
/******/ })
/************************************************************************/
/******/ ([
@@ -80,808 +80,6 @@ return /******/ (function(modules) { // webpackBootstrap
"use strict";
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-var _datatable = __webpack_require__(1);
-
-var _datatable2 = _interopRequireDefault(_datatable);
-
-var _package = __webpack_require__(9);
-
-var _package2 = _interopRequireDefault(_package);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-_datatable2.default.__version__ = _package2.default.version;
-
-exports.default = _datatable2.default;
-module.exports = exports['default'];
-
-/***/ }),
-/* 1 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-
-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; }; }(); /* globals $, Clusterize */
-
-
-var _utils = __webpack_require__(2);
-
-var _datamanager = __webpack_require__(3);
-
-var _datamanager2 = _interopRequireDefault(_datamanager);
-
-__webpack_require__(4);
-
-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 = {
- events: null,
- data: {
- columns: [],
- rows: []
- },
- editing: null,
- addSerialNoColumn: true,
- addCheckboxColumn: true,
- enableClusterize: true,
- enableLogs: false,
- takeAvailableSpace: false
-};
-
-var DataTable = function () {
- function DataTable(wrapper, options) {
- _classCallCheck(this, DataTable);
-
- this.wrapper = $(wrapper);
- if (this.wrapper.length === 0) {
- throw new Error('Invalid argument given for `wrapper`');
- }
-
- this.options = Object.assign({}, DEFAULT_OPTIONS, options);
- // custom user events
- this.events = this.options.events;
- // map of checked rows
- this.checkMap = [];
-
- this.datamanager = new _datamanager2.default(this.options);
-
- if (this.options.data) {
- this.refresh(this.options.data);
- }
- }
-
- _createClass(DataTable, [{
- key: 'makeDom',
- value: function makeDom() {
- this.wrapper.html('\n
\n ');
-
- this.header = this.wrapper.find('.data-table-header');
- this.bodyScrollable = this.wrapper.find('.body-scrollable');
- // this.body = this.wrapper.find('.data-table-body');
- this.footer = this.wrapper.find('.data-table-footer');
- }
- }, {
- key: 'refresh',
- value: function refresh(data) {
- this.datamanager.init(data);
- this.render();
- }
- }, {
- key: 'appendRows',
- value: function appendRows(rows) {
- this.datamanager.appendRows(rows);
- this.render();
- }
- }, {
- key: 'render',
- value: function render() {
- if (this.wrapper.find('.data-table').length === 0) {
- this.makeDom();
- this.makeStyle();
- this.bindEvents();
- }
-
- this.renderHeader();
- this.renderBody();
- this.setDimensions();
- }
- }, {
- key: 'renderHeader',
- value: function renderHeader() {
- var columns = this.datamanager.getColumns();
-
- this.header.html((0, _utils.getHeaderHTML)(columns));
- }
- }, {
- key: 'renderBody',
- value: function renderBody() {
- if (this.options.enableClusterize) {
- this.renderBodyWithClusterize();
- } else {
- this.renderBodyHTML();
- }
- }
- }, {
- key: 'renderBodyHTML',
- value: function renderBodyHTML() {
- var rows = this.datamanager.getRows();
-
- this.bodyScrollable.html('\n \n ' + (0, _utils.getBodyHTML)(rows) + '\n
\n ');
- }
- }, {
- key: 'renderBodyWithClusterize',
- value: function renderBodyWithClusterize() {
- var self = this;
-
- // empty body
- this.bodyScrollable.html('\n \n ' + (0, _utils.getBodyHTML)([]) + '\n
\n ');
-
- this.start = 0;
- this.pageLength = 1000;
- this.end = this.start + this.pageLength;
-
- // 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,
- scrollElem: this.bodyScrollable.get(0),
- contentElem: this.bodyScrollable.find('tbody').get(0),
- callbacks: {
- clusterChanged: function clusterChanged() {
- self.highlightCheckedRows();
- }
- }
- });
- this.log('dataAppended', this.pageLength);
- this.appendRemainingData();
- }
- }, {
- key: 'appendRemainingData',
- value: function appendRemainingData() {
- var dataAppended = this.pageLength;
- var promises = [];
- var 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(function (prev, cur) {
- return prev.then(cur);
- }, Promise.resolve());
- }
- }, {
- key: 'appendNextPagePromise',
- value: function appendNextPagePromise(start, end) {
- var _this = this;
-
- return new Promise(function (resolve) {
- setTimeout(function () {
- var rows = _this.datamanager.getRows(start, end);
- var data = _this.getDataForClusterize(rows);
-
- _this.clusterize.append(data);
- _this.log('dataAppended', rows.length);
- resolve();
- }, 0);
- });
- }
- }, {
- key: 'getDataForClusterize',
- value: function getDataForClusterize(rows) {
- return rows.map(function (row) {
- return (0, _utils.getRowHTML)(row, { rowIndex: row[0].rowIndex });
- });
- }
- }, {
- key: 'updateCell',
- value: function updateCell(rowIndex, colIndex, value) {
- var cell = this.getCell(rowIndex, colIndex);
-
- cell.content = value;
- this.refreshCell(cell);
- }
- }, {
- key: 'refreshRows',
- value: function refreshRows() {
- this.renderBody();
- this.setDimensions();
- }
- }, {
- key: 'refreshCell',
- value: function refreshCell(cell) {
- var selector = '.data-table-col[data-row-index="' + cell.rowIndex + '"][data-col-index="' + cell.colIndex + '"]';
- var $cell = this.bodyScrollable.find(selector);
- var $newCell = $((0, _utils.getColumnHTML)(cell));
-
- $cell.replaceWith($newCell);
- }
- }, {
- key: 'bindEvents',
- value: function bindEvents() {
- this.bindFocusCell();
- this.bindEditCell();
- this.bindResizeColumn();
- this.bindSortColumn();
- this.bindCheckbox();
- }
- }, {
- key: 'setDimensions',
- value: function setDimensions() {
- var self = this;
-
- if (!this.options.takeAvailableSpace) {
- // setting width as 0 will ensure that the
- // header doesn't take the available space
- this.header.css({
- width: 0
- });
- }
-
- this.header.css({
- margin: 0
- });
-
- // cache minWidth for each column
- this.minWidthMap = (0, _utils.getDefault)(this.minWidthMap, []);
- this.header.find('.data-table-col').each(function () {
- var col = $(this);
- var width = parseInt(col.find('.content').css('width'), 10);
- var colIndex = col.attr('data-col-index');
-
- if (!self.minWidthMap[colIndex]) {
- // only set this once
- self.minWidthMap[colIndex] = width;
- }
- });
-
- // set initial width as naturally calculated by table's first row
- this.bodyScrollable.find('.data-table-row[data-row-index="0"] .data-table-col').each(function () {
- var $cell = $(this);
- var width = parseInt($cell.find('.content').css('width'), 10);
- var height = parseInt($cell.find('.content').css('height'), 10);
-
- var _self$getCellAttr = self.getCellAttr($cell),
- colIndex = _self$getCellAttr.colIndex;
-
- var minWidth = self.getColumnMinWidth(colIndex);
-
- if (width < minWidth) {
- width = minWidth;
- }
- self.setColumnWidth(colIndex, width);
- self.setDefaultCellHeight(height);
- });
-
- this.setBodyWidth();
-
- this.setStyle('.data-table .body-scrollable', {
- 'margin-top': this.header.height() + 'px'
- });
-
- // center align Sr. No column
- if (this.options.addSerialNoColumn) {
- var index = this.getSerialColumnIndex();
-
- this.setStyle('.data-table [data-col-index="' + index + '"]', {
- 'text-align': 'center'
- });
- }
-
- this.bodyScrollable.find('.table').css('margin', 0);
- }
- }, {
- key: 'bindFocusCell',
- value: function bindFocusCell() {
- var self = this;
-
- this.$focusedCell = null;
- this.bodyScrollable.on('click', '.data-table-col', function () {
- var $cell = $(this);
-
- var _self$getCellAttr2 = self.getCellAttr($cell),
- colIndex = _self$getCellAttr2.colIndex;
-
- if (self.options.addCheckboxColumn && colIndex === 0) {
- return;
- }
-
- self.$focusedCell = $cell;
- self.bodyScrollable.find('.data-table-col').removeClass('selected');
- $cell.addClass('selected');
- });
- }
- }, {
- key: 'bindEditCell',
- value: function bindEditCell() {
- var _this2 = this;
-
- var self = this;
-
- this.$editingCell = null;
- this.bodyScrollable.on('dblclick', '.data-table-col', function () {
- self.activateEditing($(this));
- });
-
- $(document.body).on('keypress', function (e) {
- // enter keypress on focused cell
- if (e.which === 13 && _this2.$focusedCell && !_this2.$editingCell) {
- _this2.activateEditing(_this2.$focusedCell);
- e.stopImmediatePropagation();
- }
- });
-
- $(document.body).on('keypress', function (e) {
- // enter keypress on editing cell
- if (e.which === 13 && _this2.$editingCell) {
- _this2.log('submitCell');
- _this2.submitEditing(_this2.$editingCell);
- e.stopImmediatePropagation();
- }
- });
-
- $(document.body).on('click', function (e) {
- if ($(e.target).is('.edit-cell, .edit-cell *')) return;
- if (!_this2.$editingCell) return;
-
- _this2.$editingCell.removeClass('editing');
- _this2.$editingCell = null;
- });
- }
- }, {
- key: 'activateEditing',
- value: function activateEditing($cell) {
- var _getCellAttr = this.getCellAttr($cell),
- rowIndex = _getCellAttr.rowIndex,
- colIndex = _getCellAttr.colIndex;
-
- var col = this.getColumn(colIndex);
-
- if (col && col.editable === false) {
- return;
- }
-
- if (this.$editingCell) {
- var _getCellAttr2 = this.getCellAttr(this.$editingCell),
- _rowIndex = _getCellAttr2._rowIndex,
- _colIndex = _getCellAttr2._colIndex;
-
- if (rowIndex === _rowIndex && colIndex === _colIndex) {
- // editing the same cell
- return;
- }
- }
-
- this.$editingCell = $cell;
- $cell.addClass('editing');
-
- var $editCell = $cell.find('.edit-cell').empty();
- var cell = this.getCell(rowIndex, colIndex);
- var editing = this.getEditingObject(colIndex, rowIndex, cell.content, $editCell);
-
- if (editing) {
- this.currentCellEditing = editing;
- // initialize editing input with cell value
- editing.initValue(cell.content);
- }
- }
- }, {
- key: 'getEditingObject',
- value: function getEditingObject(colIndex, rowIndex, value, parent) {
- if (this.options.editing) {
- return this.options.editing(colIndex, rowIndex, value, parent);
- }
-
- // editing fallback
- var $input = $('');
-
- parent.append($input);
-
- return {
- initValue: function initValue(value) {
- return $input.val(value);
- },
- getValue: function getValue() {
- return $input.val();
- },
- setValue: function setValue(value) {
- return $input.val(value);
- }
- };
- }
- }, {
- key: 'submitEditing',
- value: function submitEditing($cell) {
- var _this3 = this;
-
- var _getCellAttr3 = this.getCellAttr($cell),
- rowIndex = _getCellAttr3.rowIndex,
- colIndex = _getCellAttr3.colIndex;
-
- if ($cell) {
- var editing = this.currentCellEditing;
-
- if (editing) {
- var value = editing.getValue();
- var done = editing.setValue(value);
-
- if (done && done.then) {
- // wait for promise then update internal state
- done.then(function () {
- return _this3.updateCell(rowIndex, colIndex, value);
- });
- } else {
- this.updateCell(rowIndex, colIndex, value);
- }
- }
- }
-
- this.currentCellEditing = null;
- }
- }, {
- key: 'bindResizeColumn',
- value: function bindResizeColumn() {
- var self = this;
- var isDragging = false;
- var $currCell = void 0,
- startWidth = void 0,
- startX = void 0;
-
- this.header.on('mousedown', '.data-table-col', function (e) {
- $currCell = $(this);
- var colIndex = $currCell.attr('data-col-index');
- var col = self.getColumn(colIndex);
-
- if (col && col.resizable === false) {
- return;
- }
-
- isDragging = true;
- startWidth = $currCell.find('.content').width();
- startX = e.pageX;
- });
-
- $('body').on('mouseup', function (e) {
- if (!$currCell) return;
- isDragging = false;
- var colIndex = $currCell.attr('data-col-index');
-
- if ($currCell) {
- var width = parseInt($currCell.find('.content').css('width'), 10);
-
- self.setColumnWidth(colIndex, width);
- self.setBodyWidth();
- $currCell = null;
- }
- });
-
- $('body').on('mousemove', function (e) {
- if (!isDragging) return;
- var finalWidth = startWidth + (e.pageX - startX);
- var colIndex = $currCell.attr('data-col-index');
-
- if (self.getColumnMinWidth(colIndex) > finalWidth) {
- // don't resize past minWidth
- return;
- }
-
- self.setColumnHeaderWidth(colIndex, finalWidth);
- });
- }
- }, {
- key: 'bindSortColumn',
- value: function bindSortColumn() {
- var self = this;
-
- this.header.on('click', '.data-table-col .content span', function () {
- var $cell = $(this).closest('.data-table-col');
- var sortOrder = (0, _utils.getDefault)($cell.attr('data-sort-order'), 'none');
- var colIndex = $cell.attr('data-col-index');
- var col = self.getColumn(colIndex);
-
- if (col && col.sortable === false) {
- return;
- }
-
- // reset sort indicator
- self.header.find('.sort-indicator').text('');
- self.header.find('.data-table-col').attr('data-sort-order', 'none');
-
- if (sortOrder === 'none') {
- $cell.attr('data-sort-order', 'asc');
- $cell.find('.sort-indicator').text('▲');
- } else if (sortOrder === 'asc') {
- $cell.attr('data-sort-order', 'desc');
- $cell.find('.sort-indicator').text('▼');
- } else if (sortOrder === 'desc') {
- $cell.attr('data-sort-order', 'none');
- $cell.find('.sort-indicator').text('');
- }
-
- // sortWith this action
- sortOrder = $cell.attr('data-sort-order');
-
- if (self.events && self.events.onSort) {
- self.events.onSort(colIndex, sortOrder);
- } else {
- self.sortRows(colIndex, sortOrder);
- self.refreshRows();
- }
- });
- }
- }, {
- key: 'sortRows',
- value: function sortRows(colIndex, sortOrder) {
- this.datamanager.sortRows(colIndex, sortOrder);
- }
- }, {
- key: 'bindCheckbox',
- value: function bindCheckbox() {
- if (!this.options.addCheckboxColumn) return;
- var self = this;
-
- this.wrapper.on('click', '.data-table-col[data-col-index="0"] [type="checkbox"]', function () {
- var $checkbox = $(this);
- var $cell = $checkbox.closest('.data-table-col');
-
- var _self$getCellAttr3 = self.getCellAttr($cell),
- rowIndex = _self$getCellAttr3.rowIndex,
- isHeader = _self$getCellAttr3.isHeader;
-
- var checked = $checkbox.is(':checked');
-
- if (isHeader) {
- self.checkAll(checked);
- } else {
- self.checkRow(rowIndex, checked);
- }
- });
- }
- }, {
- key: 'getCheckedRows',
- value: function getCheckedRows() {
-
- return this.checkMap.map(function (c, rowIndex) {
- if (c) {
- return rowIndex;
- }
- return null;
- }).filter(function (c) {
- return c !== null || c !== undefined;
- });
- }
- }, {
- key: 'highlightCheckedRows',
- value: function highlightCheckedRows() {
- var _this4 = this;
-
- this.getCheckedRows().map(function (rowIndex) {
- return _this4.checkRow(rowIndex, true);
- });
- }
- }, {
- key: 'checkRow',
- value: function checkRow(rowIndex, toggle) {
- var value = toggle ? 1 : 0;
-
- // update internal map
- this.checkMap[rowIndex] = value;
- // set checkbox value explicitly
- this.bodyScrollable.find('.data-table-col[data-row-index="' + rowIndex + '"][data-col-index="0"] [type="checkbox"]').prop('checked', toggle);
- // highlight row
- this.highlightRow(rowIndex, toggle);
- }
- }, {
- key: 'checkAll',
- value: function checkAll(toggle) {
- var value = toggle ? 1 : 0;
-
- // update internal map
- if (toggle) {
- this.checkMap = Array.from(Array(this.getTotalRows())).map(function (c) {
- return value;
- });
- } else {
- this.checkMap = [];
- }
- // set checkbox value
- this.bodyScrollable.find('.data-table-col[data-col-index="0"] [type="checkbox"]').prop('checked', toggle);
- // highlight all
- this.highlightAll(toggle);
- }
- }, {
- key: 'highlightRow',
- value: function highlightRow(rowIndex) {
- var toggle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
-
- var $row = this.bodyScrollable.find('.data-table-row[data-row-index="' + rowIndex + '"]');
-
- if (toggle) {
- $row.addClass('row-highlight');
- } else {
- $row.removeClass('row-highlight');
- }
- }
- }, {
- key: 'highlightAll',
- value: function highlightAll() {
- var toggle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
-
- this.bodyScrollable.find('.data-table-row').toggleClass('row-highlight', toggle);
- }
- }, {
- key: 'setColumnWidth',
- value: function setColumnWidth(colIndex, width) {
- // set width for content
- this.setStyle('[data-col-index="' + colIndex + '"] .content', {
- width: width + 'px'
- });
- // set width for edit cell
- this.setStyle('[data-col-index="' + colIndex + '"] .edit-cell', {
- width: width + 'px'
- });
- }
- }, {
- key: 'setColumnHeaderWidth',
- value: function setColumnHeaderWidth(colIndex, width) {
- this.setStyle('[data-col-index="' + colIndex + '"][data-is-header] .content', {
- width: width + 'px'
- });
- }
- }, {
- key: 'setDefaultCellHeight',
- value: function setDefaultCellHeight(height) {
- this.setStyle('.data-table-col .content', {
- height: height + 'px'
- });
- }
- }, {
- key: 'setRowHeight',
- value: function setRowHeight(rowIndex, height) {
- this.setStyle('[data-row-index="' + rowIndex + '"] .content', {
- height: height + 'px'
- });
- }
- }, {
- key: 'setColumnWidths',
- value: function setColumnWidths() {
- var _this5 = this;
-
- var availableWidth = this.wrapper.width();
- var headerWidth = this.header.width();
-
- if (headerWidth > availableWidth) {
- // don't resize, horizontal scroll takes place
- return;
- }
-
- var columns = this.datamanager.getColumns();
- var deltaWidth = (availableWidth - headerWidth) / this.datamanager.getColumnCount();
-
- columns.map(function (col) {
- var width = _this5.getColumnHeaderElement(col.colIndex).width();
- var finalWidth = width + deltaWidth - 16;
-
- if (_this5.options.addSerialNoColumn && col.colIndex === 0) {
- return;
- }
-
- _this5.setColumnHeaderWidth(col.colIndex, finalWidth);
- _this5.setColumnWidth(col.colIndex, finalWidth);
- });
- this.setBodyWidth();
- }
- }, {
- key: 'setBodyWidth',
- value: function setBodyWidth() {
- this.bodyScrollable.css('width', parseInt(this.header.css('width'), 10));
- }
- }, {
- key: 'setStyle',
- value: function setStyle(rule, styleMap) {
- var styles = this.$style.text();
-
- styles = (0, _utils.buildCSSRule)(rule, styleMap, styles);
- this.$style.html(styles);
- }
- }, {
- key: 'makeStyle',
- value: function makeStyle() {
- this.$style = $('').prependTo(this.wrapper);
- }
- }, {
- key: 'getColumn',
- value: function getColumn(colIndex) {
- return this.datamanager.getColumn(colIndex);
- }
- }, {
- key: 'getRow',
- value: function getRow(rowIndex) {
- return this.datamanager.getRow(rowIndex);
- }
- }, {
- key: 'getCell',
- value: function getCell(rowIndex, colIndex) {
- return this.datamanager.getCell(rowIndex, colIndex);
- }
- }, {
- key: 'getColumnHeaderElement',
- value: function getColumnHeaderElement(colIndex) {
- colIndex = +colIndex;
- if (colIndex < 0) return null;
- return this.wrapper.find('.data-table-col[data-is-header][data-col-index="' + colIndex + '"]');
- }
- }, {
- key: 'getColumnMinWidth',
- value: function getColumnMinWidth(colIndex) {
- colIndex = +colIndex;
- return this.minWidthMap && this.minWidthMap[colIndex];
- }
- }, {
- key: 'getCellAttr',
- value: function getCellAttr($cell) {
- return $cell.data();
- }
- }, {
- key: 'getTotalRows',
- value: function getTotalRows() {
- return this.datamanager.getRowCount();
- }
- }, {
- key: 'getSerialColumnIndex',
- value: function getSerialColumnIndex() {
- var columns = this.datamanager.getColumns();
-
- return columns.findIndex(function (column) {
- return column.content.includes('Sr. No');
- });
- }
- }, {
- key: 'log',
- value: function log() {
- if (this.options.enableLogs) {
- console.log.apply(console, arguments);
- }
- }
- }]);
-
- return DataTable;
-}();
-
-exports.default = DataTable;
-module.exports = exports['default'];
-
-/***/ }),
-/* 2 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-
Object.defineProperty(exports, "__esModule", {
value: true
});
@@ -1060,6 +258,20 @@ function buildCSSRule(rule, styleMap) {
return '' + cssRulesString + getCSSRuleBlock(rule, styleMap);
}
+function removeCSSRule(rule) {
+ var cssRulesString = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
+
+ var rulePatternStr = escapeRegExp(rule) + ' {([^}]*)}';
+ var rulePattern = new RegExp(rulePatternStr, 'g');
+ var output = cssRulesString;
+
+ if (cssRulesString && cssRulesString.match(rulePattern)) {
+ output = cssRulesString.replace(rulePattern, '');
+ }
+
+ return output.trim();
+}
+
exports.default = {
getHeaderHTML: getHeaderHTML,
getBodyHTML: getBodyHTML,
@@ -1071,12 +283,668 @@ exports.default = {
namespaceSelector: namespaceSelector,
getCSSString: getCSSString,
buildCSSRule: buildCSSRule,
+ removeCSSRule: removeCSSRule,
makeDataAttributeString: makeDataAttributeString,
getDefault: getDefault,
escapeRegExp: escapeRegExp
};
module.exports = exports['default'];
+/***/ }),
+/* 1 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _datatable = __webpack_require__(2);
+
+var _datatable2 = _interopRequireDefault(_datatable);
+
+var _package = __webpack_require__(11);
+
+var _package2 = _interopRequireDefault(_package);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+_datatable2.default.__version__ = _package2.default.version;
+
+exports.default = _datatable2.default;
+module.exports = exports['default'];
+
+/***/ }),
+/* 2 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+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; }; }(); /* globals $, Clusterize */
+
+
+var _utils = __webpack_require__(0);
+
+var _datamanager = __webpack_require__(3);
+
+var _datamanager2 = _interopRequireDefault(_datamanager);
+
+var _cellmanager = __webpack_require__(4);
+
+var _cellmanager2 = _interopRequireDefault(_cellmanager);
+
+__webpack_require__(6);
+
+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 = {
+ events: null,
+ data: {
+ columns: [],
+ rows: []
+ },
+ editing: null,
+ addSerialNoColumn: true,
+ addCheckboxColumn: true,
+ enableClusterize: true,
+ enableLogs: false,
+ takeAvailableSpace: false
+};
+
+var DataTable = function () {
+ function DataTable(wrapper, options) {
+ _classCallCheck(this, DataTable);
+
+ this.wrapper = $(wrapper);
+ if (this.wrapper.length === 0) {
+ throw new Error('Invalid argument given for `wrapper`');
+ }
+
+ this.options = Object.assign({}, DEFAULT_OPTIONS, options);
+ // custom user events
+ this.events = this.options.events;
+ // map of checked rows
+ this.checkMap = [];
+
+ // make dom, make style, bind events
+ this.make();
+
+ this.datamanager = new _datamanager2.default(this.options);
+ this.cellmanager = new _cellmanager2.default(this);
+
+ if (this.options.data) {
+ this.refresh(this.options.data);
+ }
+ }
+
+ _createClass(DataTable, [{
+ key: 'make',
+ value: function make() {
+ if (this.wrapper.find('.data-table').length === 0) {
+ this.makeDom();
+ this.makeStyle();
+ this.bindEvents();
+ }
+ }
+ }, {
+ key: 'makeDom',
+ value: function makeDom() {
+ this.wrapper.html('\n \n ');
+
+ this.header = this.wrapper.find('.data-table-header');
+ this.bodyScrollable = this.wrapper.find('.body-scrollable');
+ // this.body = this.wrapper.find('.data-table-body');
+ this.footer = this.wrapper.find('.data-table-footer');
+ this.$borders = this.wrapper.find('.data-table-borders');
+ }
+ }, {
+ key: 'refresh',
+ value: function refresh(data) {
+ this.datamanager.init(data);
+ this.render();
+ }
+ }, {
+ key: 'appendRows',
+ value: function appendRows(rows) {
+ this.datamanager.appendRows(rows);
+ this.render();
+ }
+ }, {
+ key: 'render',
+ value: function render() {
+ this.renderHeader();
+ this.renderBody();
+ this.setDimensions();
+ }
+ }, {
+ key: 'renderHeader',
+ value: function renderHeader() {
+ var columns = this.datamanager.getColumns();
+
+ this.header.html((0, _utils.getHeaderHTML)(columns));
+ }
+ }, {
+ key: 'renderBody',
+ value: function renderBody() {
+ if (this.options.enableClusterize) {
+ this.renderBodyWithClusterize();
+ } else {
+ this.renderBodyHTML();
+ }
+ }
+ }, {
+ key: 'renderBodyHTML',
+ value: function renderBodyHTML() {
+ var rows = this.datamanager.getRows();
+
+ this.bodyScrollable.html('\n \n ' + (0, _utils.getBodyHTML)(rows) + '\n
\n ');
+ }
+ }, {
+ key: 'renderBodyWithClusterize',
+ value: function renderBodyWithClusterize() {
+ var self = this;
+
+ // empty body
+ this.bodyScrollable.html('\n \n ' + (0, _utils.getBodyHTML)([]) + '\n
\n ');
+
+ this.start = 0;
+ this.pageLength = 1000;
+ this.end = this.start + this.pageLength;
+
+ // 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,
+ scrollElem: this.bodyScrollable.get(0),
+ contentElem: this.bodyScrollable.find('tbody').get(0),
+ callbacks: {
+ clusterChanged: function clusterChanged() {
+ self.highlightCheckedRows();
+ }
+ }
+ });
+ this.log('dataAppended', this.pageLength);
+ this.appendRemainingData();
+ }
+ }, {
+ key: 'appendRemainingData',
+ value: function appendRemainingData() {
+ var dataAppended = this.pageLength;
+ var promises = [];
+ var 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(function (prev, cur) {
+ return prev.then(cur);
+ }, Promise.resolve());
+ }
+ }, {
+ key: 'appendNextPagePromise',
+ value: function appendNextPagePromise(start, end) {
+ var _this = this;
+
+ return new Promise(function (resolve) {
+ setTimeout(function () {
+ var rows = _this.datamanager.getRows(start, end);
+ var data = _this.getDataForClusterize(rows);
+
+ _this.clusterize.append(data);
+ _this.log('dataAppended', rows.length);
+ resolve();
+ }, 0);
+ });
+ }
+ }, {
+ key: 'getDataForClusterize',
+ value: function getDataForClusterize(rows) {
+ return rows.map(function (row) {
+ return (0, _utils.getRowHTML)(row, { rowIndex: row[0].rowIndex });
+ });
+ }
+ }, {
+ key: 'refreshRows',
+ value: function refreshRows() {
+ this.renderBody();
+ this.setDimensions();
+ }
+ }, {
+ key: 'bindEvents',
+ value: function bindEvents() {
+ this.bindResizeColumn();
+ this.bindSortColumn();
+ this.bindCheckbox();
+ }
+ }, {
+ key: 'setDimensions',
+ value: function setDimensions() {
+ var self = this;
+
+ if (!this.options.takeAvailableSpace) {
+ // setting width as 0 will ensure that the
+ // header doesn't take the available space
+ this.header.css({
+ width: 0
+ });
+ }
+
+ this.header.css({
+ margin: 0
+ });
+
+ // cache minWidth for each column
+ this.minWidthMap = (0, _utils.getDefault)(this.minWidthMap, []);
+ this.header.find('.data-table-col').each(function () {
+ var col = $(this);
+ var width = parseInt(col.find('.content').css('width'), 10);
+ var colIndex = col.attr('data-col-index');
+
+ if (!self.minWidthMap[colIndex]) {
+ // only set this once
+ self.minWidthMap[colIndex] = width;
+ }
+ });
+
+ // set initial width as naturally calculated by table's first row
+ this.bodyScrollable.find('.data-table-row[data-row-index="0"] .data-table-col').each(function () {
+ var $cell = $(this);
+ var width = parseInt($cell.find('.content').css('width'), 10);
+ var height = parseInt($cell.find('.content').css('height'), 10);
+
+ var _self$getCellAttr = self.getCellAttr($cell),
+ colIndex = _self$getCellAttr.colIndex;
+
+ var minWidth = self.getColumnMinWidth(colIndex);
+
+ if (width < minWidth) {
+ width = minWidth;
+ }
+ self.setColumnWidth(colIndex, width);
+ self.setDefaultCellHeight(height);
+ });
+
+ this.setBodyWidth();
+
+ this.setStyle('.data-table .body-scrollable', {
+ 'margin-top': this.header.height() + 'px'
+ });
+
+ // center align Sr. No column
+ if (this.options.addSerialNoColumn) {
+ var index = this.getSerialColumnIndex();
+
+ this.setStyle('.data-table [data-col-index="' + index + '"]', {
+ 'text-align': 'center'
+ });
+ }
+
+ this.bodyScrollable.find('.table').css('margin', 0);
+ }
+ }, {
+ key: 'bindResizeColumn',
+ value: function bindResizeColumn() {
+ var self = this;
+ var isDragging = false;
+ var $currCell = void 0,
+ startWidth = void 0,
+ startX = void 0;
+
+ this.header.on('mousedown', '.data-table-col', function (e) {
+ $currCell = $(this);
+ var colIndex = $currCell.attr('data-col-index');
+ var col = self.getColumn(colIndex);
+
+ if (col && col.resizable === false) {
+ return;
+ }
+
+ isDragging = true;
+ startWidth = $currCell.find('.content').width();
+ startX = e.pageX;
+ });
+
+ $('body').on('mouseup', function (e) {
+ if (!$currCell) return;
+ isDragging = false;
+ var colIndex = $currCell.attr('data-col-index');
+
+ if ($currCell) {
+ var width = parseInt($currCell.find('.content').css('width'), 10);
+
+ self.setColumnWidth(colIndex, width);
+ self.setBodyWidth();
+ $currCell = null;
+ }
+ });
+
+ $('body').on('mousemove', function (e) {
+ if (!isDragging) return;
+ var finalWidth = startWidth + (e.pageX - startX);
+ var colIndex = $currCell.attr('data-col-index');
+
+ if (self.getColumnMinWidth(colIndex) > finalWidth) {
+ // don't resize past minWidth
+ return;
+ }
+
+ self.setColumnHeaderWidth(colIndex, finalWidth);
+ });
+ }
+ }, {
+ key: 'bindSortColumn',
+ value: function bindSortColumn() {
+ var self = this;
+
+ this.header.on('click', '.data-table-col .content span', function () {
+ var $cell = $(this).closest('.data-table-col');
+ var sortOrder = (0, _utils.getDefault)($cell.attr('data-sort-order'), 'none');
+ var colIndex = $cell.attr('data-col-index');
+ var col = self.getColumn(colIndex);
+
+ if (col && col.sortable === false) {
+ return;
+ }
+
+ // reset sort indicator
+ self.header.find('.sort-indicator').text('');
+ self.header.find('.data-table-col').attr('data-sort-order', 'none');
+
+ if (sortOrder === 'none') {
+ $cell.attr('data-sort-order', 'asc');
+ $cell.find('.sort-indicator').text('▲');
+ } else if (sortOrder === 'asc') {
+ $cell.attr('data-sort-order', 'desc');
+ $cell.find('.sort-indicator').text('▼');
+ } else if (sortOrder === 'desc') {
+ $cell.attr('data-sort-order', 'none');
+ $cell.find('.sort-indicator').text('');
+ }
+
+ // sortWith this action
+ sortOrder = $cell.attr('data-sort-order');
+
+ if (self.events && self.events.onSort) {
+ self.events.onSort(colIndex, sortOrder);
+ } else {
+ self.sortRows(colIndex, sortOrder);
+ self.refreshRows();
+ }
+ });
+ }
+ }, {
+ key: 'sortRows',
+ value: function sortRows(colIndex, sortOrder) {
+ this.datamanager.sortRows(colIndex, sortOrder);
+ }
+ }, {
+ key: 'bindCheckbox',
+ value: function bindCheckbox() {
+ if (!this.options.addCheckboxColumn) return;
+ var self = this;
+
+ this.wrapper.on('click', '.data-table-col[data-col-index="0"] [type="checkbox"]', function () {
+ var $checkbox = $(this);
+ var $cell = $checkbox.closest('.data-table-col');
+
+ var _self$getCellAttr2 = self.getCellAttr($cell),
+ rowIndex = _self$getCellAttr2.rowIndex,
+ isHeader = _self$getCellAttr2.isHeader;
+
+ var checked = $checkbox.is(':checked');
+
+ if (isHeader) {
+ self.checkAll(checked);
+ } else {
+ self.checkRow(rowIndex, checked);
+ }
+ });
+ }
+ }, {
+ key: 'getCheckedRows',
+ value: function getCheckedRows() {
+
+ return this.checkMap.map(function (c, rowIndex) {
+ if (c) {
+ return rowIndex;
+ }
+ return null;
+ }).filter(function (c) {
+ return c !== null || c !== undefined;
+ });
+ }
+ }, {
+ key: 'highlightCheckedRows',
+ value: function highlightCheckedRows() {
+ var _this2 = this;
+
+ this.getCheckedRows().map(function (rowIndex) {
+ return _this2.checkRow(rowIndex, true);
+ });
+ }
+ }, {
+ key: 'checkRow',
+ value: function checkRow(rowIndex, toggle) {
+ var value = toggle ? 1 : 0;
+
+ // update internal map
+ this.checkMap[rowIndex] = value;
+ // set checkbox value explicitly
+ this.bodyScrollable.find('.data-table-col[data-row-index="' + rowIndex + '"][data-col-index="0"] [type="checkbox"]').prop('checked', toggle);
+ // highlight row
+ this.highlightRow(rowIndex, toggle);
+ }
+ }, {
+ key: 'checkAll',
+ value: function checkAll(toggle) {
+ var value = toggle ? 1 : 0;
+
+ // update internal map
+ if (toggle) {
+ this.checkMap = Array.from(Array(this.getTotalRows())).map(function (c) {
+ return value;
+ });
+ } else {
+ this.checkMap = [];
+ }
+ // set checkbox value
+ this.bodyScrollable.find('.data-table-col[data-col-index="0"] [type="checkbox"]').prop('checked', toggle);
+ // highlight all
+ this.highlightAll(toggle);
+ }
+ }, {
+ key: 'highlightRow',
+ value: function highlightRow(rowIndex) {
+ var toggle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
+
+ var $row = this.bodyScrollable.find('.data-table-row[data-row-index="' + rowIndex + '"]');
+
+ if (toggle) {
+ $row.addClass('row-highlight');
+ } else {
+ $row.removeClass('row-highlight');
+ }
+ }
+ }, {
+ key: 'highlightAll',
+ value: function highlightAll() {
+ var toggle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
+
+ this.bodyScrollable.find('.data-table-row').toggleClass('row-highlight', toggle);
+ }
+ }, {
+ key: 'setColumnWidth',
+ value: function setColumnWidth(colIndex, width) {
+ // set width for content
+ this.setStyle('[data-col-index="' + colIndex + '"] .content', {
+ width: width + 'px'
+ });
+ // set width for edit cell
+ this.setStyle('[data-col-index="' + colIndex + '"] .edit-cell', {
+ width: width + 'px'
+ });
+ }
+ }, {
+ key: 'setColumnHeaderWidth',
+ value: function setColumnHeaderWidth(colIndex, width) {
+ this.setStyle('[data-col-index="' + colIndex + '"][data-is-header] .content', {
+ width: width + 'px'
+ });
+ }
+ }, {
+ key: 'setDefaultCellHeight',
+ value: function setDefaultCellHeight(height) {
+ this.setStyle('.data-table-col .content', {
+ height: height + 'px'
+ });
+ }
+ }, {
+ key: 'setRowHeight',
+ value: function setRowHeight(rowIndex, height) {
+ this.setStyle('[data-row-index="' + rowIndex + '"] .content', {
+ height: height + 'px'
+ });
+ }
+ }, {
+ key: 'setColumnWidths',
+ value: function setColumnWidths() {
+ var _this3 = this;
+
+ var availableWidth = this.wrapper.width();
+ var headerWidth = this.header.width();
+
+ if (headerWidth > availableWidth) {
+ // don't resize, horizontal scroll takes place
+ return;
+ }
+
+ var columns = this.datamanager.getColumns();
+ var deltaWidth = (availableWidth - headerWidth) / this.datamanager.getColumnCount();
+
+ columns.map(function (col) {
+ var width = _this3.getColumnHeaderElement(col.colIndex).width();
+ var finalWidth = width + deltaWidth - 16;
+
+ if (_this3.options.addSerialNoColumn && col.colIndex === 0) {
+ return;
+ }
+
+ _this3.setColumnHeaderWidth(col.colIndex, finalWidth);
+ _this3.setColumnWidth(col.colIndex, finalWidth);
+ });
+ this.setBodyWidth();
+ }
+ }, {
+ key: 'setBodyWidth',
+ value: function setBodyWidth() {
+ this.bodyScrollable.css('width', parseInt(this.header.css('width'), 10));
+ }
+ }, {
+ key: 'setStyle',
+ value: function setStyle(rule, styleMap) {
+ var styles = this.$style.text();
+
+ styles = (0, _utils.buildCSSRule)(rule, styleMap, styles);
+ this.$style.html(styles);
+ }
+ }, {
+ key: 'removeStyle',
+ value: function removeStyle(rule) {
+ var styles = this.$style.text();
+
+ styles = (0, _utils.removeCSSRule)(rule, styles);
+ this.$style.html(styles);
+ }
+ }, {
+ key: 'makeStyle',
+ value: function makeStyle() {
+ this.$style = $('').prependTo(this.wrapper);
+ }
+ }, {
+ key: 'getColumn',
+ value: function getColumn(colIndex) {
+ return this.datamanager.getColumn(colIndex);
+ }
+ }, {
+ key: 'getRow',
+ value: function getRow(rowIndex) {
+ return this.datamanager.getRow(rowIndex);
+ }
+ }, {
+ key: 'getCell',
+ value: function getCell(rowIndex, colIndex) {
+ return this.datamanager.getCell(rowIndex, colIndex);
+ }
+ }, {
+ key: 'getColumnHeaderElement',
+ value: function getColumnHeaderElement(colIndex) {
+ colIndex = +colIndex;
+ if (colIndex < 0) return null;
+ return this.wrapper.find('.data-table-col[data-is-header][data-col-index="' + colIndex + '"]');
+ }
+ }, {
+ key: 'getColumnMinWidth',
+ value: function getColumnMinWidth(colIndex) {
+ colIndex = +colIndex;
+ return this.minWidthMap && this.minWidthMap[colIndex];
+ }
+ }, {
+ key: 'getCellAttr',
+ value: function getCellAttr($cell) {
+ return $cell.data();
+ }
+ }, {
+ key: 'getTotalRows',
+ value: function getTotalRows() {
+ return this.datamanager.getRowCount();
+ }
+ }, {
+ key: 'getSerialColumnIndex',
+ value: function getSerialColumnIndex() {
+ var columns = this.datamanager.getColumns();
+
+ return columns.findIndex(function (column) {
+ return column.content.includes('Sr. No');
+ });
+ }
+ }, {
+ key: 'log',
+ value: function log() {
+ if (this.options.enableLogs) {
+ console.log.apply(console, arguments);
+ }
+ }
+ }]);
+
+ return DataTable;
+}();
+
+exports.default = DataTable;
+module.exports = exports['default'];
+
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
@@ -1355,10 +1223,400 @@ module.exports = exports['default'];
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+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; }; }();
+
+var _utils = __webpack_require__(0);
+
+var _keyboard = __webpack_require__(5);
+
+var _keyboard2 = _interopRequireDefault(_keyboard);
+
+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 CellManager = function () {
+ function CellManager(instance) {
+ _classCallCheck(this, CellManager);
+
+ this.instance = instance;
+ this.options = this.instance.options;
+ this.bodyScrollable = this.instance.bodyScrollable;
+
+ this.prepare();
+ this.bindEvents();
+ }
+
+ _createClass(CellManager, [{
+ key: 'prepare',
+ value: function prepare() {
+ this.$borderOutline = this.instance.$borders.find('.border-outline');
+ this.$borderBg = this.instance.$borders.find('.border-background');
+ }
+ }, {
+ key: 'bindEvents',
+ value: function bindEvents() {
+ this.bindFocusCell();
+ this.bindEditCell();
+ this.bindKeyboardNav();
+ }
+ }, {
+ key: 'bindFocusCell',
+ value: function bindFocusCell() {
+ var _this = this;
+
+ var bodyScrollable = this.instance.bodyScrollable;
+
+ this.$focusedCell = null;
+ bodyScrollable.on('click', '.data-table-col', function (e) {
+ _this.focusCell($(e.currentTarget));
+ });
+ }
+ }, {
+ key: 'focusCell',
+ value: function focusCell($cell) {
+ if (!$cell.length) return;
+ this.deactivateEditing();
+
+ var _getCellAttr = this.getCellAttr($cell),
+ colIndex = _getCellAttr.colIndex;
+
+ if (this.options.addCheckboxColumn && colIndex === 0) {
+ return;
+ }
+
+ this.$focusedCell = $cell;
+ this.bodyScrollable.find('.data-table-col').removeClass('selected');
+ $cell.addClass('selected');
+
+ this.highlightRowColumnHeader($cell);
+ }
+ }, {
+ key: 'highlightRowColumnHeader',
+ value: function highlightRowColumnHeader($cell) {
+ var _getCellAttr2 = this.getCellAttr($cell),
+ colIndex = _getCellAttr2.colIndex,
+ rowIndex = _getCellAttr2.rowIndex;
+
+ var _colIndex = this.instance.getSerialColumnIndex();
+ var colHeaderSelector = '.data-table-header .data-table-col[data-col-index="' + colIndex + '"]';
+ var rowHeaderSelector = '.data-table-col[data-row-index="' + rowIndex + '"][data-col-index="' + _colIndex + '"]';
+
+ if (this.lastSelectors) {
+ this.instance.removeStyle(this.lastSelectors.colHeaderSelector);
+ this.instance.removeStyle(this.lastSelectors.rowHeaderSelector);
+ }
+
+ this.instance.setStyle(colHeaderSelector, {
+ 'background-color': 'var(--light-bg)'
+ });
+
+ this.instance.setStyle(rowHeaderSelector, {
+ 'background-color': 'var(--light-bg)'
+ });
+
+ this.lastSelectors = {
+ colHeaderSelector: colHeaderSelector,
+ rowHeaderSelector: rowHeaderSelector
+ };
+ }
+ }, {
+ key: 'bindEditCell',
+ value: function bindEditCell() {
+ var _this2 = this;
+
+ var self = this;
+
+ this.$editingCell = null;
+ this.bodyScrollable.on('dblclick', '.data-table-col', function () {
+ self.activateEditing($(this));
+ });
+
+ _keyboard2.default.on('enter', function (e) {
+ if (_this2.$focusedCell && !_this2.$editingCell) {
+ // enter keypress on focused cell
+ _this2.activateEditing(_this2.$focusedCell);
+ } else if (_this2.$editingCell) {
+ // enter keypress on editing cell
+ _this2.submitEditing(_this2.$editingCell);
+ }
+ });
+
+ $(document.body).on('click', function (e) {
+ if ($(e.target).is('.edit-cell, .edit-cell *')) return;
+ _this2.deactivateEditing();
+ });
+ }
+ }, {
+ key: 'bindKeyboardNav',
+ value: function bindKeyboardNav() {
+ var _this3 = this;
+
+ _keyboard2.default.on('left', function () {
+ if (!_this3.$focusedCell) return;
+
+ _this3.focusCell(_this3.$focusedCell.prev());
+ });
+
+ _keyboard2.default.on('right', function () {
+ if (!_this3.$focusedCell) return;
+
+ _this3.focusCell(_this3.$focusedCell.next());
+ });
+
+ _keyboard2.default.on('up', function () {
+ if (!_this3.$focusedCell) return;
+
+ var _getCellAttr3 = _this3.getCellAttr(_this3.$focusedCell),
+ colIndex = _getCellAttr3.colIndex;
+
+ var $upRow = _this3.$focusedCell.parent().prev();
+ var $upCell = $upRow.find('[data-col-index="' + colIndex + '"]');
+
+ _this3.focusCell($upCell);
+ });
+
+ _keyboard2.default.on('down', function () {
+ if (!_this3.$focusedCell) return;
+
+ var _getCellAttr4 = _this3.getCellAttr(_this3.$focusedCell),
+ colIndex = _getCellAttr4.colIndex;
+
+ var $downRow = _this3.$focusedCell.parent().next();
+ var $downCell = $downRow.find('[data-col-index="' + colIndex + '"]');
+
+ _this3.focusCell($downCell);
+ });
+
+ _keyboard2.default.on('shift+left', function () {
+ if (!_this3.$focusedCell) return;
+
+ // this.focusCell($downCell);
+ });
+
+ _keyboard2.default.on('esc', function () {
+ _this3.deactivateEditing();
+ });
+ }
+ }, {
+ key: 'activateEditing',
+ value: function activateEditing($cell) {
+ var _getCellAttr5 = this.getCellAttr($cell),
+ rowIndex = _getCellAttr5.rowIndex,
+ colIndex = _getCellAttr5.colIndex;
+
+ var col = this.instance.getColumn(colIndex);
+
+ if (col && col.editable === false) {
+ return;
+ }
+
+ if (this.$editingCell) {
+ var _getCellAttr6 = this.getCellAttr(this.$editingCell),
+ _rowIndex = _getCellAttr6._rowIndex,
+ _colIndex = _getCellAttr6._colIndex;
+
+ if (rowIndex === _rowIndex && colIndex === _colIndex) {
+ // editing the same cell
+ return;
+ }
+ }
+
+ this.$editingCell = $cell;
+ $cell.addClass('editing');
+
+ var $editCell = $cell.find('.edit-cell').empty();
+ var cell = this.instance.getCell(rowIndex, colIndex);
+ var editing = this.getEditingObject(colIndex, rowIndex, cell.content, $editCell);
+
+ if (editing) {
+ this.currentCellEditing = editing;
+ // initialize editing input with cell value
+ editing.initValue(cell.content);
+ }
+ }
+ }, {
+ key: 'deactivateEditing',
+ value: function deactivateEditing() {
+ if (!this.$editingCell) return;
+ this.$editingCell.removeClass('editing');
+ this.$editingCell = null;
+ }
+ }, {
+ key: 'getEditingObject',
+ value: function getEditingObject(colIndex, rowIndex, value, parent) {
+ if (this.options.editing) {
+ return this.options.editing(colIndex, rowIndex, value, parent);
+ }
+
+ // editing fallback
+ var $input = $('');
+
+ parent.append($input);
+
+ return {
+ initValue: function initValue(value) {
+ $input.focus();
+ return $input.val(value);
+ },
+ getValue: function getValue() {
+ return $input.val();
+ },
+ setValue: function setValue(value) {
+ return $input.val(value);
+ }
+ };
+ }
+ }, {
+ key: 'submitEditing',
+ value: function submitEditing($cell) {
+ var _this4 = this;
+
+ var _getCellAttr7 = this.getCellAttr($cell),
+ rowIndex = _getCellAttr7.rowIndex,
+ colIndex = _getCellAttr7.colIndex;
+
+ if ($cell) {
+ var editing = this.currentCellEditing;
+
+ if (editing) {
+ var value = editing.getValue();
+ var done = editing.setValue(value);
+
+ if (done && done.then) {
+ // wait for promise then update internal state
+ done.then(function () {
+ return _this4.updateCell(rowIndex, colIndex, value);
+ });
+ } else {
+ this.updateCell(rowIndex, colIndex, value);
+ }
+ }
+ }
+
+ this.currentCellEditing = null;
+ }
+ }, {
+ key: 'updateCell',
+ value: function updateCell(rowIndex, colIndex, value) {
+ var cell = this.getCell(rowIndex, colIndex);
+
+ cell.content = value;
+ this.refreshCell(cell);
+ }
+ }, {
+ key: 'refreshCell',
+ value: function refreshCell(cell) {
+ var selector = '.data-table-col[data-row-index="' + cell.rowIndex + '"][data-col-index="' + cell.colIndex + '"]';
+ var bodyScrollable = this.instance.bodyScrollable;
+ var $cell = bodyScrollable.find(selector);
+ var $newCell = $((0, _utils.getColumnHTML)(cell));
+
+ $cell.replaceWith($newCell);
+ }
+ }, {
+ key: 'getCell',
+ value: function getCell(rowIndex, colIndex) {
+ return this.instance.datamanager.getCell(rowIndex, colIndex);
+ }
+ }, {
+ key: 'getCellAttr',
+ value: function getCellAttr($cell) {
+ return $cell.data();
+ }
+ }]);
+
+ return CellManager;
+}();
+
+exports.default = CellManager;
+module.exports = exports['default'];
+
+/***/ }),
+/* 5 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+var KEYCODES = {
+ 13: 'enter',
+ 91: 'meta',
+ 16: 'shift',
+ 17: 'ctrl',
+ 18: 'alt',
+ 37: 'left',
+ 38: 'up',
+ 39: 'right',
+ 40: 'down',
+ 9: 'tab',
+ 27: 'esc'
+};
+
+var handlers = {};
+
+function bind() {
+ $(document).on('keydown', handler);
+}
+
+function handler(e) {
+ var key = KEYCODES[e.keyCode];
+
+ if (e.shiftKey && key !== 'shift') {
+ key = 'shift+' + key;
+ }
+
+ if (e.ctrlKey && key !== 'ctrl' || e.metaKey && key !== 'meta') {
+ key = 'ctrl+' + key;
+ }
+
+ var _handlers = handlers[key];
+
+ if (_handlers && _handlers.length > 0) {
+ _handlers.map(function (h) {
+ return h();
+ });
+
+ if (!e.isDefaultPrevented()) {
+ e.preventDefault();
+ }
+ }
+}
+
+bind();
+
+exports.default = {
+ on: function on(key, handler) {
+ var keys = key.split(',').map(function (k) {
+ return k.trim();
+ });
+
+ keys.map(function (key) {
+ handlers[key] = handlers[key] || [];
+ handlers[key].push(handler);
+ });
+ }
+};
+module.exports = exports['default'];
+
+/***/ }),
+/* 6 */
+/***/ (function(module, exports, __webpack_require__) {
+
// style-loader: Adds some css to the DOM by adding a ')\n .prependTo(this.wrapper);\n }\n\n getColumn(colIndex) {\n return this.datamanager.getColumn(colIndex);\n }\n\n getRow(rowIndex) {\n return this.datamanager.getRow(rowIndex);\n }\n\n getCell(rowIndex, colIndex) {\n return this.datamanager.getCell(rowIndex, colIndex);\n }\n\n getColumnHeaderElement(colIndex) {\n colIndex = +colIndex;\n if (colIndex < 0) return null;\n return this.wrapper.find(\n `.data-table-col[data-is-header][data-col-index=\"${colIndex}\"]`\n );\n }\n\n getColumnMinWidth(colIndex) {\n colIndex = +colIndex;\n return this.minWidthMap && this.minWidthMap[colIndex];\n }\n\n getCellAttr($cell) {\n return $cell.data();\n }\n\n getTotalRows() {\n return this.datamanager.getRowCount();\n }\n\n getSerialColumnIndex() {\n const columns = this.datamanager.getColumns();\n\n return columns.findIndex(column => column.content.includes('Sr. No'));\n }\n\n log() {\n if (this.options.enableLogs) {\n console.log.apply(console, arguments);\n }\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/datatable.js","function camelCaseToDash(str) {\n return str.replace(/([A-Z])/g, (g) => `-${g[0].toLowerCase()}`);\n}\n\nfunction makeDataAttributeString(props) {\n const keys = Object.keys(props);\n\n return keys\n .map((key) => {\n const _key = camelCaseToDash(key);\n const val = props[key];\n\n if (val === undefined) return '';\n return `data-${_key}=\"${val}\" `;\n })\n .join('')\n .trim();\n}\n\nfunction getEditCellHTML() {\n return `\n \n `;\n}\n\nfunction getColumnHTML(column) {\n const { rowIndex, colIndex, isHeader } = column;\n const dataAttr = makeDataAttributeString({\n rowIndex,\n colIndex,\n isHeader\n });\n\n const editCellHTML = isHeader ? '' : getEditCellHTML();\n\n return `\n \n \n ${column.format ? column.format(column.content) : column.content}\n \n \n ${editCellHTML}\n | \n `;\n}\n\nfunction getRowHTML(columns, props) {\n const dataAttr = makeDataAttributeString(props);\n\n return `\n \n ${columns.map(getColumnHTML).join('')}\n
\n `;\n}\n\nfunction getHeaderHTML(columns) {\n const $header = `\n \n ${getRowHTML(columns, { isHeader: 1, rowIndex: -1 })}\n \n `;\n\n // columns.map(col => {\n // if (!col.width) return;\n // const $cellContent = $header.find(\n // `.data-table-col[data-col-index=\"${col.colIndex}\"] .content`\n // );\n\n // $cellContent.width(col.width);\n // });\n\n return $header;\n}\n\nfunction getBodyHTML(rows) {\n return `\n \n ${rows.map(row => getRowHTML(row, { rowIndex: row[0].rowIndex })).join('')}\n \n `;\n}\n\nfunction prepareColumn(col, i) {\n if (typeof col === 'string') {\n col = {\n content: col\n };\n }\n return Object.assign(col, {\n colIndex: i\n });\n}\n\nfunction prepareColumns(columns, props = {}) {\n const _columns = columns.map(prepareColumn);\n\n return _columns.map(col => Object.assign({}, col, props));\n}\n\nfunction prepareRowHeader(columns) {\n return prepareColumns(columns, {\n rowIndex: -1,\n isHeader: 1,\n format: (content) => `${content}`\n });\n}\n\nfunction prepareRow(row, i) {\n return prepareColumns(row, {\n rowIndex: i\n });\n}\n\nfunction prepareRows(rows) {\n return rows.map(prepareRow);\n}\n\nfunction getDefault(a, b) {\n return a !== undefined ? a : b;\n}\n\nfunction escapeRegExp(str) {\n // https://stackoverflow.com/a/6969486\n return str.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, '\\\\$&');\n}\n\nfunction getCSSString(styleMap) {\n let style = '';\n\n for (const prop in styleMap) {\n if (styleMap.hasOwnProperty(prop)) {\n style += `${prop}: ${styleMap[prop]}; `;\n }\n }\n\n return style.trim();\n}\n\nfunction getCSSRuleBlock(rule, styleMap) {\n return `${rule} { ${getCSSString(styleMap)} }`;\n}\n\nfunction namespaceSelector(selector) {\n return '.data-table ' + selector;\n}\n\nfunction buildCSSRule(rule, styleMap, cssRulesString = '') {\n // build css rules efficiently,\n // append new rule if doesnt exist,\n // update existing ones\n\n const rulePatternStr = `${escapeRegExp(rule)} {([^}]*)}`;\n const rulePattern = new RegExp(rulePatternStr, 'g');\n\n if (cssRulesString && cssRulesString.match(rulePattern)) {\n for (const property in styleMap) {\n const value = styleMap[property];\n const propPattern = new RegExp(`${escapeRegExp(property)}:([^;]*);`);\n\n cssRulesString = cssRulesString.replace(rulePattern, function (match, propertyStr) {\n if (propertyStr.match(propPattern)) {\n // property exists, replace value with new value\n propertyStr = propertyStr.replace(propPattern, (match, valueStr) => {\n return `${property}: ${value};`;\n });\n }\n propertyStr = propertyStr.trim();\n\n const replacer =\n `${rule} { ${propertyStr} }`;\n\n return replacer;\n });\n }\n\n return cssRulesString;\n }\n // no match, append new rule block\n return `${cssRulesString}${getCSSRuleBlock(rule, styleMap)}`;\n}\n\nexport default {\n getHeaderHTML,\n getBodyHTML,\n getRowHTML,\n getColumnHTML,\n getEditCellHTML,\n prepareRowHeader,\n prepareRows,\n namespaceSelector,\n getCSSString,\n buildCSSRule,\n makeDataAttributeString,\n getDefault,\n escapeRegExp\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/utils.js","\nexport default class DataManager {\n constructor(options) {\n this.options = options;\n this.rowCount = 0;\n this.currentSort = {\n sortBy: -1, // colIndex\n sortOrder: 'none' // asc, desc, none\n };\n }\n\n init(data) {\n let { columns, rows } = data;\n\n this.columns = this.prepareColumns(columns);\n this.rows = this.prepareRows(rows);\n }\n\n prepareColumns(columns) {\n if (!Array.isArray(columns)) {\n throw new TypeError('`columns` must be an array');\n }\n\n if (this.options.addSerialNoColumn && !this._serialNoColumnAdded) {\n const val = {\n content: 'Sr. No',\n editable: false,\n resizable: false\n };\n\n columns = [val].concat(columns);\n this._serialNoColumnAdded = true;\n }\n\n if (this.options.addCheckboxColumn && !this._checkboxColumnAdded) {\n const val = {\n content: '',\n editable: false,\n resizable: false\n };\n\n columns = [val].concat(columns);\n this._checkboxColumnAdded = true;\n }\n\n // wrap the title in span\n columns = columns.map(column => {\n if (typeof column === 'string') {\n column = `${column}`;\n } else if (typeof column === 'object') {\n column.content = `${column.content}`;\n }\n\n return column;\n });\n\n return prepareColumns(columns, {\n isHeader: 1\n });\n }\n\n prepareRows(rows) {\n if (!Array.isArray(rows) || !Array.isArray(rows[0])) {\n throw new TypeError('`rows` must be an array of arrays');\n }\n\n rows = rows.map((row, i) => {\n const index = this._getNextRowCount();\n\n if (row.length < this.columns.length) {\n if (this._serialNoColumnAdded) {\n const val = (index + 1) + '';\n\n row = [val].concat(row);\n }\n\n if (this._checkboxColumnAdded) {\n const val = '';\n\n row = [val].concat(row);\n }\n }\n\n return prepareRow(row, index);\n });\n\n return rows;\n }\n\n appendRows(rows) {\n if (Array.isArray(rows) && !Array.isArray(rows[0])) {\n rows = [rows];\n }\n const _rows = this.prepareRows(rows);\n\n this.rows = this.rows.concat(_rows);\n }\n\n sortRows(colIndex, sortOrder = 'none') {\n colIndex = +colIndex;\n\n if (this.currentSort.colIndex === colIndex) {\n // reverse the array if only sortOrder changed\n if (\n (this.currentSort.sortOrder === 'asc' && sortOrder === 'desc') ||\n (this.currentSort.sortOrder === 'desc' && sortOrder === 'asc')\n ) {\n this.reverseArray(this.rows);\n this.currentSort.sortOrder = sortOrder;\n return;\n }\n }\n\n this.rows.sort((a, b) => {\n const _aIndex = a[0].rowIndex;\n const _bIndex = b[0].rowIndex;\n const _a = a[colIndex].content;\n const _b = b[colIndex].content;\n\n if (sortOrder === 'none') {\n return _aIndex - _bIndex;\n } else if (sortOrder === 'asc') {\n if (_a < _b) return -1;\n if (_a > _b) return 1;\n if (_a === _b) return 0;\n } else if (sortOrder === 'desc') {\n if (_a < _b) return 1;\n if (_a > _b) return -1;\n if (_a === _b) return 0;\n }\n return 0;\n });\n\n this.currentSort.colIndex = colIndex;\n this.currentSort.sortOrder = sortOrder;\n }\n\n reverseArray(array) {\n let left = null;\n let right = null;\n let length = array.length;\n\n for (left = 0, right = length - 1; left < right; left += 1, right -= 1) {\n const temporary = array[left];\n\n array[left] = array[right];\n array[right] = temporary;\n }\n }\n\n getRowCount() {\n return this.rowCount;\n }\n\n _getNextRowCount() {\n const val = this.rowCount;\n\n this.rowCount++;\n return val;\n }\n\n getRows(start, end) {\n return this.rows.slice(start, end);\n }\n\n getColumns() {\n return this.columns;\n }\n\n getColumnCount() {\n return this.columns.length;\n }\n\n getColumn(colIndex) {\n colIndex = +colIndex;\n return this.columns.find(col => col.colIndex === colIndex);\n }\n\n getRow(rowIndex) {\n rowIndex = +rowIndex;\n return this.rows.find(row => row[0].rowIndex === rowIndex);\n }\n\n getCell(rowIndex, colIndex) {\n rowIndex = +rowIndex;\n colIndex = +colIndex;\n return this.rows.find(row => row[0].rowIndex === rowIndex)[colIndex];\n }\n\n get() {\n return {\n columns: this.columns,\n rows: this.rows\n };\n }\n}\n\nfunction prepareColumns(columns, props = {}) {\n const _columns = columns.map(prepareCell);\n\n return _columns.map(col => Object.assign({}, col, props));\n}\n\nfunction prepareRow(row, i) {\n return prepareColumns(row, {\n rowIndex: i\n });\n}\n\nfunction prepareCell(col, i) {\n if (typeof col === 'string') {\n col = {\n content: col\n };\n }\n return Object.assign(col, {\n colIndex: i\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/datamanager.js","// style-loader: Adds some css to the DOM by adding a ')\n .prependTo(this.wrapper);\n }\n\n getColumn(colIndex) {\n return this.datamanager.getColumn(colIndex);\n }\n\n getRow(rowIndex) {\n return this.datamanager.getRow(rowIndex);\n }\n\n getCell(rowIndex, colIndex) {\n return this.datamanager.getCell(rowIndex, colIndex);\n }\n\n getColumnHeaderElement(colIndex) {\n colIndex = +colIndex;\n if (colIndex < 0) return null;\n return this.wrapper.find(\n `.data-table-col[data-is-header][data-col-index=\"${colIndex}\"]`\n );\n }\n\n getColumnMinWidth(colIndex) {\n colIndex = +colIndex;\n return this.minWidthMap && this.minWidthMap[colIndex];\n }\n\n getCellAttr($cell) {\n return $cell.data();\n }\n\n getTotalRows() {\n return this.datamanager.getRowCount();\n }\n\n getSerialColumnIndex() {\n const columns = this.datamanager.getColumns();\n\n return columns.findIndex(column => column.content.includes('Sr. No'));\n }\n\n log() {\n if (this.options.enableLogs) {\n console.log.apply(console, arguments);\n }\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/datatable.js","\nexport default class DataManager {\n constructor(options) {\n this.options = options;\n this.rowCount = 0;\n this.currentSort = {\n sortBy: -1, // colIndex\n sortOrder: 'none' // asc, desc, none\n };\n }\n\n init(data) {\n let { columns, rows } = data;\n\n this.columns = this.prepareColumns(columns);\n this.rows = this.prepareRows(rows);\n }\n\n prepareColumns(columns) {\n if (!Array.isArray(columns)) {\n throw new TypeError('`columns` must be an array');\n }\n\n if (this.options.addSerialNoColumn && !this._serialNoColumnAdded) {\n const val = {\n content: 'Sr. No',\n editable: false,\n resizable: false\n };\n\n columns = [val].concat(columns);\n this._serialNoColumnAdded = true;\n }\n\n if (this.options.addCheckboxColumn && !this._checkboxColumnAdded) {\n const val = {\n content: '',\n editable: false,\n resizable: false\n };\n\n columns = [val].concat(columns);\n this._checkboxColumnAdded = true;\n }\n\n // wrap the title in span\n columns = columns.map(column => {\n if (typeof column === 'string') {\n column = `${column}`;\n } else if (typeof column === 'object') {\n column.content = `${column.content}`;\n }\n\n return column;\n });\n\n return prepareColumns(columns, {\n isHeader: 1\n });\n }\n\n prepareRows(rows) {\n if (!Array.isArray(rows) || !Array.isArray(rows[0])) {\n throw new TypeError('`rows` must be an array of arrays');\n }\n\n rows = rows.map((row, i) => {\n const index = this._getNextRowCount();\n\n if (row.length < this.columns.length) {\n if (this._serialNoColumnAdded) {\n const val = (index + 1) + '';\n\n row = [val].concat(row);\n }\n\n if (this._checkboxColumnAdded) {\n const val = '';\n\n row = [val].concat(row);\n }\n }\n\n return prepareRow(row, index);\n });\n\n return rows;\n }\n\n appendRows(rows) {\n if (Array.isArray(rows) && !Array.isArray(rows[0])) {\n rows = [rows];\n }\n const _rows = this.prepareRows(rows);\n\n this.rows = this.rows.concat(_rows);\n }\n\n sortRows(colIndex, sortOrder = 'none') {\n colIndex = +colIndex;\n\n if (this.currentSort.colIndex === colIndex) {\n // reverse the array if only sortOrder changed\n if (\n (this.currentSort.sortOrder === 'asc' && sortOrder === 'desc') ||\n (this.currentSort.sortOrder === 'desc' && sortOrder === 'asc')\n ) {\n this.reverseArray(this.rows);\n this.currentSort.sortOrder = sortOrder;\n return;\n }\n }\n\n this.rows.sort((a, b) => {\n const _aIndex = a[0].rowIndex;\n const _bIndex = b[0].rowIndex;\n const _a = a[colIndex].content;\n const _b = b[colIndex].content;\n\n if (sortOrder === 'none') {\n return _aIndex - _bIndex;\n } else if (sortOrder === 'asc') {\n if (_a < _b) return -1;\n if (_a > _b) return 1;\n if (_a === _b) return 0;\n } else if (sortOrder === 'desc') {\n if (_a < _b) return 1;\n if (_a > _b) return -1;\n if (_a === _b) return 0;\n }\n return 0;\n });\n\n this.currentSort.colIndex = colIndex;\n this.currentSort.sortOrder = sortOrder;\n }\n\n reverseArray(array) {\n let left = null;\n let right = null;\n let length = array.length;\n\n for (left = 0, right = length - 1; left < right; left += 1, right -= 1) {\n const temporary = array[left];\n\n array[left] = array[right];\n array[right] = temporary;\n }\n }\n\n getRowCount() {\n return this.rowCount;\n }\n\n _getNextRowCount() {\n const val = this.rowCount;\n\n this.rowCount++;\n return val;\n }\n\n getRows(start, end) {\n return this.rows.slice(start, end);\n }\n\n getColumns() {\n return this.columns;\n }\n\n getColumnCount() {\n return this.columns.length;\n }\n\n getColumn(colIndex) {\n colIndex = +colIndex;\n return this.columns.find(col => col.colIndex === colIndex);\n }\n\n getRow(rowIndex) {\n rowIndex = +rowIndex;\n return this.rows.find(row => row[0].rowIndex === rowIndex);\n }\n\n getCell(rowIndex, colIndex) {\n rowIndex = +rowIndex;\n colIndex = +colIndex;\n return this.rows.find(row => row[0].rowIndex === rowIndex)[colIndex];\n }\n\n get() {\n return {\n columns: this.columns,\n rows: this.rows\n };\n }\n}\n\nfunction prepareColumns(columns, props = {}) {\n const _columns = columns.map(prepareCell);\n\n return _columns.map(col => Object.assign({}, col, props));\n}\n\nfunction prepareRow(row, i) {\n return prepareColumns(row, {\n rowIndex: i\n });\n}\n\nfunction prepareCell(col, i) {\n if (typeof col === 'string') {\n col = {\n content: col\n };\n }\n return Object.assign(col, {\n colIndex: i\n });\n}\n\n\n\n// WEBPACK FOOTER //\n// ./src/datamanager.js","import { getColumnHTML } from './utils';\nimport keyboard from 'keyboard';\n\nexport default class CellManager {\n constructor(instance) {\n this.instance = instance;\n this.options = this.instance.options;\n this.bodyScrollable = this.instance.bodyScrollable;\n\n this.prepare();\n this.bindEvents();\n }\n\n prepare() {\n this.$borderOutline = this.instance.$borders.find('.border-outline');\n this.$borderBg = this.instance.$borders.find('.border-background');\n }\n\n bindEvents() {\n this.bindFocusCell();\n this.bindEditCell();\n this.bindKeyboardNav();\n }\n\n bindFocusCell() {\n const bodyScrollable = this.instance.bodyScrollable;\n\n this.$focusedCell = null;\n bodyScrollable.on('click', '.data-table-col', (e) => {\n this.focusCell($(e.currentTarget));\n });\n }\n\n focusCell($cell) {\n if (!$cell.length) return;\n this.deactivateEditing();\n\n const { colIndex } = this.getCellAttr($cell);\n\n if (this.options.addCheckboxColumn && colIndex === 0) {\n return;\n }\n\n this.$focusedCell = $cell;\n this.bodyScrollable.find('.data-table-col').removeClass('selected');\n $cell.addClass('selected');\n\n this.highlightRowColumnHeader($cell);\n }\n\n highlightRowColumnHeader($cell) {\n const { colIndex, rowIndex } = this.getCellAttr($cell);\n const _colIndex = this.instance.getSerialColumnIndex();\n const colHeaderSelector = `.data-table-header .data-table-col[data-col-index=\"${colIndex}\"]`;\n const rowHeaderSelector = `.data-table-col[data-row-index=\"${rowIndex}\"][data-col-index=\"${_colIndex}\"]`;\n\n if (this.lastSelectors) {\n this.instance.removeStyle(this.lastSelectors.colHeaderSelector);\n this.instance.removeStyle(this.lastSelectors.rowHeaderSelector);\n }\n\n this.instance.setStyle(colHeaderSelector, {\n 'background-color': 'var(--light-bg)'\n });\n\n this.instance.setStyle(rowHeaderSelector, {\n 'background-color': 'var(--light-bg)'\n });\n\n this.lastSelectors = {\n colHeaderSelector,\n rowHeaderSelector\n };\n }\n\n bindEditCell() {\n const self = this;\n\n this.$editingCell = null;\n this.bodyScrollable.on('dblclick', '.data-table-col', function () {\n self.activateEditing($(this));\n });\n\n keyboard.on('enter', (e) => {\n if (this.$focusedCell && !this.$editingCell) {\n // enter keypress on focused cell\n this.activateEditing(this.$focusedCell);\n } else if (this.$editingCell) {\n // enter keypress on editing cell\n this.submitEditing(this.$editingCell);\n }\n });\n\n $(document.body).on('click', e => {\n if ($(e.target).is('.edit-cell, .edit-cell *')) return;\n this.deactivateEditing();\n });\n }\n\n bindKeyboardNav() {\n keyboard.on('left', () => {\n if (!this.$focusedCell) return;\n\n this.focusCell(this.$focusedCell.prev());\n });\n\n keyboard.on('right', () => {\n if (!this.$focusedCell) return;\n\n this.focusCell(this.$focusedCell.next());\n });\n\n keyboard.on('up', () => {\n if (!this.$focusedCell) return;\n\n const { colIndex } = this.getCellAttr(this.$focusedCell);\n const $upRow = this.$focusedCell.parent().prev();\n const $upCell = $upRow.find(`[data-col-index=\"${colIndex}\"]`);\n\n this.focusCell($upCell);\n });\n\n keyboard.on('down', () => {\n if (!this.$focusedCell) return;\n\n const { colIndex } = this.getCellAttr(this.$focusedCell);\n const $downRow = this.$focusedCell.parent().next();\n const $downCell = $downRow.find(`[data-col-index=\"${colIndex}\"]`);\n\n this.focusCell($downCell);\n });\n\n keyboard.on('shift+left', () => {\n if (!this.$focusedCell) return;\n\n // this.focusCell($downCell);\n });\n\n keyboard.on('esc', () => {\n this.deactivateEditing();\n });\n }\n\n activateEditing($cell) {\n const { rowIndex, colIndex } = this.getCellAttr($cell);\n const col = this.instance.getColumn(colIndex);\n\n if (col && col.editable === false) {\n return;\n }\n\n if (this.$editingCell) {\n const { _rowIndex, _colIndex } = this.getCellAttr(this.$editingCell);\n\n if (rowIndex === _rowIndex && colIndex === _colIndex) {\n // editing the same cell\n return;\n }\n }\n\n this.$editingCell = $cell;\n $cell.addClass('editing');\n\n const $editCell = $cell.find('.edit-cell').empty();\n const cell = this.instance.getCell(rowIndex, colIndex);\n const editing = this.getEditingObject(colIndex, rowIndex, cell.content, $editCell);\n\n if (editing) {\n this.currentCellEditing = editing;\n // initialize editing input with cell value\n editing.initValue(cell.content);\n }\n }\n\n deactivateEditing() {\n if (!this.$editingCell) return;\n this.$editingCell.removeClass('editing');\n this.$editingCell = null;\n }\n\n getEditingObject(colIndex, rowIndex, value, parent) {\n if (this.options.editing) {\n return this.options.editing(colIndex, rowIndex, value, parent);\n }\n\n // editing fallback\n const $input = $('');\n\n parent.append($input);\n\n return {\n initValue(value) {\n $input.focus();\n return $input.val(value);\n },\n getValue() {\n return $input.val();\n },\n setValue(value) {\n return $input.val(value);\n }\n };\n }\n\n submitEditing($cell) {\n const { rowIndex, colIndex } = this.getCellAttr($cell);\n\n if ($cell) {\n const editing = this.currentCellEditing;\n\n if (editing) {\n const value = editing.getValue();\n const done = editing.setValue(value);\n\n if (done && done.then) {\n // wait for promise then update internal state\n done.then(\n () => this.updateCell(rowIndex, colIndex, value)\n );\n } else {\n this.updateCell(rowIndex, colIndex, value);\n }\n }\n }\n\n this.currentCellEditing = null;\n }\n\n updateCell(rowIndex, colIndex, value) {\n const cell = this.getCell(rowIndex, colIndex);\n\n cell.content = value;\n this.refreshCell(cell);\n }\n\n refreshCell(cell) {\n const selector = `.data-table-col[data-row-index=\"${cell.rowIndex}\"][data-col-index=\"${cell.colIndex}\"]`;\n const bodyScrollable = this.instance.bodyScrollable;\n const $cell = bodyScrollable.find(selector);\n const $newCell = $(getColumnHTML(cell));\n\n $cell.replaceWith($newCell);\n }\n\n getCell(rowIndex, colIndex) {\n return this.instance.datamanager.getCell(rowIndex, colIndex);\n }\n\n getCellAttr($cell) {\n return $cell.data();\n }\n}\n\n\n\n\n// WEBPACK FOOTER //\n// ./src/cellmanager.js","const KEYCODES = {\n 13: 'enter',\n 91: 'meta',\n 16: 'shift',\n 17: 'ctrl',\n 18: 'alt',\n 37: 'left',\n 38: 'up',\n 39: 'right',\n 40: 'down',\n 9: 'tab',\n 27: 'esc'\n};\n\nconst handlers = {};\n\nfunction bind() {\n $(document).on('keydown', handler);\n}\n\nfunction handler(e) {\n let key = KEYCODES[e.keyCode];\n\n if (e.shiftKey && key !== 'shift') {\n key = 'shift+' + key;\n }\n\n if ((e.ctrlKey && key !== 'ctrl') || (e.metaKey && key !== 'meta')) {\n key = 'ctrl+' + key;\n }\n\n const _handlers = handlers[key];\n\n if (_handlers && _handlers.length > 0) {\n _handlers.map(h => h());\n\n if (!e.isDefaultPrevented()) {\n e.preventDefault();\n }\n }\n}\n\nbind();\n\nexport default {\n on(key, handler) {\n const keys = key.split(',').map(k => k.trim());\n\n keys.map(key => {\n handlers[key] = handlers[key] || [];\n handlers[key].push(handler);\n });\n }\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/keyboard.js","// style-loader: Adds some css to the DOM by adding a