diff --git a/package.json b/package.json
index b8bfbfb..946dc3e 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"cy:open": "cypress open",
"cy:run": "cypress run",
"test": "start-server-and-test cy:server http://localhost:8989 cy:run",
+ "test-local": "start-server-and-test cy:server http://localhost:8989 cy:open",
"travis-deploy-once": "travis-deploy-once",
"semantic-release": "semantic-release",
"lint": "eslint src",
@@ -64,7 +65,7 @@
},
"homepage": "https://frappe.github.io/datatable",
"dependencies": {
- "clusterize.js": "^0.18.0",
+ "hyperlist": "^1.0.0-beta",
"lodash": "^4.17.5",
"sortablejs": "^1.7.0"
},
diff --git a/src/body-renderer.js b/src/body-renderer.js
index 33348fc..d092601 100644
--- a/src/body-renderer.js
+++ b/src/body-renderer.js
@@ -1,6 +1,5 @@
-import Clusterize from 'clusterize.js';
+import HyperList from 'hyperlist';
import $ from './dom';
-import { nextTick } from './utils';
export default class BodyRenderer {
constructor(instance) {
@@ -11,59 +10,45 @@ export default class BodyRenderer {
this.cellmanager = instance.cellmanager;
this.bodyScrollable = instance.bodyScrollable;
this.log = instance.log;
- this.appendRemainingData = nextTick(this.appendRemainingData, this);
+ }
+
+ renderRows(rows) {
+ let config = {
+ itemHeight: 40,
+ total: rows.length,
+ generate: (index) => {
+ const el = document.createElement('div');
+ const rowHTML = this.rowmanager.getRowHTML(rows[index], rows[index].meta);
+ el.innerHTML = rowHTML;
+ return el.children[0];
+ }
+ };
+ this.hyperlist.refresh($('.dt-body', this.bodyScrollable), config);
}
render() {
- if (this.options.clusterize) {
- this.renderBodyWithClusterize();
- } else {
- this.renderBodyHTML();
- }
- }
-
- renderBodyHTML() {
const rows = this.datamanager.getRowsForView();
- this.bodyScrollable.innerHTML = this.getBodyHTML(rows);
- this.instance.setDimensions();
- this.restoreState();
- }
+ let config = {
+ itemHeight: 40,
+ total: rows.length,
+ generate: (index) => {
+ const el = document.createElement('div');
+ const rowHTML = this.rowmanager.getRowHTML(rows[index], rows[index].meta);
+ el.innerHTML = rowHTML;
+ return el.children[0];
+ }
+ };
- renderBodyWithClusterize() {
- // first page
- const rows = this.datamanager.getRowsForView(0, 20);
- let initialData = this.getDataForClusterize(rows);
-
- if (initialData.length === 0) {
- initialData = [this.getNoDataHTML()];
- }
-
- if (!this.clusterize) {
- // empty body
- this.bodyScrollable.innerHTML = this.getBodyHTML([]);
-
- // first 20 rows will appended
- // rest of them in nextTick
- this.clusterize = new Clusterize({
- rows: initialData,
- scrollElem: this.bodyScrollable,
- contentElem: $('tbody', this.bodyScrollable),
- callbacks: {
- clusterChanged: () => this.restoreState()
- },
- /* eslint-disable */
- show_no_data_row: false,
- /* eslint-enable */
- });
-
- // setDimensions requires atleast 1 row to exist in dom
- this.instance.setDimensions();
+ if (!this.hyperlist) {
+ this.bodyScrollable.innerHTML = '
';
+ this.hyperlist = new HyperList($('.dt-body', this.bodyScrollable), config);
} else {
- this.clusterize.update(initialData);
+ this.renderRows(rows);
}
- this.appendRemainingData();
+ // setDimensions requires atleast 1 row to exist in dom
+ this.instance.setDimensions();
}
restoreState() {
@@ -73,12 +58,6 @@ export default class BodyRenderer {
this.cellmanager.focusCellOnClusterChanged();
}
- appendRemainingData() {
- const rows = this.datamanager.getRowsForView(20);
- const data = this.getDataForClusterize(rows);
- this.clusterize.append(data);
- }
-
showToastMessage(message, hideAfter) {
this.instance.toastMessage.innerHTML = this.getToastMessageHTML(message);
@@ -99,11 +78,11 @@ export default class BodyRenderer {
getBodyHTML(rows) {
return `
-
-
+
+
${rows.map(row => this.rowmanager.getRowHTML(row, row.meta)).join('')}
-
-
+
+
`;
}
diff --git a/src/cellmanager.js b/src/cellmanager.js
index e251534..4f1be22 100644
--- a/src/cellmanager.js
+++ b/src/cellmanager.js
@@ -749,9 +749,9 @@ export default class CellManager {
].join(' ');
return `
-
+
${this.getCellContent(cell)}
- |
+
`;
}
diff --git a/src/columnmanager.js b/src/columnmanager.js
index d443dd9..1cefd6e 100644
--- a/src/columnmanager.js
+++ b/src/columnmanager.js
@@ -17,14 +17,15 @@ export default class ColumnManager {
'style',
'wrapper',
'rowmanager',
- 'bodyScrollable'
+ 'bodyScrollable',
+ 'bodyRenderer'
]);
this.bindEvents();
}
renderHeader() {
- this.header.innerHTML = '';
+ this.header.innerHTML = '';
this.refreshHeader();
}
@@ -32,7 +33,7 @@ export default class ColumnManager {
const columns = this.datamanager.getColumns();
// refresh html
- $('thead', this.header).innerHTML = this.getHeaderHTML(columns);
+ $('div', this.header).innerHTML = this.getHeaderHTML(columns);
this.$filterRow = $('.dt-row-filter', this.header);
if (this.$filterRow) {
@@ -282,11 +283,10 @@ export default class ColumnManager {
applyFilter(keyword, colIndex) {
this.datamanager.filterRows(keyword, colIndex)
.then(({
- rowsToHide,
rowsToShow
}) => {
- this.rowmanager.hideRows(rowsToHide);
- this.rowmanager.showRows(rowsToShow);
+ const rows = rowsToShow.map(rowIndex => this.datamanager.getRow(rowIndex));
+ this.bodyRenderer.renderRows(rows);
});
}
diff --git a/src/datatable.js b/src/datatable.js
index 8abebee..391a592 100644
--- a/src/datatable.js
+++ b/src/datatable.js
@@ -69,8 +69,8 @@ class DataTable {
prepareDom() {
this.wrapper.innerHTML = `
-
+
diff --git a/src/rowmanager.js b/src/rowmanager.js
index b6a1674..50ad350 100644
--- a/src/rowmanager.js
+++ b/src/rowmanager.js
@@ -279,9 +279,9 @@ export default class RowManager {
}
return `
-
+
${row.map(cell => this.cellmanager.getCellHTML(cell)).join('')}
-
+
`;
}
diff --git a/src/style.css b/src/style.css
index 8dee290..ebb85d0 100644
--- a/src/style.css
+++ b/src/style.css
@@ -43,7 +43,7 @@
}
.dt-scrollable {
- max-height: 40vw;
+ height: 40vw;
overflow: auto;
border-bottom: 1px solid var(--dt-border-color);
@@ -60,6 +60,8 @@
}
.dt-row {
+ display: flex;
+
&--highlight .dt-cell {
background-color: var(--dt-selection-highlight-color);
}
@@ -75,6 +77,8 @@
.dt-cell {
border: 1px solid var(--dt-border-color);
+ border-bottom: none;
+ border-right: none;
position: relative;
outline: none;
padding: 0;
@@ -141,6 +145,10 @@
background-color: var(--dt-header-cell-bg);
}
+ &--header:last-child {
+ border-right: 1px solid var(--dt-border-color);
+ }
+
&--header &__content {
padding-right: var(--dt-spacer-3);
font-weight: bold;
diff --git a/src/style.js b/src/style.js
index b902202..5cda80b 100644
--- a/src/style.js
+++ b/src/style.js
@@ -119,33 +119,16 @@ export default class Style {
}
setDimensions() {
- this.setHeaderStyle();
-
this.setupMinWidth();
this.setupNaturalColumnWidth();
this.setupColumnWidth();
this.distributeRemainingWidth();
this.setColumnStyle();
this.compensateScrollbarWidth();
-
this.setDefaultCellHeight();
this.setBodyStyle();
}
- setHeaderStyle() {
- if (this.options.layout === 'fluid') {
- // setting width as 0 will ensure that the
- // header doesn't take the available space
- $.style(this.header, {
- width: 0
- });
- }
-
- $.style(this.header, {
- margin: 0
- });
- }
-
setupMinWidth() {
$.each('.dt-cell--header', this.header).map(col => {
const { colIndex } = $.data(col);
@@ -228,7 +211,7 @@ export default class Style {
}
compensateScrollbarWidth() {
- if (!$.hasVerticalOverflow(this.bodyScrollable)) return;
+ if (!$.hasVerticalOverflow($('.dt-body', this.bodyScrollable))) return;
requestAnimationFrame(() => {
const scrollbarWidth = $.scrollbarWidth();
@@ -313,26 +296,9 @@ export default class Style {
width: width + 'px'
});
- const $body = $('.dt-body', this.bodyScrollable);
-
- if ($body) {
- $.style($body, {
- height: '0px'
- });
-
- $.style($('tbody', $body), {
- height: '100%'
- });
- }
-
$.style(this.bodyScrollable, {
marginTop: $.style(this.header, 'height') + 'px'
});
-
- $.style($('table', this.bodyScrollable), {
- margin: 0,
- width: '100%'
- });
});
}
diff --git a/yarn.lock b/yarn.lock
index eec30ca..956f5ea 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1493,11 +1493,6 @@ clone@^1.0.2:
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f"
integrity sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=
-clusterize.js@^0.18.0:
- version "0.18.0"
- resolved "https://registry.yarnpkg.com/clusterize.js/-/clusterize.js-0.18.0.tgz#32dce7267c5e934bfb205ba65a98760005041331"
- integrity sha512-13AqtsPStx5OawyggucdPawJaJmPl56HbG32Urya79VE39T7ZlpgVUGIOPwr9TIwf/duZAXjhXDQxC2eiMe6AA==
-
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -3331,6 +3326,11 @@ https-proxy-agent@^2.2.0, https-proxy-agent@^2.2.1:
agent-base "^4.1.0"
debug "^3.1.0"
+hyperlist@^1.0.0-beta:
+ version "1.0.0-beta"
+ resolved "https://registry.yarnpkg.com/hyperlist/-/hyperlist-1.0.0-beta.tgz#2cbbd77f4498c2ecc290b7f3c6745b3f0288247e"
+ integrity sha1-LLvXf0SYwuzCkLfzxnRbPwKIJH4=
+
iconv-lite@^0.4.17:
version "0.4.21"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.21.tgz#c47f8733d02171189ebc4a400f3218d348094798"