Tree expand/collapse working

This commit is contained in:
Faris Ansari 2018-03-02 15:42:51 +05:30
parent 081dbac41b
commit 470ab90fef
8 changed files with 460 additions and 239 deletions

View File

@ -825,6 +825,25 @@ function linkProperties(target, source, properties) {
Object.defineProperties(target, props);
}
function isSet(val) {
return val !== undefined || val !== null;
}
function notSet(val) {
return !isSet(val);
}
function isNumber(val) {
return !isNaN(val);
}
function ensureArray(val) {
if (!Array.isArray(val)) {
return [val];
}
return val;
}
class DataManager {
constructor(options) {
this.options = options;
@ -847,6 +866,7 @@ class DataManager {
this.prepareColumns();
this.prepareRows();
this.prepareTreeRows();
this.prepareRowView();
this.prepareNumericColumns();
@ -995,13 +1015,25 @@ class DataManager {
}
}
meta.indent = d.indent;
meta.indent = d.indent || 0;
}
return this.prepareRow(row, meta);
});
}
prepareTreeRows() {
this.rows.forEach((row, i) => {
if (isNumber(row.meta.indent)) {
// if (i === 36) debugger;
const nextRow = this.getRow(i + 1);
row.meta.isLeaf = !nextRow ||
notSet(nextRow.meta.indent) ||
nextRow.meta.indent <= row.meta.indent;
}
});
}
prepareRowView() {
// This is order in which rows will be rendered in the table.
// When sorting happens, only this.rowViewOrder will change
@ -1323,21 +1355,44 @@ class DataManager {
return this.getRow(rowIndex)[colIndex];
}
getChildrenIndices(parentRowIndex) {
getChildren(parentRowIndex) {
parentRowIndex = +parentRowIndex;
const parentIndent = this.getRow(parentRowIndex).meta.indent;
const out = [];
let i = parentRowIndex + 1;
let nextRow = this.getRow(i);
let nextIndent = nextRow ? (nextRow.meta.indent || 0) : -1;
for (let i = parentRowIndex + 1; i < this.rowCount; i++) {
const row = this.getRow(i);
if (isNaN(row.meta.indent)) continue;
while (nextIndent > parentIndent) {
out.push(i);
if (row.meta.indent > parentIndent) {
out.push(i);
}
i++;
nextRow = this.getRow(i);
nextIndent = nextRow ? (nextRow.meta.indent || 0) : -1;
if (row.meta.indent === parentIndent) {
break;
}
}
return out;
}
getImmediateChildren(parentRowIndex) {
parentRowIndex = +parentRowIndex;
const parentIndent = this.getRow(parentRowIndex).meta.indent;
const out = [];
const childIndent = parentIndent + 1;
for (let i = parentRowIndex + 1; i < this.rowCount; i++) {
const row = this.getRow(i);
if (isNaN(row.meta.indent) || row.meta.indent > childIndent) continue;
if (row.meta.indent === childIndent) {
out.push(i);
}
if (row.meta.indent === parentIndent) {
break;
}
}
return out;
@ -1774,15 +1829,7 @@ class ColumnManager {
}
getFirstColumnIndex() {
if (this.options.addCheckboxColumn && this.options.addSerialNoColumn) {
return 2;
}
if (this.options.addCheckboxColumn || this.options.addSerialNoColumn) {
return 1;
}
return 0;
return this.datamanager.getColumnIndexById('_rowIndex') + 1;
}
getHeaderCell$(colIndex) {
@ -1815,14 +1862,16 @@ var getDropdownHTML = function getDropdownHTML(dropdownButton = 'v') {
class CellManager {
constructor(instance) {
this.instance = instance;
this.wrapper = this.instance.wrapper;
this.options = this.instance.options;
this.style = this.instance.style;
this.bodyScrollable = this.instance.bodyScrollable;
this.columnmanager = this.instance.columnmanager;
this.rowmanager = this.instance.rowmanager;
this.datamanager = this.instance.datamanager;
this.keyboard = this.instance.keyboard;
linkProperties(this, this.instance, [
'wrapper',
'options',
'style',
'bodyScrollable',
'columnmanager',
'rowmanager',
'datamanager',
'keyboard'
]);
this.bindEvents();
}
@ -1986,30 +2035,11 @@ class CellManager {
const { rowIndex } = $.data($cell);
if ($cell.classList.contains('tree-close')) {
this.rowmanager.openTreeNode(rowIndex);
$cell.classList.remove('tree-close');
this.rowmanager.openSingleNode(rowIndex);
} else {
this.rowmanager.closeTreeNode(rowIndex);
$cell.classList.add('tree-close');
this.rowmanager.closeSingleNode(rowIndex);
}
});
// this.keyboard.on('left, right', (e) => {
// const firstColumnIndex = this.datamanager.getColumnIndexById('_rowIndex') + 1;
// if (e.target.matches('.data-table-cell')) {
// const $cell = e.target;
// const { colIndex, rowIndex } = $.data($cell);
// if (+colIndex === firstColumnIndex) {
// if (keyCode[e.keyCode] === 'left') {
// this.rowmanager.closeTreeNode(rowIndex);
// }
// if (keyCode[e.keyCode] === 'right') {
// this.rowmanager.openTreeNode(rowIndex);
// }
// return false;
// }
// }
// });
}
focusCell($cell, {
@ -2362,17 +2392,25 @@ class CellManager {
}
refreshCell(cell) {
const $cell = $(this.cellSelector(cell.colIndex, cell.rowIndex), this.bodyScrollable);
const $cell = $(this.selector(cell.colIndex, cell.rowIndex), this.bodyScrollable);
$cell.innerHTML = this.getCellContent(cell);
}
toggleTreeButton(rowIndex, flag) {
const colIndex = this.columnmanager.getFirstColumnIndex();
const $cell = this.getCell$(colIndex, rowIndex);
if ($cell) {
$cell.classList[flag ? 'remove' : 'add']('tree-close');
}
}
isStandardCell(colIndex) {
// Standard cells are in Sr. No and Checkbox column
return colIndex < this.columnmanager.getFirstColumnIndex();
}
getCell$(colIndex, rowIndex) {
return $(this.cellSelector(colIndex, rowIndex), this.bodyScrollable);
return $(this.selector(colIndex, rowIndex), this.bodyScrollable);
}
getAboveCell$($cell) {
@ -2520,7 +2558,7 @@ class CellManager {
`;
}
cellSelector(colIndex, rowIndex) {
selector(colIndex, rowIndex) {
return `.data-table-cell[data-col-index="${colIndex}"][data-row-index="${rowIndex}"]`;
}
}
@ -2528,9 +2566,11 @@ class CellManager {
class RowManager {
constructor(instance) {
this.instance = instance;
this.options = this.instance.options;
this.wrapper = this.instance.wrapper;
this.bodyScrollable = this.instance.bodyScrollable;
linkProperties(this, this.instance, [
'options',
'wrapper',
'bodyScrollable'
]);
this.bindEvents();
this.refreshRows = promisify(this.refreshRows, this);
@ -2676,6 +2716,7 @@ class RowManager {
}
hideRows(rowIndices) {
rowIndices = ensureArray(rowIndices);
rowIndices.map(rowIndex => {
const $tr = this.getRow$(rowIndex);
$tr.classList.add('hide');
@ -2683,20 +2724,33 @@ class RowManager {
}
showRows(rowIndices) {
rowIndices = ensureArray(rowIndices);
rowIndices.map(rowIndex => {
const $tr = this.getRow$(rowIndex);
$tr.classList.remove('hide');
});
}
openTreeNode(rowIndex) {
const rowsToShow = this.datamanager.getChildrenIndices(rowIndex);
openSingleNode(rowIndex) {
const rowsToShow = this.datamanager.getImmediateChildren(rowIndex);
this.showRows(rowsToShow);
this.cellmanager.toggleTreeButton(rowIndex, true);
}
closeTreeNode(rowIndex) {
const rowsToHide = this.datamanager.getChildrenIndices(rowIndex);
this.hideRows(rowsToHide);
closeSingleNode(rowIndex) {
const children = this.datamanager.getImmediateChildren(rowIndex);
children.forEach(childIndex => {
const row = this.datamanager.getRow(childIndex);
if (row.meta.isLeaf) {
// close
this.hideRows(childIndex);
this.cellmanager.toggleTreeButton(childIndex, false);
} else {
this.closeSingleNode(childIndex);
this.hideRows(childIndex);
}
});
this.cellmanager.toggleTreeButton(rowIndex, false);
}
getRow$(rowIndex) {

View File

@ -824,6 +824,25 @@ function linkProperties(target, source, properties) {
Object.defineProperties(target, props);
}
function isSet(val) {
return val !== undefined || val !== null;
}
function notSet(val) {
return !isSet(val);
}
function isNumber(val) {
return !isNaN(val);
}
function ensureArray(val) {
if (!Array.isArray(val)) {
return [val];
}
return val;
}
class DataManager {
constructor(options) {
this.options = options;
@ -846,6 +865,7 @@ class DataManager {
this.prepareColumns();
this.prepareRows();
this.prepareTreeRows();
this.prepareRowView();
this.prepareNumericColumns();
@ -994,13 +1014,25 @@ class DataManager {
}
}
meta.indent = d.indent;
meta.indent = d.indent || 0;
}
return this.prepareRow(row, meta);
});
}
prepareTreeRows() {
this.rows.forEach((row, i) => {
if (isNumber(row.meta.indent)) {
// if (i === 36) debugger;
const nextRow = this.getRow(i + 1);
row.meta.isLeaf = !nextRow ||
notSet(nextRow.meta.indent) ||
nextRow.meta.indent <= row.meta.indent;
}
});
}
prepareRowView() {
// This is order in which rows will be rendered in the table.
// When sorting happens, only this.rowViewOrder will change
@ -1322,21 +1354,44 @@ class DataManager {
return this.getRow(rowIndex)[colIndex];
}
getChildrenIndices(parentRowIndex) {
getChildren(parentRowIndex) {
parentRowIndex = +parentRowIndex;
const parentIndent = this.getRow(parentRowIndex).meta.indent;
const out = [];
let i = parentRowIndex + 1;
let nextRow = this.getRow(i);
let nextIndent = nextRow ? (nextRow.meta.indent || 0) : -1;
for (let i = parentRowIndex + 1; i < this.rowCount; i++) {
const row = this.getRow(i);
if (isNaN(row.meta.indent)) continue;
while (nextIndent > parentIndent) {
out.push(i);
if (row.meta.indent > parentIndent) {
out.push(i);
}
i++;
nextRow = this.getRow(i);
nextIndent = nextRow ? (nextRow.meta.indent || 0) : -1;
if (row.meta.indent === parentIndent) {
break;
}
}
return out;
}
getImmediateChildren(parentRowIndex) {
parentRowIndex = +parentRowIndex;
const parentIndent = this.getRow(parentRowIndex).meta.indent;
const out = [];
const childIndent = parentIndent + 1;
for (let i = parentRowIndex + 1; i < this.rowCount; i++) {
const row = this.getRow(i);
if (isNaN(row.meta.indent) || row.meta.indent > childIndent) continue;
if (row.meta.indent === childIndent) {
out.push(i);
}
if (row.meta.indent === parentIndent) {
break;
}
}
return out;
@ -1773,15 +1828,7 @@ class ColumnManager {
}
getFirstColumnIndex() {
if (this.options.addCheckboxColumn && this.options.addSerialNoColumn) {
return 2;
}
if (this.options.addCheckboxColumn || this.options.addSerialNoColumn) {
return 1;
}
return 0;
return this.datamanager.getColumnIndexById('_rowIndex') + 1;
}
getHeaderCell$(colIndex) {
@ -1814,14 +1861,16 @@ var getDropdownHTML = function getDropdownHTML(dropdownButton = 'v') {
class CellManager {
constructor(instance) {
this.instance = instance;
this.wrapper = this.instance.wrapper;
this.options = this.instance.options;
this.style = this.instance.style;
this.bodyScrollable = this.instance.bodyScrollable;
this.columnmanager = this.instance.columnmanager;
this.rowmanager = this.instance.rowmanager;
this.datamanager = this.instance.datamanager;
this.keyboard = this.instance.keyboard;
linkProperties(this, this.instance, [
'wrapper',
'options',
'style',
'bodyScrollable',
'columnmanager',
'rowmanager',
'datamanager',
'keyboard'
]);
this.bindEvents();
}
@ -1985,30 +2034,11 @@ class CellManager {
const { rowIndex } = $.data($cell);
if ($cell.classList.contains('tree-close')) {
this.rowmanager.openTreeNode(rowIndex);
$cell.classList.remove('tree-close');
this.rowmanager.openSingleNode(rowIndex);
} else {
this.rowmanager.closeTreeNode(rowIndex);
$cell.classList.add('tree-close');
this.rowmanager.closeSingleNode(rowIndex);
}
});
// this.keyboard.on('left, right', (e) => {
// const firstColumnIndex = this.datamanager.getColumnIndexById('_rowIndex') + 1;
// if (e.target.matches('.data-table-cell')) {
// const $cell = e.target;
// const { colIndex, rowIndex } = $.data($cell);
// if (+colIndex === firstColumnIndex) {
// if (keyCode[e.keyCode] === 'left') {
// this.rowmanager.closeTreeNode(rowIndex);
// }
// if (keyCode[e.keyCode] === 'right') {
// this.rowmanager.openTreeNode(rowIndex);
// }
// return false;
// }
// }
// });
}
focusCell($cell, {
@ -2361,17 +2391,25 @@ class CellManager {
}
refreshCell(cell) {
const $cell = $(this.cellSelector(cell.colIndex, cell.rowIndex), this.bodyScrollable);
const $cell = $(this.selector(cell.colIndex, cell.rowIndex), this.bodyScrollable);
$cell.innerHTML = this.getCellContent(cell);
}
toggleTreeButton(rowIndex, flag) {
const colIndex = this.columnmanager.getFirstColumnIndex();
const $cell = this.getCell$(colIndex, rowIndex);
if ($cell) {
$cell.classList[flag ? 'remove' : 'add']('tree-close');
}
}
isStandardCell(colIndex) {
// Standard cells are in Sr. No and Checkbox column
return colIndex < this.columnmanager.getFirstColumnIndex();
}
getCell$(colIndex, rowIndex) {
return $(this.cellSelector(colIndex, rowIndex), this.bodyScrollable);
return $(this.selector(colIndex, rowIndex), this.bodyScrollable);
}
getAboveCell$($cell) {
@ -2519,7 +2557,7 @@ class CellManager {
`;
}
cellSelector(colIndex, rowIndex) {
selector(colIndex, rowIndex) {
return `.data-table-cell[data-col-index="${colIndex}"][data-row-index="${rowIndex}"]`;
}
}
@ -2527,9 +2565,11 @@ class CellManager {
class RowManager {
constructor(instance) {
this.instance = instance;
this.options = this.instance.options;
this.wrapper = this.instance.wrapper;
this.bodyScrollable = this.instance.bodyScrollable;
linkProperties(this, this.instance, [
'options',
'wrapper',
'bodyScrollable'
]);
this.bindEvents();
this.refreshRows = promisify(this.refreshRows, this);
@ -2675,6 +2715,7 @@ class RowManager {
}
hideRows(rowIndices) {
rowIndices = ensureArray(rowIndices);
rowIndices.map(rowIndex => {
const $tr = this.getRow$(rowIndex);
$tr.classList.add('hide');
@ -2682,20 +2723,33 @@ class RowManager {
}
showRows(rowIndices) {
rowIndices = ensureArray(rowIndices);
rowIndices.map(rowIndex => {
const $tr = this.getRow$(rowIndex);
$tr.classList.remove('hide');
});
}
openTreeNode(rowIndex) {
const rowsToShow = this.datamanager.getChildrenIndices(rowIndex);
openSingleNode(rowIndex) {
const rowsToShow = this.datamanager.getImmediateChildren(rowIndex);
this.showRows(rowsToShow);
this.cellmanager.toggleTreeButton(rowIndex, true);
}
closeTreeNode(rowIndex) {
const rowsToHide = this.datamanager.getChildrenIndices(rowIndex);
this.hideRows(rowsToHide);
closeSingleNode(rowIndex) {
const children = this.datamanager.getImmediateChildren(rowIndex);
children.forEach(childIndex => {
const row = this.datamanager.getRow(childIndex);
if (row.meta.isLeaf) {
// close
this.hideRows(childIndex);
this.cellmanager.toggleTreeButton(childIndex, false);
} else {
this.closeSingleNode(childIndex);
this.hideRows(childIndex);
}
});
this.cellmanager.toggleTreeButton(rowIndex, false);
}
getRow$(rowIndex) {

View File

@ -824,6 +824,25 @@ function linkProperties(target, source, properties) {
Object.defineProperties(target, props);
}
function isSet(val) {
return val !== undefined || val !== null;
}
function notSet(val) {
return !isSet(val);
}
function isNumber(val) {
return !isNaN(val);
}
function ensureArray(val) {
if (!Array.isArray(val)) {
return [val];
}
return val;
}
class DataManager {
constructor(options) {
this.options = options;
@ -846,6 +865,7 @@ class DataManager {
this.prepareColumns();
this.prepareRows();
this.prepareTreeRows();
this.prepareRowView();
this.prepareNumericColumns();
@ -994,13 +1014,25 @@ class DataManager {
}
}
meta.indent = d.indent;
meta.indent = d.indent || 0;
}
return this.prepareRow(row, meta);
});
}
prepareTreeRows() {
this.rows.forEach((row, i) => {
if (isNumber(row.meta.indent)) {
// if (i === 36) debugger;
const nextRow = this.getRow(i + 1);
row.meta.isLeaf = !nextRow ||
notSet(nextRow.meta.indent) ||
nextRow.meta.indent <= row.meta.indent;
}
});
}
prepareRowView() {
// This is order in which rows will be rendered in the table.
// When sorting happens, only this.rowViewOrder will change
@ -1322,21 +1354,44 @@ class DataManager {
return this.getRow(rowIndex)[colIndex];
}
getChildrenIndices(parentRowIndex) {
getChildren(parentRowIndex) {
parentRowIndex = +parentRowIndex;
const parentIndent = this.getRow(parentRowIndex).meta.indent;
const out = [];
let i = parentRowIndex + 1;
let nextRow = this.getRow(i);
let nextIndent = nextRow ? (nextRow.meta.indent || 0) : -1;
for (let i = parentRowIndex + 1; i < this.rowCount; i++) {
const row = this.getRow(i);
if (isNaN(row.meta.indent)) continue;
while (nextIndent > parentIndent) {
out.push(i);
if (row.meta.indent > parentIndent) {
out.push(i);
}
i++;
nextRow = this.getRow(i);
nextIndent = nextRow ? (nextRow.meta.indent || 0) : -1;
if (row.meta.indent === parentIndent) {
break;
}
}
return out;
}
getImmediateChildren(parentRowIndex) {
parentRowIndex = +parentRowIndex;
const parentIndent = this.getRow(parentRowIndex).meta.indent;
const out = [];
const childIndent = parentIndent + 1;
for (let i = parentRowIndex + 1; i < this.rowCount; i++) {
const row = this.getRow(i);
if (isNaN(row.meta.indent) || row.meta.indent > childIndent) continue;
if (row.meta.indent === childIndent) {
out.push(i);
}
if (row.meta.indent === parentIndent) {
break;
}
}
return out;
@ -1773,15 +1828,7 @@ class ColumnManager {
}
getFirstColumnIndex() {
if (this.options.addCheckboxColumn && this.options.addSerialNoColumn) {
return 2;
}
if (this.options.addCheckboxColumn || this.options.addSerialNoColumn) {
return 1;
}
return 0;
return this.datamanager.getColumnIndexById('_rowIndex') + 1;
}
getHeaderCell$(colIndex) {
@ -1814,14 +1861,16 @@ var getDropdownHTML = function getDropdownHTML(dropdownButton = 'v') {
class CellManager {
constructor(instance) {
this.instance = instance;
this.wrapper = this.instance.wrapper;
this.options = this.instance.options;
this.style = this.instance.style;
this.bodyScrollable = this.instance.bodyScrollable;
this.columnmanager = this.instance.columnmanager;
this.rowmanager = this.instance.rowmanager;
this.datamanager = this.instance.datamanager;
this.keyboard = this.instance.keyboard;
linkProperties(this, this.instance, [
'wrapper',
'options',
'style',
'bodyScrollable',
'columnmanager',
'rowmanager',
'datamanager',
'keyboard'
]);
this.bindEvents();
}
@ -1985,30 +2034,11 @@ class CellManager {
const { rowIndex } = $.data($cell);
if ($cell.classList.contains('tree-close')) {
this.rowmanager.openTreeNode(rowIndex);
$cell.classList.remove('tree-close');
this.rowmanager.openSingleNode(rowIndex);
} else {
this.rowmanager.closeTreeNode(rowIndex);
$cell.classList.add('tree-close');
this.rowmanager.closeSingleNode(rowIndex);
}
});
// this.keyboard.on('left, right', (e) => {
// const firstColumnIndex = this.datamanager.getColumnIndexById('_rowIndex') + 1;
// if (e.target.matches('.data-table-cell')) {
// const $cell = e.target;
// const { colIndex, rowIndex } = $.data($cell);
// if (+colIndex === firstColumnIndex) {
// if (keyCode[e.keyCode] === 'left') {
// this.rowmanager.closeTreeNode(rowIndex);
// }
// if (keyCode[e.keyCode] === 'right') {
// this.rowmanager.openTreeNode(rowIndex);
// }
// return false;
// }
// }
// });
}
focusCell($cell, {
@ -2361,17 +2391,25 @@ class CellManager {
}
refreshCell(cell) {
const $cell = $(this.cellSelector(cell.colIndex, cell.rowIndex), this.bodyScrollable);
const $cell = $(this.selector(cell.colIndex, cell.rowIndex), this.bodyScrollable);
$cell.innerHTML = this.getCellContent(cell);
}
toggleTreeButton(rowIndex, flag) {
const colIndex = this.columnmanager.getFirstColumnIndex();
const $cell = this.getCell$(colIndex, rowIndex);
if ($cell) {
$cell.classList[flag ? 'remove' : 'add']('tree-close');
}
}
isStandardCell(colIndex) {
// Standard cells are in Sr. No and Checkbox column
return colIndex < this.columnmanager.getFirstColumnIndex();
}
getCell$(colIndex, rowIndex) {
return $(this.cellSelector(colIndex, rowIndex), this.bodyScrollable);
return $(this.selector(colIndex, rowIndex), this.bodyScrollable);
}
getAboveCell$($cell) {
@ -2519,7 +2557,7 @@ class CellManager {
`;
}
cellSelector(colIndex, rowIndex) {
selector(colIndex, rowIndex) {
return `.data-table-cell[data-col-index="${colIndex}"][data-row-index="${rowIndex}"]`;
}
}
@ -2527,9 +2565,11 @@ class CellManager {
class RowManager {
constructor(instance) {
this.instance = instance;
this.options = this.instance.options;
this.wrapper = this.instance.wrapper;
this.bodyScrollable = this.instance.bodyScrollable;
linkProperties(this, this.instance, [
'options',
'wrapper',
'bodyScrollable'
]);
this.bindEvents();
this.refreshRows = promisify(this.refreshRows, this);
@ -2675,6 +2715,7 @@ class RowManager {
}
hideRows(rowIndices) {
rowIndices = ensureArray(rowIndices);
rowIndices.map(rowIndex => {
const $tr = this.getRow$(rowIndex);
$tr.classList.add('hide');
@ -2682,20 +2723,33 @@ class RowManager {
}
showRows(rowIndices) {
rowIndices = ensureArray(rowIndices);
rowIndices.map(rowIndex => {
const $tr = this.getRow$(rowIndex);
$tr.classList.remove('hide');
});
}
openTreeNode(rowIndex) {
const rowsToShow = this.datamanager.getChildrenIndices(rowIndex);
openSingleNode(rowIndex) {
const rowsToShow = this.datamanager.getImmediateChildren(rowIndex);
this.showRows(rowsToShow);
this.cellmanager.toggleTreeButton(rowIndex, true);
}
closeTreeNode(rowIndex) {
const rowsToHide = this.datamanager.getChildrenIndices(rowIndex);
this.hideRows(rowsToHide);
closeSingleNode(rowIndex) {
const children = this.datamanager.getImmediateChildren(rowIndex);
children.forEach(childIndex => {
const row = this.datamanager.getRow(childIndex);
if (row.meta.isLeaf) {
// close
this.hideRows(childIndex);
this.cellmanager.toggleTreeButton(childIndex, false);
} else {
this.closeSingleNode(childIndex);
this.hideRows(childIndex);
}
});
this.cellmanager.toggleTreeButton(rowIndex, false);
}
getRow$(rowIndex) {

View File

@ -1,7 +1,8 @@
import {
copyTextToClipboard,
makeDataAttributeString,
throttle
throttle,
linkProperties
} from './utils';
import $ from './dom';
import {
@ -11,14 +12,16 @@ import {
export default class CellManager {
constructor(instance) {
this.instance = instance;
this.wrapper = this.instance.wrapper;
this.options = this.instance.options;
this.style = this.instance.style;
this.bodyScrollable = this.instance.bodyScrollable;
this.columnmanager = this.instance.columnmanager;
this.rowmanager = this.instance.rowmanager;
this.datamanager = this.instance.datamanager;
this.keyboard = this.instance.keyboard;
linkProperties(this, this.instance, [
'wrapper',
'options',
'style',
'bodyScrollable',
'columnmanager',
'rowmanager',
'datamanager',
'keyboard'
]);
this.bindEvents();
}
@ -182,30 +185,11 @@ export default class CellManager {
const { rowIndex } = $.data($cell);
if ($cell.classList.contains('tree-close')) {
this.rowmanager.openTreeNode(rowIndex);
$cell.classList.remove('tree-close');
this.rowmanager.openSingleNode(rowIndex);
} else {
this.rowmanager.closeTreeNode(rowIndex);
$cell.classList.add('tree-close');
this.rowmanager.closeSingleNode(rowIndex);
}
});
// this.keyboard.on('left, right', (e) => {
// const firstColumnIndex = this.datamanager.getColumnIndexById('_rowIndex') + 1;
// if (e.target.matches('.data-table-cell')) {
// const $cell = e.target;
// const { colIndex, rowIndex } = $.data($cell);
// if (+colIndex === firstColumnIndex) {
// if (keyCode[e.keyCode] === 'left') {
// this.rowmanager.closeTreeNode(rowIndex);
// }
// if (keyCode[e.keyCode] === 'right') {
// this.rowmanager.openTreeNode(rowIndex);
// }
// return false;
// }
// }
// });
}
focusCell($cell, {
@ -558,17 +542,25 @@ export default class CellManager {
}
refreshCell(cell) {
const $cell = $(this.cellSelector(cell.colIndex, cell.rowIndex), this.bodyScrollable);
const $cell = $(this.selector(cell.colIndex, cell.rowIndex), this.bodyScrollable);
$cell.innerHTML = this.getCellContent(cell);
}
toggleTreeButton(rowIndex, flag) {
const colIndex = this.columnmanager.getFirstColumnIndex();
const $cell = this.getCell$(colIndex, rowIndex);
if ($cell) {
$cell.classList[flag ? 'remove' : 'add']('tree-close');
}
}
isStandardCell(colIndex) {
// Standard cells are in Sr. No and Checkbox column
return colIndex < this.columnmanager.getFirstColumnIndex();
}
getCell$(colIndex, rowIndex) {
return $(this.cellSelector(colIndex, rowIndex), this.bodyScrollable);
return $(this.selector(colIndex, rowIndex), this.bodyScrollable);
}
getAboveCell$($cell) {
@ -716,7 +708,7 @@ export default class CellManager {
`;
}
cellSelector(colIndex, rowIndex) {
selector(colIndex, rowIndex) {
return `.data-table-cell[data-col-index="${colIndex}"][data-row-index="${rowIndex}"]`;
}
}

View File

@ -406,15 +406,7 @@ export default class ColumnManager {
}
getFirstColumnIndex() {
if (this.options.addCheckboxColumn && this.options.addSerialNoColumn) {
return 2;
}
if (this.options.addCheckboxColumn || this.options.addSerialNoColumn) {
return 1;
}
return 0;
return this.datamanager.getColumnIndexById('_rowIndex') + 1;
}
getHeaderCell$(colIndex) {

View File

@ -1,6 +1,8 @@
import {
isNumeric,
promisify
promisify,
isNumber,
notSet
} from './utils';
export default class DataManager {
@ -25,6 +27,7 @@ export default class DataManager {
this.prepareColumns();
this.prepareRows();
this.prepareTreeRows();
this.prepareRowView();
this.prepareNumericColumns();
@ -173,13 +176,25 @@ export default class DataManager {
}
}
meta.indent = d.indent;
meta.indent = d.indent || 0;
}
return this.prepareRow(row, meta);
});
}
prepareTreeRows() {
this.rows.forEach((row, i) => {
if (isNumber(row.meta.indent)) {
// if (i === 36) debugger;
const nextRow = this.getRow(i + 1);
row.meta.isLeaf = !nextRow ||
notSet(nextRow.meta.indent) ||
nextRow.meta.indent <= row.meta.indent;
}
});
}
prepareRowView() {
// This is order in which rows will be rendered in the table.
// When sorting happens, only this.rowViewOrder will change
@ -501,21 +516,44 @@ export default class DataManager {
return this.getRow(rowIndex)[colIndex];
}
getChildrenIndices(parentRowIndex) {
getChildren(parentRowIndex) {
parentRowIndex = +parentRowIndex;
const parentIndent = this.getRow(parentRowIndex).meta.indent;
const out = [];
let i = parentRowIndex + 1;
let nextRow = this.getRow(i);
let nextIndent = nextRow ? (nextRow.meta.indent || 0) : -1;
for (let i = parentRowIndex + 1; i < this.rowCount; i++) {
const row = this.getRow(i);
if (isNaN(row.meta.indent)) continue;
while (nextIndent > parentIndent) {
out.push(i);
if (row.meta.indent > parentIndent) {
out.push(i);
}
i++;
nextRow = this.getRow(i);
nextIndent = nextRow ? (nextRow.meta.indent || 0) : -1;
if (row.meta.indent === parentIndent) {
break;
}
}
return out;
}
getImmediateChildren(parentRowIndex) {
parentRowIndex = +parentRowIndex;
const parentIndent = this.getRow(parentRowIndex).meta.indent;
const out = [];
const childIndent = parentIndent + 1;
for (let i = parentRowIndex + 1; i < this.rowCount; i++) {
const row = this.getRow(i);
if (isNaN(row.meta.indent) || row.meta.indent > childIndent) continue;
if (row.meta.indent === childIndent) {
out.push(i);
}
if (row.meta.indent === parentIndent) {
break;
}
}
return out;

View File

@ -1,15 +1,19 @@
import $ from './dom';
import {
makeDataAttributeString,
promisify
promisify,
ensureArray,
linkProperties
} from './utils';
export default class RowManager {
constructor(instance) {
this.instance = instance;
this.options = this.instance.options;
this.wrapper = this.instance.wrapper;
this.bodyScrollable = this.instance.bodyScrollable;
linkProperties(this, this.instance, [
'options',
'wrapper',
'bodyScrollable'
]);
this.bindEvents();
this.refreshRows = promisify(this.refreshRows, this);
@ -155,6 +159,7 @@ export default class RowManager {
}
hideRows(rowIndices) {
rowIndices = ensureArray(rowIndices);
rowIndices.map(rowIndex => {
const $tr = this.getRow$(rowIndex);
$tr.classList.add('hide');
@ -162,20 +167,33 @@ export default class RowManager {
}
showRows(rowIndices) {
rowIndices = ensureArray(rowIndices);
rowIndices.map(rowIndex => {
const $tr = this.getRow$(rowIndex);
$tr.classList.remove('hide');
});
}
openTreeNode(rowIndex) {
const rowsToShow = this.datamanager.getChildrenIndices(rowIndex);
openSingleNode(rowIndex) {
const rowsToShow = this.datamanager.getImmediateChildren(rowIndex);
this.showRows(rowsToShow);
this.cellmanager.toggleTreeButton(rowIndex, true);
}
closeTreeNode(rowIndex) {
const rowsToHide = this.datamanager.getChildrenIndices(rowIndex);
this.hideRows(rowsToHide);
closeSingleNode(rowIndex) {
const children = this.datamanager.getImmediateChildren(rowIndex);
children.forEach(childIndex => {
const row = this.datamanager.getRow(childIndex);
if (row.meta.isLeaf) {
// close
this.hideRows(childIndex);
this.cellmanager.toggleTreeButton(childIndex, false);
} else {
this.closeSingleNode(childIndex);
this.hideRows(childIndex);
}
});
this.cellmanager.toggleTreeButton(rowIndex, false);
}
getRow$(rowIndex) {

View File

@ -183,3 +183,22 @@ export function linkProperties(target, source, properties) {
}, {});
Object.defineProperties(target, props);
};
export function isSet(val) {
return val !== undefined || val !== null;
}
export function notSet(val) {
return !isSet(val);
}
export function isNumber(val) {
return !isNaN(val);
}
export function ensureArray(val) {
if (!Array.isArray(val)) {
return [val];
}
return val;
}