tabulator-tables
Version:
Interactive table generation JavaScript library
958 lines (749 loc) • 27.7 kB
JavaScript
import Module from "../../core/Module.js";
import Range from "./Range.js";
import extensions from './extensions/extensions.js';
export default class SelectRange extends Module {
static moduleName = "selectRange";
static moduleInitOrder = 1;
static moduleExtensions = extensions;
constructor(table) {
super(table);
this.selecting = "cell";
this.mousedown = false;
this.ranges = [];
this.overlay = null;
this.rowHeader = null;
this.layoutChangeTimeout = null;
this.columnSelection = false;
this.rowSelection = false;
this.maxRanges = 0;
this.activeRange = false;
this.blockKeydown = false;
this.keyDownEvent = this._handleKeyDown.bind(this);
this.mouseUpEvent = this._handleMouseUp.bind(this);
this.registerTableOption("selectableRange", false); //enable selectable range
this.registerTableOption("selectableRangeColumns", false); //enable selectable range
this.registerTableOption("selectableRangeRows", false); //enable selectable range
this.registerTableOption("selectableRangeClearCells", false); //allow clearing of active range
this.registerTableOption("selectableRangeClearCellsValue", undefined); //value for cleared active range
this.registerTableOption("selectableRangeAutoFocus", true); //focus on a cell after resetRanges
this.registerTableFunction("getRangesData", this.getRangesData.bind(this));
this.registerTableFunction("getRanges", this.getRanges.bind(this));
this.registerTableFunction("addRange", this.addRangeFromComponent.bind(this));
this.registerComponentFunction("cell", "getRanges", this.cellGetRanges.bind(this));
this.registerComponentFunction("row", "getRanges", this.rowGetRanges.bind(this));
this.registerComponentFunction("column", "getRanges", this.colGetRanges.bind(this));
}
///////////////////////////////////
/////// Initialization ///////
///////////////////////////////////
initialize() {
if (this.options("selectableRange")) {
if(!this.options("selectableRows")){
this.maxRanges = this.options("selectableRange");
this.initializeTable();
this.initializeWatchers();
}else{
console.warn("SelectRange functionality cannot be used in conjunction with row selection");
}
if(this.options('columns').findIndex((column) => column.frozen) > 0) {
console.warn("Having frozen column in arbitrary position with selectRange option may result in unpredictable behavior.");
}
if(this.options('columns').filter((column) => column.frozen) > 1) {
console.warn("Having multiple frozen columns with selectRange option may result in unpredictable behavior.");
}
}
}
initializeTable() {
this.overlay = document.createElement("div");
this.overlay.classList.add("tabulator-range-overlay");
this.rangeContainer = document.createElement("div");
this.rangeContainer.classList.add("tabulator-range-container");
this.activeRangeCellElement = document.createElement("div");
this.activeRangeCellElement.classList.add("tabulator-range-cell-active");
this.overlay.appendChild(this.rangeContainer);
this.overlay.appendChild(this.activeRangeCellElement);
this.table.rowManager.element.addEventListener("keydown", this.keyDownEvent);
this.resetRanges();
this.table.rowManager.element.appendChild(this.overlay);
this.table.columnManager.element.setAttribute("tabindex", 0);
this.table.element.classList.add("tabulator-ranges");
}
initializeWatchers() {
this.columnSelection = this.options("selectableRangeColumns");
this.rowSelection = this.options("selectableRangeRows");
this.subscribe("column-init", this.initializeColumn.bind(this));
this.subscribe("column-mousedown", this.handleColumnMouseDown.bind(this));
this.subscribe("column-mousemove", this.handleColumnMouseMove.bind(this));
this.subscribe("column-resized", this.handleColumnResized.bind(this));
this.subscribe("column-moving", this.handleColumnMoving.bind(this));
this.subscribe("column-moved", this.handleColumnMoved.bind(this));
this.subscribe("column-width", this.layoutChange.bind(this));
this.subscribe("column-height", this.layoutChange.bind(this));
this.subscribe("column-resized", this.layoutChange.bind(this));
this.subscribe("columns-loaded", this.updateHeaderColumn.bind(this));
this.subscribe("cell-height", this.layoutChange.bind(this));
this.subscribe("cell-rendered", this.renderCell.bind(this));
this.subscribe("cell-mousedown", this.handleCellMouseDown.bind(this));
this.subscribe("cell-mousemove", this.handleCellMouseMove.bind(this));
this.subscribe("cell-click", this.handleCellClick.bind(this));
this.subscribe("cell-editing", this.handleEditingCell.bind(this));
this.subscribe("page-changed", this.redraw.bind(this));
this.subscribe("scroll-vertical", this.layoutChange.bind(this));
this.subscribe("scroll-horizontal", this.layoutChange.bind(this));
this.subscribe("data-destroy", this.tableDestroyed.bind(this));
this.subscribe("data-processed", this.resetRanges.bind(this));
this.subscribe("table-layout", this.layoutElement.bind(this));
this.subscribe("table-redraw", this.redraw.bind(this));
this.subscribe("table-destroy", this.tableDestroyed.bind(this));
this.subscribe("edit-editor-clear", this.finishEditingCell.bind(this));
this.subscribe("edit-blur", this.restoreFocus.bind(this));
this.subscribe("keybinding-nav-prev", this.keyNavigate.bind(this, "left"));
this.subscribe("keybinding-nav-next", this.keyNavigate.bind(this, "right"));
this.subscribe("keybinding-nav-left", this.keyNavigate.bind(this, "left"));
this.subscribe("keybinding-nav-right", this.keyNavigate.bind(this, "right"));
this.subscribe("keybinding-nav-up", this.keyNavigate.bind(this, "up"));
this.subscribe("keybinding-nav-down", this.keyNavigate.bind(this, "down"));
this.subscribe("keybinding-nav-range", this.keyNavigateRange.bind(this));
}
initializeColumn(column) {
if(this.columnSelection && column.definition.headerSort && this.options("headerSortClickElement") !== "icon"){
console.warn("Using column headerSort with selectableRangeColumns option may result in unpredictable behavior. Consider using headerSortClickElement: 'icon'.");
}
if (column.modules.edit) {
// Block editor from taking action so we can trigger edit by
// double clicking.
// column.modules.edit.blocked = true;
}
}
updateHeaderColumn(){
var frozenCols;
if(this.rowSelection){
this.rowHeader = this.table.columnManager.getVisibleColumnsByIndex()[0];
if(this.rowHeader){
this.rowHeader.definition.cssClass = this.rowHeader.definition.cssClass + " tabulator-range-row-header";
if(this.rowHeader.definition.headerSort){
console.warn("Using column headerSort with selectableRangeRows option may result in unpredictable behavior");
}
if(this.rowHeader.definition.editor){
console.warn("Using column editor with selectableRangeRows option may result in unpredictable behavior");
}
}
}
//warn if invalid frozen column configuration detected
if(this.table.modules.frozenColumns && this.table.modules.frozenColumns.active){
frozenCols = this.table.modules.frozenColumns.getFrozenColumns();
if(frozenCols.length > 1 || (frozenCols.length === 1 && frozenCols[0] !== this.rowHeader)){
console.warn("Using frozen columns that are not the range header in combination with the selectRange option may result in unpredictable behavior");
}
}
}
///////////////////////////////////
/////// Table Functions ///////
///////////////////////////////////
getRanges(){
return this.ranges.map((range) => range.getComponent());
}
getRangesData() {
return this.ranges.map((range) => range.getData());
}
addRangeFromComponent(start, end){
start = start ? start._cell : null;
end = end ? end._cell : null;
return this.addRange(start, end);
}
///////////////////////////////////
/////// Component Functions ///////
///////////////////////////////////
cellGetRanges(cell){
var ranges = [];
if (cell.column === this.rowHeader) {
ranges = this.ranges.filter((range) => range.occupiesRow(cell.row));
} else {
ranges = this.ranges.filter((range) => range.occupies(cell));
}
return ranges.map((range) => range.getComponent());
}
rowGetRanges(row){
var ranges = this.ranges.filter((range) => range.occupiesRow(row));
return ranges.map((range) => range.getComponent());
}
colGetRanges(col){
var ranges = this.ranges.filter((range) => range.occupiesColumn(col));
return ranges.map((range) => range.getComponent());
}
///////////////////////////////////
////////// Event Handlers /////////
///////////////////////////////////
_handleMouseUp(e){
this.mousedown = false;
document.removeEventListener("mouseup", this.mouseUpEvent);
}
_handleKeyDown(e) {
if (!this.blockKeydown && (!this.table.modules.edit || (this.table.modules.edit && !this.table.modules.edit.currentCell))) {
if (e.key === "Enter") {
// is editing a cell?
if (this.table.modules.edit && this.table.modules.edit.currentCell) {
return;
}
this.table.modules.edit.editCell(this.getActiveCell());
e.preventDefault();
}
if ((e.key === "Backspace" || e.key === "Delete") && this.options("selectableRangeClearCells")) {
if(this.activeRange){
this.activeRange.clearValues();
}
}
}
}
initializeFocus(cell){
var range;
this.restoreFocus();
try{
if (document.selection) { // IE
range = document.body.createTextRange();
range.moveToElementText(cell.getElement());
range.select();
} else if (window.getSelection) {
range = document.createRange();
range.selectNode(cell.getElement());
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
}
}catch(e){}
}
restoreFocus(element){
this.table.rowManager.element.focus();
return true;
}
///////////////////////////////////
////// Column Functionality ///////
///////////////////////////////////
handleColumnResized(column) {
var selected;
if (this.selecting !== "column" && this.selecting !== "all") {
return;
}
selected = this.ranges.some((range) => range.occupiesColumn(column));
if (!selected) {
return;
}
this.ranges.forEach((range) => {
var selectedColumns = range.getColumns(true);
selectedColumns.forEach((selectedColumn) => {
if (selectedColumn !== column) {
selectedColumn.setWidth(column.width);
}
});
});
}
handleColumnMoving(_event, column) {
this.resetRanges().setBounds(column);
this.overlay.style.visibility = "hidden";
}
handleColumnMoved(from, _to, _after) {
this.activeRange.setBounds(from);
this.layoutElement();
}
handleColumnMouseDown(event, column) {
if (event.button === 2 && (this.selecting === "column" || this.selecting === "all") && this.activeRange.occupiesColumn(column)) {
return;
}
//If columns are movable, allow dragging columns only if they are not
//selected. Dragging selected columns should move the columns instead.
if(this.table.options.movableColumns && this.selecting === "column" && this.activeRange.occupiesColumn(column)){
return;
}
this.mousedown = true;
document.addEventListener("mouseup", this.mouseUpEvent);
this.newSelection(event, column);
}
handleColumnMouseMove(e, column) {
if (column === this.rowHeader || !this.mousedown || this.selecting === 'all') {
return;
}
this.activeRange.setBounds(false, column, true);
}
///////////////////////////////////
//////// Cell Functionality ///////
///////////////////////////////////
renderCell(cell) {
var el = cell.getElement(),
rangeIdx = this.ranges.findIndex((range) => range.occupies(cell));
el.classList.toggle("tabulator-range-selected", rangeIdx !== -1);
el.classList.toggle("tabulator-range-only-cell-selected", this.ranges.length === 1 && this.ranges[0].atTopLeft(cell) && this.ranges[0].atBottomRight(cell));
el.dataset.range = rangeIdx;
}
handleCellMouseDown(event, cell) {
if (event.button === 2 && (this.activeRange.occupies(cell) || ((this.selecting === "row" || this.selecting === "all") && this.activeRange.occupiesRow(cell.row)))) {
return;
}
this.mousedown = true;
document.addEventListener("mouseup", this.mouseUpEvent);
this.newSelection(event, cell);
}
handleCellMouseMove(e, cell) {
if (!this.mousedown || this.selecting === "all") {
return;
}
this.activeRange.setBounds(false, cell, true);
}
handleCellClick(e, cell){
this.initializeFocus(cell);
}
handleEditingCell(cell) {
if(this.activeRange){
this.activeRange.setBounds(cell);
}
}
finishEditingCell() {
this.blockKeydown = true;
this.table.rowManager.element.focus();
setTimeout(() => {
this.blockKeydown = false;
}, 10);
}
///////////////////////////////////
/////// Navigation ///////
///////////////////////////////////
keyNavigate(dir, e){
if(this.navigate(false, false, dir)){
// e.preventDefault();
}
e.preventDefault();
}
keyNavigateRange(e, dir, jump, expand){
if(this.navigate(jump, expand, dir)){
// e.preventDefault();
}
e.preventDefault();
}
navigate(jump, expand, dir) {
var moved = false,
range, rangeEdge, prevRect, nextRow, nextCol, row, column,
rowRect, rowManagerRect, columnRect, columnManagerRect;
// Don't navigate while editing
if (this.table.modules.edit && this.table.modules.edit.currentCell) {
return false;
}
// If there are more than 1 range, use the active range and destroy the others
if (this.ranges.length > 1) {
this.ranges = this.ranges.filter((range) => {
if (range === this.activeRange) {
range.setEnd(range.start.row, range.start.col);
return true;
}
range.destroy();
return false;
});
}
range = this.activeRange;
prevRect = {
top: range.top,
bottom: range.bottom,
left: range.left,
right: range.right
};
rangeEdge = expand ? range.end : range.start;
nextRow = rangeEdge.row;
nextCol = rangeEdge.col;
if(jump){
switch(dir){
case "left":
nextCol = this.findJumpCellLeft(range.start.row, rangeEdge.col);
break;
case "right":
nextCol = this.findJumpCellRight(range.start.row, rangeEdge.col);
break;
case "up":
nextRow = this.findJumpCellUp(rangeEdge.row, range.start.col);
break;
case "down":
nextRow = this.findJumpCellDown(rangeEdge.row, range.start.col);
break;
}
}else{
if(expand){
if ((this.selecting === 'row' && (dir === 'left' || dir === 'right')) || (this.selecting === 'column' && (dir === 'up' || dir === 'down'))) {
return;
}
}
switch(dir){
case "left":
nextCol = Math.max(nextCol - 1, 0);
break;
case "right":
nextCol = Math.min(nextCol + 1, this.getTableColumns().length - 1);
break;
case "up":
nextRow = Math.max(nextRow - 1, 0);
break;
case "down":
nextRow = Math.min(nextRow + 1, this.getTableRows().length - 1);
break;
}
}
if(this.rowHeader && nextCol === 0) {
nextCol = 1;
}
if(!expand){
range.setStart(nextRow, nextCol);
}
range.setEnd(nextRow, nextCol);
if(!expand){
this.selecting = "cell";
}
moved = prevRect.top !== range.top || prevRect.bottom !== range.bottom || prevRect.left !== range.left || prevRect.right !== range.right;
if (moved) {
row = this.getRowByRangePos(range.end.row);
column = this.getColumnByRangePos(range.end.col);
rowRect = row.getElement().getBoundingClientRect();
columnRect = column.getElement().getBoundingClientRect();
rowManagerRect = this.table.rowManager.getElement().getBoundingClientRect();
columnManagerRect = this.table.columnManager.getElement().getBoundingClientRect();
if(!(rowRect.top >= rowManagerRect.top && rowRect.bottom <= rowManagerRect.bottom)){
if(row.getElement().parentNode && column.getElement().parentNode){
// Use faster autoScroll when the elements are on the DOM
this.autoScroll(range, row.getElement(), column.getElement());
}else{
row.getComponent().scrollTo(undefined, false);
}
}
if(!(columnRect.left >= columnManagerRect.left + this.getRowHeaderWidth() && columnRect.right <= columnManagerRect.right)){
if(row.getElement().parentNode && column.getElement().parentNode){
// Use faster autoScroll when the elements are on the DOM
this.autoScroll(range, row.getElement(), column.getElement());
}else{
column.getComponent().scrollTo(undefined, false);
}
}
this.layoutElement();
return true;
}
}
rangeRemoved(removed){
this.ranges = this.ranges.filter((range) => range !== removed);
if(this.activeRange === removed){
if(this.ranges.length){
this.activeRange = this.ranges[this.ranges.length - 1];
}else{
this.addRange();
}
}
this.layoutElement();
}
findJumpRow(column, rows, reverse, emptyStart, emptySide){
if(reverse){
rows = rows.reverse();
}
return this.findJumpItem(emptyStart, emptySide, rows, function(row){return row.getData()[column.getField()];});
}
findJumpCol(row, columns, reverse, emptyStart, emptySide){
if(reverse){
columns = columns.reverse();
}
return this.findJumpItem(emptyStart, emptySide, columns, function(column){return row.getData()[column.getField()];});
}
findJumpItem(emptyStart, emptySide, items, valueResolver){
var nextItem;
for(let currentItem of items){
let currentValue = valueResolver(currentItem);
if(emptyStart){
nextItem = currentItem;
if(currentValue){
break;
}
}else{
if(emptySide){
nextItem = currentItem;
if(currentValue){
break;
}
}else{
if(currentValue){
nextItem = currentItem;
}else{
break;
}
}
}
}
return nextItem;
}
findJumpCellLeft(rowPos, colPos){
var row = this.getRowByRangePos(rowPos),
columns = this.getTableColumns(),
isStartingCellEmpty = this.isEmpty(row.getData()[columns[colPos].getField()]),
isLeftOfStartingCellEmpty = columns[colPos - 1] ? this.isEmpty(row.getData()[columns[colPos - 1].getField()]) : false,
targetCols = this.rowHeader ? columns.slice(1, colPos) : columns.slice(0, colPos),
jumpCol = this.findJumpCol(row, targetCols, true, isStartingCellEmpty, isLeftOfStartingCellEmpty);
if(jumpCol){
return jumpCol.getPosition() - 1;
}
return colPos;
}
findJumpCellRight(rowPos, colPos){
var row = this.getRowByRangePos(rowPos),
columns = this.getTableColumns(),
isStartingCellEmpty = this.isEmpty(row.getData()[columns[colPos].getField()]),
isRightOfStartingCellEmpty = columns[colPos + 1] ? this.isEmpty(row.getData()[columns[colPos + 1].getField()]) : false,
jumpCol = this.findJumpCol(row, columns.slice(colPos + 1, columns.length), false, isStartingCellEmpty, isRightOfStartingCellEmpty);
if(jumpCol){
return jumpCol.getPosition() - 1;
}
return colPos;
}
findJumpCellUp(rowPos, colPos) {
var column = this.getColumnByRangePos(colPos),
rows = this.getTableRows(),
isStartingCellEmpty = this.isEmpty(rows[rowPos].getData()[column.getField()]),
isTopOfStartingCellEmpty = rows[rowPos - 1] ? this.isEmpty(rows[rowPos - 1].getData()[column.getField()]) : false,
jumpRow = this.findJumpRow(column, rows.slice(0, rowPos), true, isStartingCellEmpty, isTopOfStartingCellEmpty);
if(jumpRow){
return jumpRow.position - 1;
}
return rowPos;
}
findJumpCellDown(rowPos, colPos) {
var column = this.getColumnByRangePos(colPos),
rows = this.getTableRows(),
isStartingCellEmpty = this.isEmpty(rows[rowPos].getData()[column.getField()]),
isBottomOfStartingCellEmpty = rows[rowPos + 1] ? this.isEmpty(rows[rowPos + 1].getData()[column.getField()]) : false,
jumpRow = this.findJumpRow(column, rows.slice(rowPos + 1, rows.length), false, isStartingCellEmpty, isBottomOfStartingCellEmpty);
if(jumpRow){
return jumpRow.position - 1;
}
return rowPos;
}
///////////////////////////////////
/////// Selection ///////
///////////////////////////////////
newSelection(event, element) {
var range;
if (element.type === "column") {
if(!this.columnSelection){
return;
}
if (element === this.rowHeader) {
range = this.resetRanges();
this.selecting = "all";
var topLeftCell, bottomRightCell = this.getCell(-1, -1);
if(this.rowHeader){
topLeftCell = this.getCell(0, 1);
}else{
topLeftCell = this.getCell(0, 0);
}
range.setBounds(topLeftCell, bottomRightCell);
return;
} else {
this.selecting = "column";
}
} else if (element.column === this.rowHeader) {
this.selecting = "row";
} else {
this.selecting = "cell";
}
if (event.shiftKey) {
this.activeRange.setBounds(false, element);
} else if (event.ctrlKey) {
this.addRange().setBounds(element);
} else {
this.resetRanges().setBounds(element);
}
}
autoScroll(range, row, column) {
var tableHolder = this.table.rowManager.element,
rect, view, withinHorizontalView, withinVerticalView;
if (typeof row === 'undefined') {
row = this.getRowByRangePos(range.end.row).getElement();
}
if (typeof column === 'undefined') {
column = this.getColumnByRangePos(range.end.col).getElement();
}
rect = {
left: column.offsetLeft,
right: column.offsetLeft + column.offsetWidth,
top: row.offsetTop,
bottom: row.offsetTop + row.offsetHeight,
};
view = {
left: tableHolder.scrollLeft + this.getRowHeaderWidth(),
right: Math.ceil(tableHolder.scrollLeft + tableHolder.clientWidth),
top: tableHolder.scrollTop,
bottom: tableHolder.scrollTop + tableHolder.offsetHeight - this.table.rowManager.scrollbarWidth,
};
withinHorizontalView = view.left < rect.left && rect.left < view.right && view.left < rect.right && rect.right < view.right;
withinVerticalView = view.top < rect.top && rect.top < view.bottom && view.top < rect.bottom && rect.bottom < view.bottom;
if (!withinHorizontalView) {
if (rect.left < view.left) {
tableHolder.scrollLeft = rect.left - this.getRowHeaderWidth();
} else if (rect.right > view.right) {
tableHolder.scrollLeft = Math.min(rect.right - tableHolder.clientWidth, rect.left - this.getRowHeaderWidth());
}
}
if (!withinVerticalView) {
if (rect.top < view.top) {
tableHolder.scrollTop = rect.top;
} else if (rect.bottom > view.bottom) {
tableHolder.scrollTop = rect.bottom - tableHolder.clientHeight;
}
}
}
///////////////////////////////////
/////// Layout ///////
///////////////////////////////////
layoutChange(){
this.overlay.style.visibility = "hidden";
clearTimeout(this.layoutChangeTimeout);
this.layoutChangeTimeout = setTimeout(this.layoutRanges.bind(this), 200);
}
redraw(force) {
if (force) {
this.selecting = 'cell';
this.resetRanges();
this.layoutElement();
}
}
layoutElement(visibleRows) {
var rows;
if (visibleRows) {
rows = this.table.rowManager.getVisibleRows(true);
} else {
rows = this.table.rowManager.getRows();
}
rows.forEach((row) => {
if (row.type === "row") {
this.layoutRow(row);
row.cells.forEach((cell) => this.renderCell(cell));
}
});
this.getTableColumns().forEach((column) => {
this.layoutColumn(column);
});
this.layoutRanges();
}
layoutRow(row) {
var el = row.getElement(),
selected = false,
occupied = this.ranges.some((range) => range.occupiesRow(row));
if (this.selecting === "row") {
selected = occupied;
} else if (this.selecting === "all") {
selected = true;
}
el.classList.toggle("tabulator-range-selected", selected);
el.classList.toggle("tabulator-range-highlight", occupied);
}
layoutColumn(column) {
var el = column.getElement(),
selected = false,
occupied = this.ranges.some((range) => range.occupiesColumn(column));
if (this.selecting === "column") {
selected = occupied;
} else if (this.selecting === "all") {
selected = true;
}
el.classList.toggle("tabulator-range-selected", selected);
el.classList.toggle("tabulator-range-highlight", occupied);
}
layoutRanges() {
var activeCell, activeCellEl, activeRowEl;
if (!this.table.initialized) {
return;
}
activeCell = this.getActiveCell();
if (!activeCell) {
return;
}
activeCellEl = activeCell.getElement();
activeRowEl = activeCell.row.getElement();
if(this.table.rtl){
this.activeRangeCellElement.style.right = activeRowEl.offsetWidth - activeCellEl.offsetLeft - activeCellEl.offsetWidth + "px";
}else{
this.activeRangeCellElement.style.left = activeRowEl.offsetLeft + activeCellEl.offsetLeft + "px";
}
this.activeRangeCellElement.style.top = activeRowEl.offsetTop + "px";
this.activeRangeCellElement.style.width = activeCellEl.offsetWidth + "px";
this.activeRangeCellElement.style.height = activeRowEl.offsetHeight + "px";
this.ranges.forEach((range) => range.layout());
this.overlay.style.visibility = "visible";
}
///////////////////////////////////
/////// Helper Functions ///////
///////////////////////////////////
getCell(rowIdx, colIdx) {
var row;
if (colIdx < 0) {
colIdx = this.getTableColumns().length + colIdx;
if (colIdx < 0) {
return null;
}
}
if (rowIdx < 0) {
rowIdx = this.getTableRows().length + rowIdx;
}
row = this.table.rowManager.getRowFromPosition(rowIdx + 1);
return row ? row.getCells(false, true).filter((cell) => cell.column.visible)[colIdx] : null;
}
getActiveCell() {
return this.getCell(this.activeRange.start.row, this.activeRange.start.col);
}
getRowByRangePos(pos) {
return this.getTableRows()[pos];
}
getColumnByRangePos(pos) {
return this.getTableColumns()[pos];
}
getTableRows() {
return this.table.rowManager.getDisplayRows().filter(row=> row.type === "row");
}
getTableColumns() {
return this.table.columnManager.getVisibleColumnsByIndex();
}
addRange(start, end) {
var range;
if(this.maxRanges !== true && this.ranges.length >= this.maxRanges){
this.ranges.shift().destroy();
}
range = new Range(this.table, this, start, end);
this.activeRange = range;
this.ranges.push(range);
this.rangeContainer.appendChild(range.element);
return range;
}
resetRanges() {
var range, cell, visibleCells;
this.ranges.forEach((range) => range.destroy());
this.ranges = [];
range = this.addRange();
if(this.table.rowManager.activeRows.length){
visibleCells = this.table.rowManager.activeRows[0].cells.filter((cell) => cell.column.visible);
cell = visibleCells[this.rowHeader ? 1 : 0];
if(cell){
range.setBounds(cell);
if(this.options("selectableRangeAutoFocus")){
this.initializeFocus(cell);
}
}
}
return range;
}
tableDestroyed(){
document.removeEventListener("mouseup", this.mouseUpEvent);
this.table.rowManager.element.removeEventListener("keydown", this.keyDownEvent);
}
selectedRows(component) {
return component ? this.activeRange.getRows().map((row) => row.getComponent()) : this.activeRange.getRows();
}
selectedColumns(component) {
return component ? this.activeRange.getColumns().map((col) => col.getComponent()) : this.activeRange.getColumns();
}
getRowHeaderWidth(){
if(!this.rowHeader){
return 0;
}
return this.rowHeader.getElement().offsetWidth;
}
isEmpty(value) {
return value === null || value === undefined || value === "";
}
}