diff --git a/treegrid.js b/treegrid.js index fc87030..430e55f 100644 --- a/treegrid.js +++ b/treegrid.js @@ -1,7 +1,7 @@ /** * Very simple and fast tree grid/table, compatible with dynamic loading and stickyheaders.js * License: MPL 2.0+, (c) Vitaliy Filippov 2016+ - * Version: 2016-10-07 + * Version: 2016-10-08 */ /** @@ -56,16 +56,16 @@ * // called before expanding node. should return false if you want to prevent expanding the node * TG.onExpand = function(node) {}; * // called before a cell is selected with mouse - * TG.onCellSelect = function(node, colIndex, td) { return ; } + * TG.onCellSelect = function(node, subrowIndex, colIndex, td) { return ; } * // called when all currently selected cells are deselected - * TG.onDeselectAllCells = function(node, colIndex, td) {} + * TG.onDeselectAllCells = function() {} * // called before a cell is edited - * TG.onStartCellEdit = function(node, colIndex, td) { return { + * TG.onStartCellEdit = function(node, subrowIndex, colIndex, td) { return { * abort: , * value: * } } * // called before a cell is stopped being edited - * TG.onStopCellEdit = function (node, colIndex, value, td) { return { html: } } + * TG.onStopCellEdit = function (node, subrowIndex, colIndex, value, td) { return { html: } } * */ function TreeGrid(options) @@ -165,6 +165,17 @@ TreeGrid.prototype._getCellIndex = function(n, sticky) return i; } +TreeGrid.prototype._getSubrow = function(cell) +{ + var row = cell.parentNode, subrow = 0; + while (row.previousSibling && row.previousSibling._node == row._node) + { + row = row.previousSibling; + subrow++; + } + return subrow; +} + TreeGrid.prototype.initCellEditing = function() { var self = this; @@ -177,7 +188,8 @@ TreeGrid.prototype.initCellEditing = function() td = td.parentNode; if (td.nodeName == 'TD' && td.parentNode._node && td.previousSibling && td.className != 'celleditor') { - var params = self.onStartCellEdit && self.onStartCellEdit(td.parentNode._node, self._getCellIndex(td, true), td) || {}; + var params = self.onStartCellEdit && + self.onStartCellEdit(td.parentNode._node, self._getSubrow(td), self._getCellIndex(td, true), td) || {}; if (params.abort) return; self.editedCells.push(td); @@ -211,10 +223,12 @@ TreeGrid.prototype.initCellEditing = function() TreeGrid.prototype.stopCellEditing = function(td, _int) { var i = this._getCellIndex(td, true); + var subrow = this._getSubrow(td); var node = td.parentNode._node; node._oldCells[i] = undefined; - var params = this.onStopCellEdit && this.onStopCellEdit(node, i, td.firstChild ? td.firstChild.value : null, td) || {}; - node.render(i); + var params = this.onStopCellEdit && + this.onStopCellEdit(node, subrow, i, td.firstChild ? td.firstChild.value : null, td) || {}; + node.render(i, subrow, true); if (!_int) { for (var i = 0; i < this.editedCells.length; i++) @@ -242,7 +256,8 @@ TreeGrid.prototype.initCellSelection = function(restrictToNode) if (!cell.parentNode._node || cell.className.indexOf(' selected') >= 0) return; var i = self._getCellIndex(cell, true); - if (!self.onCellSelect || self.onCellSelect(cell.parentNode._node, i, cell)) + var subrow = self._getSubrow(cell); + if (!self.onCellSelect || self.onCellSelect(cell.parentNode._node, subrow, i, cell)) cell.className += ' selected'; }; @@ -481,7 +496,7 @@ TreeGridNode.prototype._hashEqual = function(a, b) return true; } -TreeGridNode.prototype._renderCell = function(rowIndex, colIndex, cell) +TreeGridNode.prototype._renderCell = function(rowIndex, colIndex, cell, force) { // this may be the first render of a row inside a stickyheaders grid var tr = this.tr[rowIndex]; @@ -489,35 +504,40 @@ TreeGridNode.prototype._renderCell = function(rowIndex, colIndex, cell) while (!tr.cells[ri]) tr.appendChild(document.createElement('td')); // virtualDOM-like approach: compare old HTML properties - if (!this._oldCells[rowIndex] || !this._oldCells[rowIndex][colIndex] || + if (force || !this._oldCells[rowIndex] || !this._oldCells[rowIndex][colIndex] || cell && !this._hashEqual(this._oldCells[rowIndex][colIndex], cell)) { this.grid._setProps(tr.cells[ri], cell); - if (rowIndex == 0 && colIndex == 0) - this._addCollapser(); + if (colIndex == 0) + { + if (rowIndex == 0) + this._addCollapser(); + else + tr.cells[ri].style.paddingLeft = (this.grid._initialPadding + this.grid.levelIndent * this.level + 20) + 'px'; + } } } -TreeGridNode.prototype.render = function(colidx, rowidx) +TreeGridNode.prototype.render = function(colidx, rowidx, force) { var cells = this.grid.renderer(this, colidx, rowidx); if (this.tr.length == 1) cells = [ cells ]; - if (!(colidx !== null && colidx !== undefined && colidx >= 0 && colidx < this.grid.header.length)) + if (colidx === null || colidx < 0 || colidx >= this.grid.header.length) colidx = undefined; - if (!(this.tr.length > 1 && rowidx !== null && rowidx !== undefined && rowidx >= 0 && rowidx < this.tr.length)) + if (rowidx === null || rowidx < 0 || rowidx >= this.tr.length) rowidx = undefined; if (rowidx !== undefined) { if (colidx !== undefined) { - this._renderCell(rowidx, colidx, cells[rowidx] && cells[rowidx][colidx]); + this._renderCell(rowidx, colidx, cells[rowidx] && cells[rowidx][colidx], force); this._oldCells[rowidx][colidx] = cells[rowidx] && cells[rowidx][colidx]; } else { for (var j = 0; j < this.grid.header.length; j++) - this._renderCell(rowidx, j, cells[rowidx] && cells[rowidx][j]); + this._renderCell(rowidx, j, cells[rowidx] && cells[rowidx][j], force); this._oldCells[rowidx] = cells[rowidx]; } } @@ -525,7 +545,7 @@ TreeGridNode.prototype.render = function(colidx, rowidx) { for (var i = 0; i < this.tr.length; i++) { - this._renderCell(i, colidx, cells[i] && cells[i][colidx]); + this._renderCell(i, colidx, cells[i] && cells[i][colidx], force); this._oldCells[i][colidx] = cells[i] && cells[i][colidx]; } } @@ -533,7 +553,7 @@ TreeGridNode.prototype.render = function(colidx, rowidx) { for (var i = 0; i < this.tr.length; i++) for (var j = 0; j < this.grid.header.length; j++) - this._renderCell(i, j, cells[i] && cells[i][j]); + this._renderCell(i, j, cells[i] && cells[i][j], force); this._oldCells = cells; } }