UNPKG

primeng

Version:

PrimeNG is an open source UI library for Angular featuring a rich set of 80+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeB

1,556 lines (1,476 loc) 222 kB
import * as i1 from '@angular/common'; import { isPlatformBrowser, DOCUMENT, CommonModule } from '@angular/common'; import * as i0 from '@angular/core'; import { Injectable, inject, EventEmitter, NgZone, booleanAttribute, numberAttribute, ContentChildren, ContentChild, ViewChild, Output, Input, ViewEncapsulation, Component, PLATFORM_ID, Inject, HostListener, Directive, ChangeDetectionStrategy, NgModule } from '@angular/core'; import * as i4 from '@angular/forms'; import { FormsModule } from '@angular/forms'; import { resolveFieldData, isEmpty, getOffset, addClass, findSingle, getIndex, calculateScrollbarWidth, removeClass, hasClass, getHiddenElementOuterWidth, getHiddenElementOuterHeight, reorderArray, equals, find, calculateScrollbarHeight, clearSelection, invokeElementMethod, focus, isNotEmpty, getAttribute } from '@primeuix/utils'; import * as i3 from 'primeng/api'; import { FilterService, PrimeTemplate, SharedModule } from 'primeng/api'; import { BaseComponent } from 'primeng/basecomponent'; import { Checkbox } from 'primeng/checkbox'; import { DomHandler } from 'primeng/dom'; import { SpinnerIcon, ArrowDownIcon, ArrowUpIcon, SortAltIcon, SortAmountUpAltIcon, SortAmountDownIcon, ChevronDownIcon, ChevronRightIcon, CheckIcon, MinusIcon } from 'primeng/icons'; import * as i2 from 'primeng/paginator'; import { PaginatorModule } from 'primeng/paginator'; import { Ripple } from 'primeng/ripple'; import { Scroller } from 'primeng/scroller'; import { Subject } from 'rxjs'; import { BaseStyle } from 'primeng/base'; const theme = ({ dt }) => ` /* For PrimeNG */ .p-treetable { position: relative; } .p-treetable table { border-collapse: collapse; width: 100%; table-layout: fixed; } .p-treetable .p-sortable-column { cursor: pointer; user-select: none; } .p-treetable .p-sortable-column .p-column-title, .p-treetable .p-sortable-column .p-sortable-column-icon, .p-treetable .p-sortable-column .p-sortable-column-badge { vertical-align: middle; } .p-treetable .p-sortable-column .p-sortable-column-badge { display: inline-flex; align-items: center; justify-content: center; } .p-treetable-auto-layout>.p-treetable-wrapper { overflow-x: auto; } .p-treetable-auto-layout>.p-treetable-wrapper>table { table-layout: auto; } .p-treetable-hoverable-rows .p-treetable-tbody>tr { cursor: pointer; } .p-treetable-toggler { cursor: pointer; user-select: none; display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; overflow: hidden; position: relative; } /* Scrollable */ .p-treetable-scrollable-wrapper { position: relative; } .p-treetable-scrollable-header, .p-treetable-scrollable-footer { overflow: hidden; flex-shrink: 0; } .p-treetable-scrollable-body { overflow: auto; position: relative; } .p-treetable-virtual-table { position: absolute; } /* Frozen Columns */ .p-treetable-frozen-view .p-treetable-scrollable-body { overflow: hidden; } .p-treetable-frozen-view>.p-treetable-scrollable-body>table>.p-treetable-tbody>tr>td:last-child { border-right: 0 none; } .p-treetable-unfrozen-view { position: absolute; top: 0; } /* Flex Scrollable */ .p-treetable-flex-scrollable { display: flex; flex-direction: column; flex: 1; height: 100%; } .p-treetable-flex-scrollable .p-treetable-scrollable-wrapper, .p-treetable-flex-scrollable .p-treetable-scrollable-view { display: flex; flex-direction: column; flex: 1; height: 100%; } .p-treetable-flex-scrollable .p-treetable-virtual-scrollable-body { flex: 1; } /* Resizable */ .p-treetable-resizable>.p-treetable-wrapper { overflow-x: auto; } .p-treetable-resizable .p-treetable-thead>tr>th, .p-treetable-resizable .p-treetable-tfoot>tr>td, .p-treetable-resizable .p-treetable-tbody>tr>td { overflow: hidden; } .p-treetable-resizable .p-resizable-column { background-clip: padding-box; position: relative; } .p-treetable-resizable-fit .p-resizable-column:last-child .p-column-resizer { display: none; } .p-treetable .p-column-resizer { display: block; position: absolute; top: 0; right: 0; margin: 0; width: ${dt('treetable.column.resizer.width')}; height: 100%; padding: 0px; cursor: col-resize; border: 1px solid transparent; } .p-treetable .p-column-resizer-helper { width: ${dt('treetable.resize.indicator.width')}; position: absolute; z-index: 10; display: none; background: ${dt('treetable.resize.indicator.color')}; } .p-treetable .p-row-editor-init, .p-treetable .p-row-editor-save, .p-treetable .p-row-editor-cancel { display: inline-flex; align-items: center; justify-content: center; overflow: hidden; position: relative; } /* Reorder */ .p-treetable-reorder-indicator-up, .p-treetable-reorder-indicator-down { position: absolute; display: none; } [ttReorderableColumn] { cursor: move; } /* Loader */ .p-treetable-mask { position: absolute !important; display: flex; align-items: center; justify-content: center; z-index: 2; } .p-treetable-loading-icon { font-size: ${dt('treetable.loading.icon.size')}; width: ${dt('treetable.loading.icon.size')}; height: ${dt('treetable.loading.icon.size')}; } /* Virtual Scroll */ .p-treetable .p-scroller-loading { transform: none !important; min-height: 0; position: sticky; top: 0; left: 0; } .p-treetable .p-paginator-top { border-color: ${dt('treetable.paginator.top.border.color')}; border-style: solid; border-width: ${dt('treetable.paginator.top.border.width')}; } .p-treetable .p-paginator-bottom { border-color: ${dt('treetable.paginator.bottom.border.color')}; border-style: solid; border-width: ${dt('treetable.paginator.bottom.border.width')}; } .p-treetable .p-treetable-header { background: ${dt('treetable.header.background')}; color: ${dt('treetable.header.color')}; border-color: ${dt('treetable.header.border.color')}; border-style: solid; border-width: ${dt('treetable.header.border.width')}; padding: ${dt('treetable.header.padding')}; font-weight: ${dt('treetable.column.title.font.weight')}; } .p-treetable .p-treetable-footer { background: ${dt('treetable.footer.background')}; color: ${dt('treetable.footer.color')}; border-color: ${dt('treetable.footer.border.color')}; border-style: solid; border-width: ${dt('treetable.footer.border.width')}; padding: ${dt('treetable.footer.padding')}; font-weight: ${dt('treetable.column.footer.font.weight')}; } .p-treetable .p-treetable-thead>tr>th { padding: ${dt('treetable.header.cell.padding')}; background: ${dt('treetable.header.cell.background')}; border-color: ${dt('treetable.header.cell.border.color')}; border-style: solid; border-width: 0 0 1px 0; color: ${dt('treetable.header.cell.color')}; font-weight: ${dt('treetable.column.title.font.weight')}; text-align: start; transition: background ${dt('treetable.transition.duration')}, color ${dt('treetable.transition.duration')}, border-color ${dt('treetable.transition.duration')}, outline-color ${dt('treetable.transition.duration')}, box-shadow ${dt('treetable.transition.duration')}; } .p-treetable .p-treetable-tfoot>tr>td { text-align: start; padding: ${dt('treetable.footer.cell.padding')}; border-color: ${dt('treetable.footer.cell.border.color')}; border-style: solid; border-width: 0 0 1px 0; color: ${dt('treetable.footer.cell.color')}; background: ${dt('treetable.footer.cell.background')}; font-weight: ${dt('treetable.column.footer.font.weight')}; } .p-treetable .p-sortable-column { cursor: pointer; user-select: none; outline-color: transparent; vertical-align: middle; } .p-treetable .p-sortable-column .p-sortable-column-icon { color: ${dt('treetable.sort.icon.color')}; transition: color ${dt('treetable.transition.duration')}; } .p-treetable .p-sortable-column:not(.p-treetable-column-sorted):hover { background: ${dt('treetable.header.cell.hover.background')}; color: ${dt('treetable.header.cell.hover.color')}; } .p-treetable .p-sortable-column:not(.p-treetable-column-sorted):hover .p-sortable-column-icon { color: ${dt('treetable.sort.icon.hover.color')}; } .p-treetable .p-sortable-column.p-treetable-column-sorted { background: ${dt('treetable.header.cell.selected.background')}; color: ${dt('treetable.header.cell.selected.color')}; } .p-treetable .p-sortable-column.p-treetable-column-sorted .p-sortable-column-icon { color: ${dt('treetable.header.cell.selected.color')}; } .p-treetable .p-sortable-column:focus-visible { box-shadow: ${dt('treetable.header.cell.focus.ring.shadow')}; outline: ${dt('treetable.header.cell.focus.ring.width')} ${dt('treetable.header.cell.focus.ring.style')} ${dt('treetable.header.cell.focus.ring.color')}; outline-offset: ${dt('treetable.header.cell.focus.ring.offset')}; } .p-treetable-hoverable .p-treetable-selectable-row { cursor: pointer; } .p-treetable .p-treetable-tbody > tr { outline-color: transparent; background: ${dt('treetable.row.background')}; color: ${dt('treetable.row.color')}; transition: background ${dt('treetable.transition.duration')}, color ${dt('treetable.transition.duration')}, border-color ${dt('treetable.transition.duration')}, outline-color ${dt('treetable.transition.duration')}, box-shadow ${dt('treetable.transition.duration')}; } .p-treetable .p-treetable-tbody>tr>td { text-align: start; border-color: ${dt('treetable.body.cell.border.color')}; border-style: solid; border-width: 0 0 1px 0; padding: ${dt('treetable.body.cell.padding')}; } .p-treetable .p-treetable-tbody>tr>td .p-treetable-toggler { display: inline-flex; align-items: center; justify-content: center; overflow: hidden; position: relative; width: ${dt('treetable.node.toggle.button.size')}; height: ${dt('treetable.node.toggle.button.size')}; color: ${dt('treetable.node.toggle.button.color')}; border: 0 none; background: transparent; cursor: pointer; border-radius: ${dt('treetable.node.toggle.button.border.radius')}; transition: background ${dt('treetable.transition.duration')}, color ${dt('treetable.transition.duration')}, border-color ${dt('treetable.transition.duration')}, outline-color ${dt('treetable.transition.duration')}, box-shadow ${dt('treetable.transition.duration')}; outline-color: transparent; user-select: none; } .p-treetable .p-treetable-tbody>tr>td .p-treetable-toggler:enabled:hover { color: ${dt('treetable.node.toggle.button.hover.color')}; background: ${dt('treetable.node.toggle.button.hover.background')}; } .p-treetable .p-treetable-tbody>tr>tr.treetable-row-selected .p-treetable-toggler:hover { background: ${dt('treetable.node.toggle.button.selected.hover.background')}; color: ${dt('treetable.node.toggle.button.selected.hover.color')}; } .p-treetable .p-treetable-tbody>tr>td .p-treetable-toggler:focus-visible { box-shadow: ${dt('treetable.node.toggle.button.focus.ring.shadow')}; outline: ${dt('treetable.node.toggle.button.focus.ring.width')} ${dt('treetable.node.toggle.button.focus.ring.style')} ${dt('treetable.node.toggle.button.focus.ring.color')}; outline-offset: ${dt('treetable.node.toggle.button.focus.ring.offset')}; } .p-treetable .p-treetable-tbody>tr.p-treetable-row-selected { background: ${dt('treetable.row.selected.background')}; color: ${dt('treetable.row.selected.color')}; } .p-treetable-tbody > tr:focus-visible, .p-treetable-tbody > tr.p-treetable-contextmenu-row-selected { box-shadow: ${dt('treetable.row.focus.ring.shadow')}; outline: ${dt('treetable.row.focus.ring.width')} ${dt('treetable.row.focus.ring.style')} ${dt('treetable.row.focus.ring.color')}; outline-offset: ${dt('treetable.row.focus.ring.offset')}; } .p-treetable .p-treetable-tbody>tr.p-treetable-row-selected .p-treetable-toggler { color: inherit; } .p-treetable .p-treetable-tbody>tr.p-treetable-row-selected .p-treetable-toggler:hover { background: ${dt('treetable.node.toggle.button.selected.hover.background')}; color: ${dt('treetable.node.toggle.button.selected.hover.color')}; } .p-treetable.p-treetable-hoverable-rows .p-treetable-tbody>tr:not(.p-treetable-row-selected):hover { background: ${dt('treetable.row.hover.background')}; color: ${dt('treetable.row.hover.color')}; } .p-treetable.p-treetable-gridlines .p-datatable-header { border-width: 1px 1px 0 1px; } .p-treetable.p-treetable-gridlines .p-treetable-footer { border-width: 0 1px 1px 1px; } .p-treetable.p-treetable-gridlines .p-treetable-top { border-width: 0 1px 0 1px; } .p-treetable.p-treetable-gridlines .p-treetable-bottom { border-width: 0 1px 1px 1px; } .p-treetable.p-treetable-gridlines .p-treetable-thead>tr>th { border-width: 1px; } .p-treetable.p-treetable-gridlines .p-treetable-tbody>tr>td { border-width: 1px; } .p-treetable.p-treetable-gridlines .p-treetable-tfoot>tr>td { border-width: 1px; } .p-treetable.p-treetable-sm .p-treetable-header { padding: 0.65625rem 0.875rem; } .p-treetable.p-treetable-sm .p-treetable-thead>tr>th { padding: 0.375rem 0.5rem; } .p-treetable.p-treetable-sm .p-treetable-tbody>tr>td { padding: 0.375rem 0.5rem; } .p-treetable.p-treetable-sm .p-treetable-tfoot>tr>td { padding: 0.375rem 0.5rem; } .p-treetable.p-treetable-sm .p-treetable-footer { padding: 0.375rem 0.5rem; } .p-treetable.p-treetable-lg .p-treetable-header { padding: 0.9375rem 1.25rem; } .p-treetable.p-treetable-lg .p-treetable-thead>tr>th { padding: 0.9375rem 1.25rem; } .p-treetable.p-treetable-lg .p-treetable-tbody>tr>td { padding: 0.9375rem 1.25rem; } .p-treetable.p-treetable-lg .p-treetable-tfoot>tr>td { padding: 0.9375rem 1.25rem; } .p-treetable.p-treetable-lg .p-treetable-footer { padding: 0.9375rem 1.25rem; } p-treetabletoggler + p-treetablecheckbox .p-checkbox { vertical-align: middle; } p-treetabletoggler + p-treetablecheckbox + span { vertical-align: middle; } `; const classes = { root: ({ instance }) => ({ 'p-treetable p-component': true, 'p-treetable-hoverable': instance.rowHover || instance.selectionMode, 'p-treetable-resizable': instance.resizableColumns, 'p-treetable-resizable-fit': instance.resizableColumns && instance.columnResizeMode === 'fit', 'p-treetable-scrollable': instance.scrollable, 'p-treetable-flex-scrollable': instance.scrollable && instance.scrollHeight === 'flex', 'p-treetable-gridlines': instance.showGridlines, 'p-treetable-sm': instance.size === 'small', 'p-treetable-lg': instance.size === 'large' }), loading: 'p-treetable-loading', //TODO: required? mask: 'p-treetable-mask p-overlay-mask', loadingIcon: 'p-treetable-loading-icon', header: 'p-treetable-header', paginator: ({ instance }) => 'p-treetable-paginator-' + instance.paginatorPosition, tableContainer: 'p-treetable-table-container', table: ({ instance }) => ({ 'p-treetable-table': true, 'p-treetable-scrollable-table': instance.scrollable, 'p-treetable-resizable-table': instance.resizableColumns, 'p-treetable-resizable-table-fit': instance.resizableColumns && instance.columnResizeMode === 'fit' }), thead: 'p-treetable-thead', headerCell: ({ instance }) => ({ 'p-treetable-header-cell': true, 'p-treetable-sortable-column': instance.sortable, 'p-treetable-resizable-column': instance.resizableColumns, 'p-treetable-column-sorted': instance?.sorted, 'p-treetable-frozen-column': instance.columnProp('frozen') }), columnResizer: 'p-treetable-column-resizer', columnHeaderContent: 'p-treetable-column-header-content', columnTitle: 'p-treetable-column-title', sortIcon: 'p-treetable-sort-icon', pcSortBadge: 'p-treetable-sort-badge', tbody: 'p-treetable-tbody', row: ({ instance }) => ({ 'p-treetable-row-selected': instance.selected }), bodyCell: ({ instance }) => ({ 'p-treetable-frozen-column': instance.columnProp('frozen') }), bodyCellContent: ({ instance }) => ({ 'p-treetable-body-cell-content': true, 'p-treetable-body-cell-content-expander': instance.columnProp('expander') }), toggler: 'p-treetable-body-cell-content-expander', nodeToggleButton: 'p-treetable-node-toggle-button', nodeToggleIcon: 'p-treetable-node-toggle-icon', pcNodeCheckbox: 'p-treetable-node-checkbox', emptyMessage: 'p-treetable-empty-message', tfoot: 'p-treetable-tfoot', footerCell: ({ instance }) => ({ 'p-treetable-frozen-column': instance.columnProp('frozen') }), footer: 'p-treetable-footer', columnResizeIndicator: 'p-treetable-column-resize-indicator' }; const inlineStyles = { tableContainer: { overflow: 'auto' }, thead: { position: 'sticky' }, tfoot: { position: 'sticky' } }; class TreeTableStyle extends BaseStyle { name = 'treetable'; theme = theme; classes = classes; inlineStyles = inlineStyles; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: TreeTableStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: TreeTableStyle }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: TreeTableStyle, decorators: [{ type: Injectable }] }); /** * * TreeTable is used to display hierarchical data in tabular format. * * [Live Demo](https://www.primeng.org/treetable/) * * @module treetablestyle * */ var TreeTableClasses; (function (TreeTableClasses) { /** * Class name of the root element */ TreeTableClasses["root"] = "p-treetable"; /** * Class name of the loading element */ TreeTableClasses["loading"] = "p-treetable-loading"; /** * Class name of the mask element */ TreeTableClasses["mask"] = "p-treetable-mask"; /** * Class name of the loading icon element */ TreeTableClasses["loadingIcon"] = "p-treetable-loading-icon"; /** * Class name of the header element */ TreeTableClasses["header"] = "p-treetable-header"; /** * Class name of the paginator element */ TreeTableClasses["paginator"] = "p-treetable-paginator-[position]"; /** * Class name of the table container element */ TreeTableClasses["tableContainer"] = "p-treetable-table-container"; /** * Class name of the table element */ TreeTableClasses["table"] = "p-treetable-table"; /** * Class name of the thead element */ TreeTableClasses["thead"] = "p-treetable-thead"; /** * Class name of the column resizer element */ TreeTableClasses["columnResizer"] = "p-treetable-column-resizer"; /** * Class name of the column title element */ TreeTableClasses["columnTitle"] = "p-treetable-column-title"; /** * Class name of the sort icon element */ TreeTableClasses["sortIcon"] = "p-treetable-sort-icon"; /** * Class name of the sort badge element */ TreeTableClasses["pcSortBadge"] = "p-treetable-sort-badge"; /** * Class name of the tbody element */ TreeTableClasses["tbody"] = "p-treetable-tbody"; /** * Class name of the node toggle button element */ TreeTableClasses["nodeToggleButton"] = "p-treetable-node-toggle-button"; /** * Class name of the node toggle icon element */ TreeTableClasses["nodeToggleIcon"] = "p-treetable-node-toggle-icon"; /** * Class name of the node checkbox element */ TreeTableClasses["pcNodeCheckbox"] = "p-treetable-node-checkbox"; /** * Class name of the empty message element */ TreeTableClasses["emptyMessage"] = "p-treetable-empty-message"; /** * Class name of the tfoot element */ TreeTableClasses["tfoot"] = "p-treetable-tfoot"; /** * Class name of the footer element */ TreeTableClasses["footer"] = "p-treetable-footer"; /** * Class name of the column resize indicator element */ TreeTableClasses["columnResizeIndicator"] = "p-treetable-column-resize-indicator"; })(TreeTableClasses || (TreeTableClasses = {})); class TreeTableService { sortSource = new Subject(); selectionSource = new Subject(); contextMenuSource = new Subject(); uiUpdateSource = new Subject(); totalRecordsSource = new Subject(); sortSource$ = this.sortSource.asObservable(); selectionSource$ = this.selectionSource.asObservable(); contextMenuSource$ = this.contextMenuSource.asObservable(); uiUpdateSource$ = this.uiUpdateSource.asObservable(); totalRecordsSource$ = this.totalRecordsSource.asObservable(); onSort(sortMeta) { this.sortSource.next(sortMeta); } onSelectionChange() { this.selectionSource.next(null); } onContextMenu(node) { this.contextMenuSource.next(node); } onUIUpdate(value) { this.uiUpdateSource.next(value); } onTotalRecordsChange(value) { this.totalRecordsSource.next(value); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: TreeTableService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: TreeTableService }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: TreeTableService, decorators: [{ type: Injectable }] }); /** * TreeTable is used to display hierarchical data in tabular format. * @group Components */ class TreeTable extends BaseComponent { _componentStyle = inject(TreeTableStyle); /** * An array of objects to represent dynamic columns. * @group Props */ columns; /** * Inline style of the component. * @group Props */ style; /** * Style class of the component. * @group Props */ styleClass; /** * Inline style of the table. * @group Props */ tableStyle; /** * Style class of the table. * @group Props */ tableStyleClass; /** * Whether the cell widths scale according to their content or not. * @group Props */ autoLayout; /** * Defines if data is loaded and interacted with in lazy manner. * @group Props */ lazy = false; /** * Whether to call lazy loading on initialization. * @group Props */ lazyLoadOnInit = true; /** * When specified as true, enables the pagination. * @group Props */ paginator; /** * Number of rows to display per page. * @group Props */ rows; /** * Index of the first row to be displayed. * @group Props */ first = 0; /** * Number of page links to display in paginator. * @group Props */ pageLinks = 5; /** * Array of integer/object values to display inside rows per page dropdown of paginator * @group Props */ rowsPerPageOptions; /** * Whether to show it even there is only one page. * @group Props */ alwaysShowPaginator = true; /** * Position of the paginator. * @group Props */ paginatorPosition = 'bottom'; /** * Custom style class for paginator * @group Props */ paginatorStyleClass; /** * Target element to attach the paginator dropdown overlay, valid values are "body" or a local ng-template variable of another element (note: use binding with brackets for template variables, e.g. [appendTo]="mydiv" for a div element having #mydiv as variable name). * @group Props */ paginatorDropdownAppendTo; /** * Template of the current page report element. Available placeholders are {currentPage},{totalPages},{rows},{first},{last} and {totalRecords} * @group Props */ currentPageReportTemplate = '{currentPage} of {totalPages}'; /** * Whether to display current page report. * @group Props */ showCurrentPageReport; /** * Whether to display a dropdown to navigate to any page. * @group Props */ showJumpToPageDropdown; /** * When enabled, icons are displayed on paginator to go first and last page. * @group Props */ showFirstLastIcon = true; /** * Whether to show page links. * @group Props */ showPageLinks = true; /** * Sort order to use when an unsorted column gets sorted by user interaction. * @group Props */ defaultSortOrder = 1; /** * Defines whether sorting works on single column or on multiple columns. * @group Props */ sortMode = 'single'; /** * When true, resets paginator to first page after sorting. * @group Props */ resetPageOnSort = true; /** * Whether to use the default sorting or a custom one using sortFunction. * @group Props */ customSort; /** * Specifies the selection mode, valid values are "single" and "multiple". * @group Props */ selectionMode; /** * Selected row with a context menu. * @group Props */ contextMenuSelection; /** * Mode of the contet menu selection. * @group Props */ contextMenuSelectionMode = 'separate'; /** * A property to uniquely identify a record in data. * @group Props */ dataKey; /** * Defines whether metaKey is should be considered for the selection. On touch enabled devices, metaKeySelection is turned off automatically. * @group Props */ metaKeySelection = false; /** * Algorithm to define if a row is selected, valid values are "equals" that compares by reference and "deepEquals" that compares all fields. * @group Props */ compareSelectionBy = 'deepEquals'; /** * Adds hover effect to rows without the need for selectionMode. * @group Props */ rowHover; /** * Displays a loader to indicate data load is in progress. * @group Props */ loading; /** * The icon to show while indicating data load is in progress. * @group Props */ loadingIcon; /** * Whether to show the loading mask when loading property is true. * @group Props */ showLoader = true; /** * When specified, enables horizontal and/or vertical scrolling. * @group Props */ scrollable; /** * Height of the scroll viewport in fixed pixels or the "flex" keyword for a dynamic size. * @group Props */ scrollHeight; /** * Whether the data should be loaded on demand during scroll. * @group Props */ virtualScroll; /** * Height of a row to use in calculations of virtual scrolling. * @group Props */ virtualScrollItemSize; /** * Whether to use the scroller feature. The properties of scroller component can be used like an object in it. * @group Props */ virtualScrollOptions; /** * The delay (in milliseconds) before triggering the virtual scroll. This determines the time gap between the user's scroll action and the actual rendering of the next set of items in the virtual scroll. * @group Props */ virtualScrollDelay = 150; /** * Width of the frozen columns container. * @group Props */ frozenWidth; /** * An array of objects to represent dynamic columns that are frozen. * @group Props */ frozenColumns; /** * When enabled, columns can be resized using drag and drop. * @group Props */ resizableColumns; /** * Defines whether the overall table width should change on column resize, valid values are "fit" and "expand". * @group Props */ columnResizeMode = 'fit'; /** * When enabled, columns can be reordered using drag and drop. * @group Props */ reorderableColumns; /** * Local ng-template varilable of a ContextMenu. * @group Props */ contextMenu; /** * Function to optimize the dom operations by delegating to ngForTrackBy, default algorithm checks for object identity. * @group Props */ rowTrackBy = (index, item) => item; /** * An array of FilterMetadata objects to provide external filters. * @group Props */ filters = {}; /** * An array of fields as string to use in global filtering. * @group Props */ globalFilterFields; /** * Delay in milliseconds before filtering the data. * @group Props */ filterDelay = 300; /** * Mode for filtering valid values are "lenient" and "strict". Default is lenient. * @group Props */ filterMode = 'lenient'; /** * Locale to use in filtering. The default locale is the host environment's current locale. * @group Props */ filterLocale; /** * Locale to be used in paginator formatting. * @group Props */ paginatorLocale; /** * Number of total records, defaults to length of value when not defined. * @group Props */ get totalRecords() { return this._totalRecords; } set totalRecords(val) { this._totalRecords = val; this.tableService.onTotalRecordsChange(this._totalRecords); } /** * Name of the field to sort data by default. * @group Props */ get sortField() { return this._sortField; } set sortField(val) { this._sortField = val; } /** * Order to sort when default sorting is enabled. * @defaultValue 1 * @group Props */ get sortOrder() { return this._sortOrder; } set sortOrder(val) { this._sortOrder = val; } /** * An array of SortMeta objects to sort the data by default in multiple sort mode. * @defaultValue null * @group Props */ get multiSortMeta() { return this._multiSortMeta; } set multiSortMeta(val) { this._multiSortMeta = val; } /** * Selected row in single mode or an array of values in multiple mode. * @defaultValue null * @group Props */ get selection() { return this._selection; } set selection(val) { this._selection = val; } /** * An array of objects to display. * @defaultValue null * @group Props */ get value() { return this._value; } set value(val) { this._value = val; } /** * Indicates the height of rows to be scrolled. * @defaultValue 28 * @group Props * @deprecated use virtualScrollItemSize property instead. */ get virtualRowHeight() { return this._virtualRowHeight; } set virtualRowHeight(val) { this._virtualRowHeight = val; console.log('The virtualRowHeight property is deprecated, use virtualScrollItemSize property instead.'); } /** * A map of keys to control the selection state. * @group Props */ get selectionKeys() { return this._selectionKeys; } set selectionKeys(value) { this._selectionKeys = value; this.selectionKeysChange.emit(this._selectionKeys); } /** * Whether to show grid lines between cells. * @defaultValue false * @group Props */ showGridlines = false; /** * Callback to invoke on selected node change. * @param {TreeTableNode} object - Node instance. * @group Emits */ selectionChange = new EventEmitter(); /** * Callback to invoke on context menu selection change. * @param {TreeTableNode} object - Node instance. * @group Emits */ contextMenuSelectionChange = new EventEmitter(); /** * Callback to invoke when data is filtered. * @param {TreeTableFilterEvent} event - Custom filter event. * @group Emits */ onFilter = new EventEmitter(); /** * Callback to invoke when a node is expanded. * @param {TreeTableNodeExpandEvent} event - Node expand event. * @group Emits */ onNodeExpand = new EventEmitter(); /** * Callback to invoke when a node is collapsed. * @param {TreeTableNodeCollapseEvent} event - Node collapse event. * @group Emits */ onNodeCollapse = new EventEmitter(); /** * Callback to invoke when pagination occurs. * @param {TreeTablePaginatorState} object - Paginator state. * @group Emits */ onPage = new EventEmitter(); /** * Callback to invoke when a column gets sorted. * @param {Object} Object - Sort data. * @group Emits */ onSort = new EventEmitter(); /** * Callback to invoke when paging, sorting or filtering happens in lazy mode. * @param {TreeTableLazyLoadEvent} event - Custom lazy load event. * @group Emits */ onLazyLoad = new EventEmitter(); /** * An event emitter to invoke on custom sorting, refer to sorting section for details. * @param {TreeTableSortEvent} event - Custom sort event. * @group Emits */ sortFunction = new EventEmitter(); /** * Callback to invoke when a column is resized. * @param {TreeTableColResizeEvent} event - Custom column resize event. * @group Emits */ onColResize = new EventEmitter(); /** * Callback to invoke when a column is reordered. * @param {TreeTableColumnReorderEvent} event - Custom column reorder. * @group Emits */ onColReorder = new EventEmitter(); /** * Callback to invoke when a node is selected. * @param {TreeTableNode} object - Node instance. * @group Emits */ onNodeSelect = new EventEmitter(); /** * Callback to invoke when a node is unselected. * @param {TreeTableNodeUnSelectEvent} event - Custom node unselect event. * @group Emits */ onNodeUnselect = new EventEmitter(); /** * Callback to invoke when a node is selected with right click. * @param {TreeTableContextMenuSelectEvent} event - Custom context menu select event. * @group Emits */ onContextMenuSelect = new EventEmitter(); /** * Callback to invoke when state of header checkbox changes. * @param {TreeTableHeaderCheckboxToggleEvent} event - Custom checkbox toggle event. * @group Emits */ onHeaderCheckboxToggle = new EventEmitter(); /** * Callback to invoke when a cell switches to edit mode. * @param {TreeTableEditEvent} event - Custom edit event. * @group Emits */ onEditInit = new EventEmitter(); /** * Callback to invoke when cell edit is completed. * @param {TreeTableEditEvent} event - Custom edit event. * @group Emits */ onEditComplete = new EventEmitter(); /** * Callback to invoke when cell edit is cancelled with escape key. * @param {TreeTableEditEvent} event - Custom edit event. * @group Emits */ onEditCancel = new EventEmitter(); /** * Callback to invoke when selectionKeys are changed. * @param {Object} object - updated value of the selectionKeys. * @group Emits */ selectionKeysChange = new EventEmitter(); containerViewChild; resizeHelperViewChild; reorderIndicatorUpViewChild; reorderIndicatorDownViewChild; tableViewChild; scrollableViewChild; scrollableFrozenViewChild; _value = []; _virtualRowHeight = 28; _selectionKeys; serializedValue; _totalRecords = 0; _multiSortMeta; _sortField; _sortOrder = 1; filteredNodes; filterTimeout; _colGroupTemplate; colGroupTemplate; _captionTemplate; captionTemplate; _headerTemplate; headerTemplate; _bodyTemplate; bodyTemplate; _footerTemplate; footerTemplate; _summaryTemplate; summaryTemplate; _emptyMessageTemplate; emptyMessageTemplate; _paginatorLeftTemplate; paginatorLeftTemplate; _paginatorRightTemplate; paginatorRightTemplate; _paginatorDropdownItemTemplate; paginatorDropdownItemTemplate; _frozenHeaderTemplate; frozenHeaderTemplate; _frozenBodyTemplate; frozenBodyTemplate; _frozenFooterTemplate; frozenFooterTemplate; _frozenColGroupTemplate; frozenColGroupTemplate; _loadingIconTemplate; loadingIconTemplate; _reorderIndicatorUpIconTemplate; reorderIndicatorUpIconTemplate; _reorderIndicatorDownIconTemplate; reorderIndicatorDownIconTemplate; _sortIconTemplate; sortIconTemplate; _checkboxIconTemplate; checkboxIconTemplate; _headerCheckboxIconTemplate; headerCheckboxIconTemplate; _togglerIconTemplate; togglerIconTemplate; _paginatorFirstPageLinkIconTemplate; paginatorFirstPageLinkIconTemplate; _paginatorLastPageLinkIconTemplate; paginatorLastPageLinkIconTemplate; _paginatorPreviousPageLinkIconTemplate; paginatorPreviousPageLinkIconTemplate; _paginatorNextPageLinkIconTemplate; paginatorNextPageLinkIconTemplate; _loaderTemplate; loaderTemplate; lastResizerHelperX; reorderIconWidth; reorderIconHeight; draggedColumn; dropPosition; preventSelectionSetterPropagation; _selection; selectedKeys = {}; rowTouched; editingCell; editingCellData; editingCellField; editingCellClick; documentEditListener; initialized; toggleRowIndex; ngOnInit() { super.ngOnInit(); if (this.lazy && this.lazyLoadOnInit && !this.virtualScroll) { this.onLazyLoad.emit(this.createLazyLoadMetadata()); } this.initialized = true; } templates; ngAfterContentInit() { this.templates.forEach((item) => { switch (item.getType()) { case 'caption': this.captionTemplate = item.template; break; case 'header': this.headerTemplate = item.template; break; case 'body': this.bodyTemplate = item.template; break; case 'footer': this.footerTemplate = item.template; break; case 'summary': this.summaryTemplate = item.template; break; case 'colgroup': this.colGroupTemplate = item.template; break; case 'emptymessage': this.emptyMessageTemplate = item.template; break; case 'paginatorleft': this.paginatorLeftTemplate = item.template; break; case 'paginatorright': this.paginatorRightTemplate = item.template; break; case 'paginatordropdownitem': this.paginatorDropdownItemTemplate = item.template; break; case 'frozenheader': this.frozenHeaderTemplate = item.template; break; case 'frozenbody': this.frozenBodyTemplate = item.template; break; case 'frozenfooter': this.frozenFooterTemplate = item.template; break; case 'frozencolgroup': this.frozenColGroupTemplate = item.template; break; case 'loadingicon': this.loadingIconTemplate = item.template; break; case 'reorderindicatorupicon': this.reorderIndicatorUpIconTemplate = item.template; break; case 'reorderindicatordownicon': this.reorderIndicatorDownIconTemplate = item.template; break; case 'sorticon': this.sortIconTemplate = item.template; break; case 'checkboxicon': this.checkboxIconTemplate = item.template; break; case 'headercheckboxicon': this.headerCheckboxIconTemplate = item.template; break; case 'togglericon': this.togglerIconTemplate = item.template; break; case 'paginatorfirstpagelinkicon': this.paginatorFirstPageLinkIconTemplate = item.template; break; case 'paginatorlastpagelinkicon': this.paginatorLastPageLinkIconTemplate = item.template; break; case 'paginatorpreviouspagelinkicon': this.paginatorPreviousPageLinkIconTemplate = item.template; break; case 'paginatornextpagelinkicon': this.paginatorNextPageLinkIconTemplate = item.template; break; case 'loader': this.loaderTemplate = item.template; break; } }); } filterService = inject(FilterService); tableService = inject(TreeTableService); zone = inject(NgZone); ngOnChanges(simpleChange) { super.ngOnChanges(simpleChange); if (simpleChange.value) { this._value = simpleChange.value.currentValue; if (!this.lazy) { this.totalRecords = this._value ? this._value.length : 0; if (this.sortMode == 'single' && this.sortField) this.sortSingle(); else if (this.sortMode == 'multiple' && this.multiSortMeta) this.sortMultiple(); else if (this.hasFilter()) //sort already filters this._filter(); } this.updateSerializedValue(); this.tableService.onUIUpdate(this.value); } if (simpleChange.sortField) { this._sortField = simpleChange.sortField.currentValue; //avoid triggering lazy load prior to lazy initialization at onInit if (!this.lazy || this.initialized) { if (this.sortMode === 'single') { this.sortSingle(); } } } if (simpleChange.sortOrder) { this._sortOrder = simpleChange.sortOrder.currentValue; //avoid triggering lazy load prior to lazy initialization at onInit if (!this.lazy || this.initialized) { if (this.sortMode === 'single') { this.sortSingle(); } } } if (simpleChange.multiSortMeta) { this._multiSortMeta = simpleChange.multiSortMeta.currentValue; if (this.sortMode === 'multiple') { this.sortMultiple(); } } if (simpleChange.selection) { this._selection = simpleChange.selection.currentValue; if (!this.preventSelectionSetterPropagation) { this.updateselectedKeys(); this.tableService.onSelectionChange(); } this.preventSelectionSetterPropagation = false; } } updateSerializedValue() { this.serializedValue = []; if (this.paginator) this.serializePageNodes(); else this.serializeNodes(null, this.filteredNodes || this.value, 0, true); } serializeNodes(parent, nodes, level, visible) { if (nodes && nodes.length) { for (let node of nodes) { node.parent = parent; const rowNode = { node: node, parent: parent, level: level, visible: visible && (parent ? parent.expanded : true) }; this.serializedValue.push(rowNode); if (rowNode.visible && node.expanded) { this.serializeNodes(node, node.children, level + 1, rowNode.visible); } } } } serializePageNodes() { let data = this.filteredNodes || this.value; this.serializedValue = []; if (data && data.length) { const first = this.lazy ? 0 : this.first; for (let i = first; i < first + this.rows; i++) { let node = data[i]; if (node) { this.serializedValue.push({ node: node, parent: null, level: 0, visible: true }); this.serializeNodes(node, node.children, 1, true); } } } } updateselectedKeys() { if (this.dataKey && this._selection) { this.selectedKeys = {}; if (Array.isArray(this._selection)) { for (let node of this._selection) { this.selectedKeys[String(resolveFieldData(node.data, this.dataKey))] = 1; } } else { this.selectedKeys[String(resolveFieldData(this._selection.data, this.dataKey))] = 1; } } } onPageChange(event) { this.first = event.first; this.rows = event.rows; if (this.lazy) this.onLazyLoad.emit(this.createLazyLoadMetadata()); else this.serializePageNodes(); this.onPage.emit({ first: this.first, rows: this.rows }); this.tableService.onUIUpdate(this.value); if (this.scrollable) { this.resetScrollTop(); } } sort(event) { let originalEvent = event.originalEvent; if (this.sortMode === 'single') { this._sortOrder = this.sortField === event.field ? this.sortOrder * -1 : this.defaultSortOrder; this._sortField = event.field; this.sortSingle(); if (this.resetPageOnSort && this.scrollable) { this.resetScrollTop(); } } if (this.sortMode === 'multiple') { let metaKey = originalEvent.metaKey || originalEvent.ctrlKey; let sortMeta = this.getSortMeta(event.field); if (sortMeta) { if (!metaKey) { this._multiSortMeta = [{ field: event.field, order: sortMeta.order * -1 }]; if (this.resetPageOnSort && this.scrollable) { this.resetScrollTop(); } } else { sortMeta.order = sortMeta.order * -1; } } else { if (!metaKey || !this.multiSortMeta) { this._multiSortMeta = []; if (this.resetPageOnSort && this.scrollable) { this.resetScrollTop(); } } this.multiSortMeta.push({ field: event.field, order: this.defaultSortOrder }); } this.sortMultiple(); } } sortSingle() { if (this.sortField && this.sortOrder) { if (this.lazy) { this.onLazyLoad.emit(this.createLazyLoadMetadata()); } else if (this.value) { this.sortNodes(this.value); if (this.hasFilter()) { this._filter(); } } let sortMeta = { field: this.sortField, order: this.sortOrder }; this.onSort.emit(sortMeta); this.tableService.onSort(sortMeta); this.updateSerializedValue(); } } sortNodes(nodes) { if (!nodes || nodes.length === 0) { return; } if (this.customSort) { this.sortFunction.emit({ data: nodes, mode: this.sortMode, field: this.sortField, order: this.sortOrder }); } else { nodes.sort((node1, node2) => { let value1 = resolveFieldData(node1.data, this.sortField); let value2 = resolveFieldData(node2.data, this.sortField); let result = null; if (value1 == null && value2 != null) result = -1; else if (value1 != null && value2 == null) result = 1; else if (value1 == null && value2 == null) result = 0; else if (typeof value1 === 'string' && typeof value2 === 'string') result = value1.localeCompare(value2, undefined, { numeric: true }); else result = value1 < value2 ? -1 : value1 > value2 ? 1 : 0; return this.sortOrder * result; }); } for (let node of nodes) { this.sortNodes(node.children); } } sortMultiple() { if (this.multiSortMeta) { if (this.lazy) { this.