UNPKG

ag-grid

Version:

Advanced Javascript Datagrid. Supports raw Javascript, AngularJS 1.x, AngularJS 2.0 and Web Components

430 lines (370 loc) 16.7 kB
/// <reference path="../gridOptionsWrapper.ts" /> /// <reference path="../grid.ts" /> /// <reference path="../utils.ts" /> /// <reference path="../columnController.ts" /> /// <reference path="../expressionService.ts" /> /// <reference path="rowRenderer.ts" /> /// <reference path="../templateService.ts" /> /// <reference path="../selectionController.ts" /> /// <reference path="renderedCell.ts" /> /// <reference path="../virtualDom/vHtmlElement.ts" /> module ag.grid { var _ = Utils; export class RenderedRow { public vPinnedRow: any; public vBodyRow: any; private renderedCells: {[key: number]: RenderedCell} = {}; private scope: any; private node: any; private rowIndex: number; private cellRendererMap: {[key: string]: any}; private gridOptionsWrapper: GridOptionsWrapper; private parentScope: any; private angularGrid: Grid; private columnController: ColumnController; private expressionService: ExpressionService; private rowRenderer: RowRenderer; private selectionRendererFactory: SelectionRendererFactory; private $compile: any; private templateService: TemplateService; private selectionController: SelectionController; private pinning: boolean; private eBodyContainer: HTMLElement; private ePinnedContainer: HTMLElement; private valueService: ValueService; private eventService: EventService; constructor(gridOptionsWrapper: GridOptionsWrapper, valueService: ValueService, parentScope: any, angularGrid: Grid, columnController: ColumnController, expressionService: ExpressionService, cellRendererMap: {[key: string]: any}, selectionRendererFactory: SelectionRendererFactory, $compile: any, templateService: TemplateService, selectionController: SelectionController, rowRenderer: RowRenderer, eBodyContainer: HTMLElement, ePinnedContainer: HTMLElement, node: any, rowIndex: number, eventService: EventService) { this.gridOptionsWrapper = gridOptionsWrapper; this.valueService = valueService; this.parentScope = parentScope; this.angularGrid = angularGrid; this.expressionService = expressionService; this.columnController = columnController; this.cellRendererMap = cellRendererMap; this.selectionRendererFactory = selectionRendererFactory; this.$compile = $compile; this.templateService = templateService; this.selectionController = selectionController; this.rowRenderer = rowRenderer; this.eBodyContainer = eBodyContainer; this.ePinnedContainer = ePinnedContainer; this.pinning = columnController.isPinning(); this.eventService = eventService; var groupHeaderTakesEntireRow = this.gridOptionsWrapper.isGroupUseEntireRow(); var rowIsHeaderThatSpans = node.group && groupHeaderTakesEntireRow; this.vBodyRow = this.createRowContainer(); if (this.pinning) { this.vPinnedRow = this.createRowContainer(); } this.rowIndex = rowIndex; this.node = node; this.scope = this.createChildScopeOrNull(node.data); if (!rowIsHeaderThatSpans) { this.drawNormalRow(); } this.addDynamicStyles(); this.addDynamicClasses(); var rowStr = this.rowIndex.toString(); if (this.node.floatingBottom) { rowStr = 'fb-' + rowStr; } else if (this.node.floatingTop) { rowStr = 'ft-' + rowStr; } this.vBodyRow.setAttribute('row', rowStr); if (this.pinning) { this.vPinnedRow.setAttribute('row', rowStr); } // if showing scrolls, position on the container if (!this.gridOptionsWrapper.isForPrint()) { this.vBodyRow.style.top = (this.gridOptionsWrapper.getRowHeight() * this.rowIndex) + "px"; if (this.pinning) { this.vPinnedRow.style.top = (this.gridOptionsWrapper.getRowHeight() * this.rowIndex) + "px"; } } this.vBodyRow.style.height = (this.gridOptionsWrapper.getRowHeight()) + "px"; if (this.pinning) { this.vPinnedRow.style.height = (this.gridOptionsWrapper.getRowHeight()) + "px"; } // if group item, insert the first row if (rowIsHeaderThatSpans) { this.createGroupRow(); } this.bindVirtualElement(this.vBodyRow); if (this.pinning) { this.bindVirtualElement(this.vPinnedRow); } if (this.scope) { this.$compile(this.vBodyRow.getElement())(this.scope); if (this.pinning) { this.$compile(this.vPinnedRow.getElement())(this.scope); } } this.eBodyContainer.appendChild(this.vBodyRow.getElement()); if (this.pinning) { this.ePinnedContainer.appendChild(this.vPinnedRow.getElement()); } } public onRowSelected(selected: boolean): void { _.iterateObject(this.renderedCells, (key: any, renderedCell: RenderedCell)=> { renderedCell.setSelected(selected); }); } public softRefresh(): void { _.iterateObject(this.renderedCells, (key: any, renderedCell: RenderedCell)=> { if (renderedCell.isVolatile()) { renderedCell.refreshCell(); } }); } public getRenderedCellForColumn(column: Column): RenderedCell { return this.renderedCells[column.index]; } public getCellForCol(column: Column): any { var renderedCell = this.renderedCells[column.index]; if (renderedCell) { return renderedCell.getVGridCell().getElement(); } else { return null; } } public destroy(): void { this.destroyScope(); if (this.pinning) { this.ePinnedContainer.removeChild(this.vPinnedRow.getElement()); } this.eBodyContainer.removeChild(this.vBodyRow.getElement()); } private destroyScope(): void { if (this.scope) { this.scope.$destroy(); this.scope = null; } } public isDataInList(rows: any[]): boolean { return rows.indexOf(this.node.data) >= 0; } public isNodeInList(nodes: RowNode[]): boolean { return nodes.indexOf(this.node) >= 0; } public isGroup(): boolean { return this.node.group === true; } private drawNormalRow() { var columns = this.columnController.getDisplayedColumns(); for (var i = 0; i<columns.length; i++) { var column = columns[i]; var firstCol = i === 0; var renderedCell = new RenderedCell(firstCol, column, this.$compile, this.rowRenderer, this.gridOptionsWrapper, this.expressionService, this.selectionRendererFactory, this.selectionController, this.templateService, this.cellRendererMap, this.node, this.rowIndex, this.scope, this.columnController, this.valueService, this.eventService); var vGridCell = renderedCell.getVGridCell(); if (column.pinned) { this.vPinnedRow.appendChild(vGridCell); } else { this.vBodyRow.appendChild(vGridCell); } this.renderedCells[column.index] = renderedCell; } } private bindVirtualElement(vElement: ag.vdom.VHtmlElement): void { var html = vElement.toHtmlString(); var element: Element = <Element> _.loadTemplate(html); vElement.elementAttached(element); } private createGroupRow() { var eGroupRow = this.createGroupSpanningEntireRowCell(false); if (this.pinning) { this.vPinnedRow.appendChild(eGroupRow); var eGroupRowPadding = this.createGroupSpanningEntireRowCell(true); this.vBodyRow.appendChild(eGroupRowPadding); } else { this.vBodyRow.appendChild(eGroupRow); } } private createGroupSpanningEntireRowCell(padding: any) { var eRow: any; // padding means we are on the right hand side of a pinned table, ie // in the main body. if (padding) { eRow = document.createElement('span'); } else { var rowCellRenderer = this.gridOptionsWrapper.getGroupRowRenderer(); if (!rowCellRenderer) { rowCellRenderer = { renderer: 'group', innerRenderer: this.gridOptionsWrapper.getGroupRowInnerRenderer() }; } var params = { node: this.node, data: this.node.data, rowIndex: this.rowIndex, api: this.gridOptionsWrapper.getApi(), colDef: { cellRenderer: rowCellRenderer } }; eRow = this.cellRendererMap['group'](params); } if (this.node.footer) { _.addCssClass(eRow, 'ag-footer-cell-entire-row'); } else { _.addCssClass(eRow, 'ag-group-cell-entire-row'); } return eRow; } public setMainRowWidth(width: number) { this.vBodyRow.addStyles({width: width + "px"}); } private createChildScopeOrNull(data: any) { if (this.gridOptionsWrapper.isAngularCompileRows()) { var newChildScope = this.parentScope.$new(); newChildScope.data = data; return newChildScope; } else { return null; } } private addDynamicStyles() { var rowStyle = this.gridOptionsWrapper.getRowStyle(); if (rowStyle) { if (typeof rowStyle === 'function') { console.log('ag-Grid: rowStyle should be a string or an array, not be a function, use getRowStyle() instead'); } else { this.vBodyRow.addStyles(rowStyle); if (this.pinning) { this.vPinnedRow.addStyles(rowStyle); } } } var rowStyleFunc = this.gridOptionsWrapper.getRowStyleFunc(); if (rowStyleFunc) { var params = { data: this.node.data, node: this.node, api: this.gridOptionsWrapper.getApi(), context: this.gridOptionsWrapper.getContext(), $scope: this.scope }; var cssToUseFromFunc = rowStyleFunc(params); this.vBodyRow.addStyles(cssToUseFromFunc); if (this.pinning) { this.vPinnedRow.addStyles(cssToUseFromFunc); } } } private createRowContainer() { var vRow = new ag.vdom.VHtmlElement('div'); var that = this; vRow.addEventListener("click", function (event) { that.angularGrid.onRowClicked(event, Number(this.getAttribute("row")), that.node) }); return vRow; } public getRowNode(): any { return this.node; } public getRowIndex(): any { return this.rowIndex; } public refreshCells(colIds: string[]): void { if (!colIds) { return; } var columnsToRefresh = this.columnController.getColumns(colIds); _.iterateObject(this.renderedCells, (key: any, renderedCell: RenderedCell)=> { var colForCel = renderedCell.getColumn(); if (columnsToRefresh.indexOf(colForCel)>=0) { renderedCell.refreshCell(); } }); } private addDynamicClasses() { var classes: string[] = []; classes.push('ag-row'); classes.push(this.rowIndex % 2 == 0 ? "ag-row-even" : "ag-row-odd"); if (this.selectionController.isNodeSelected(this.node)) { classes.push("ag-row-selected"); } if (this.node.group) { classes.push("ag-row-group"); // if a group, put the level of the group in classes.push("ag-row-level-" + this.node.level); if (!this.node.footer && this.node.expanded) { classes.push("ag-row-group-expanded"); } if (!this.node.footer && !this.node.expanded) { // opposite of expanded is contracted according to the internet. classes.push("ag-row-group-contracted"); } if (this.node.footer) { classes.push("ag-row-footer"); } } else { // if a leaf, and a parent exists, put a level of the parent, else put level of 0 for top level item if (this.node.parent) { classes.push("ag-row-level-" + (this.node.parent.level + 1)); } else { classes.push("ag-row-level-0"); } } // add in extra classes provided by the config var gridOptionsRowClass = this.gridOptionsWrapper.getRowClass(); if (gridOptionsRowClass) { if (typeof gridOptionsRowClass === 'function') { console.warn('ag-Grid: rowClass should not be a function, please use getRowClass instead'); } else { if (typeof gridOptionsRowClass === 'string') { classes.push(gridOptionsRowClass); } else if (Array.isArray(gridOptionsRowClass)) { gridOptionsRowClass.forEach(function (classItem: any) { classes.push(classItem); }); } } } var gridOptionsRowClassFunc = this.gridOptionsWrapper.getRowClassFunc(); if (gridOptionsRowClassFunc) { var params = { node: this.node, data: this.node.data, rowIndex: this.rowIndex, context: this.gridOptionsWrapper.getContext(), api: this.gridOptionsWrapper.getApi() }; var classToUseFromFunc = gridOptionsRowClassFunc(params); if (classToUseFromFunc) { if (typeof classToUseFromFunc === 'string') { classes.push(classToUseFromFunc); } else if (Array.isArray(classToUseFromFunc)) { classToUseFromFunc.forEach(function (classItem: any) { classes.push(classItem); }); } } } this.vBodyRow.addClasses(classes); if (this.pinning) { this.vPinnedRow.addClasses(classes); } } } }