Tree expand/collapse working
This commit is contained in:
parent
081dbac41b
commit
470ab90fef
172
dist/frappe-datatable.cjs.js
vendored
172
dist/frappe-datatable.cjs.js
vendored
@ -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) {
|
||||
|
||||
172
dist/frappe-datatable.js
vendored
172
dist/frappe-datatable.js
vendored
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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}"]`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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) {
|
||||
|
||||
19
src/utils.js
19
src/utils.js
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user