datatable/src/rowmanager.js
2017-12-21 15:11:46 +05:30

193 lines
4.7 KiB
JavaScript

import $ from './dom';
import { makeDataAttributeString, promisify } from './utils';
import { getCellHTML } from './cellmanager';
export default class RowManager {
constructor(instance) {
this.instance = instance;
this.options = this.instance.options;
this.wrapper = this.instance.wrapper;
this.bodyScrollable = this.instance.bodyScrollable;
this.bindEvents();
this.refreshRows = promisify(this.refreshRows, this);
}
get datamanager() {
return this.instance.datamanager;
}
get cellmanager() {
return this.instance.cellmanager;
}
bindEvents() {
this.bindCheckbox();
}
bindCheckbox() {
if (!this.options.addCheckboxColumn) return;
// map of checked rows
this.checkMap = [];
$.on(this.wrapper, 'click', '.data-table-col[data-col-index="0"] [type="checkbox"]', (e, $checkbox) => {
const $cell = $checkbox.closest('.data-table-col');
const { rowIndex, isHeader } = $.data($cell);
const checked = $checkbox.checked;
if (isHeader) {
this.checkAll(checked);
} else {
this.checkRow(rowIndex, checked);
}
});
}
refreshRows() {
this.instance.renderBody();
this.instance.setDimensions();
}
refreshRow(row, rowIndex) {
const _row = this.datamanager.updateRow(row, rowIndex);
_row.forEach(cell => {
this.cellmanager.refreshCell(cell);
});
}
getCheckedRows() {
return this.checkMap
.map((c, rowIndex) => {
if (c) {
return rowIndex;
}
return null;
})
.filter(c => {
return c !== null || c !== undefined;
});
}
highlightCheckedRows() {
this.getCheckedRows()
.map(rowIndex => this.checkRow(rowIndex, true));
}
checkRow(rowIndex, toggle) {
const value = toggle ? 1 : 0;
// update internal map
this.checkMap[rowIndex] = value;
// set checkbox value explicitly
$.each(`.data-table-col[data-row-index="${rowIndex}"][data-col-index="0"] [type="checkbox"]`, this.bodyScrollable)
.map(input => {
input.checked = toggle;
});
// highlight row
this.highlightRow(rowIndex, toggle);
}
checkAll(toggle) {
const value = toggle ? 1 : 0;
// update internal map
if (toggle) {
this.checkMap = Array.from(Array(this.getTotalRows())).map(c => value);
} else {
this.checkMap = [];
}
// set checkbox value
$.each('.data-table-col[data-col-index="0"] [type="checkbox"]', this.bodyScrollable)
.map(input => {
input.checked = toggle;
});
// highlight all
this.highlightAll(toggle);
}
highlightRow(rowIndex, toggle = true) {
const $row = this.getRow$(rowIndex);
if (!$row) return;
if (!toggle && this.bodyScrollable.classList.contains('row-highlight-all')) {
$row.classList.add('row-unhighlight');
return;
}
if (toggle && $row.classList.contains('row-unhighlight')) {
$row.classList.remove('row-unhighlight');
}
this._highlightedRows = this._highlightedRows || {};
if (toggle) {
$row.classList.add('row-highlight');
this._highlightedRows[rowIndex] = $row;
} else {
$row.classList.remove('row-highlight');
delete this._highlightedRows[rowIndex];
}
}
highlightAll(toggle = true) {
if (toggle) {
this.bodyScrollable.classList.add('row-highlight-all');
} else {
this.bodyScrollable.classList.remove('row-highlight-all');
for (const rowIndex in this._highlightedRows) {
const $row = this._highlightedRows[rowIndex];
$row.classList.remove('row-highlight');
}
this._highlightedRows = {};
}
}
getRow$(rowIndex) {
return $(`.data-table-row[data-row-index="${rowIndex}"]`, this.bodyScrollable);
}
getTotalRows() {
return this.datamanager.getRowCount();
}
getFirstRowIndex() {
return 0;
}
getLastRowIndex() {
return this.datamanager.getRowCount() - 1;
}
scrollToRow(rowIndex) {
const $row = this.getRow$(rowIndex);
if ($.inViewport($row, this.bodyScrollable)) return;
const { top, height } = $row.getBoundingClientRect();
const { top: pTop } = this.bodyScrollable.getBoundingClientRect();
let offset;
if (top < pTop) {
offset = this.bodyScrollable.scrollTop - (pTop - top) - height;
if (offset < 0) offset = 0;
} else {
offset = this.bodyScrollable.scrollTop + (top - this.bodyScrollable.clientHeight);
}
console.log(rowIndex, offset);
$.scrollTop(this.bodyScrollable, offset);
}
}
export function getRowHTML(columns, props) {
const dataAttr = makeDataAttributeString(props);
return `
<tr class="data-table-row" ${dataAttr}>
${columns.map(getCellHTML).join('')}
</tr>
`;
}