diff --git a/src/app/components/treeselect/treeselect.ts b/src/app/components/treeselect/treeselect.ts index 2dce1e1a8ba..02a74dc93d9 100755 --- a/src/app/components/treeselect/treeselect.ts +++ b/src/app/components/treeselect/treeselect.ts @@ -2,7 +2,7 @@ import { AnimationEvent } from '@angular/animations'; import { CommonModule } from '@angular/common'; import { AfterContentInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, forwardRef, Input, NgModule, Output, QueryList, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; -import { OverlayOptions, OverlayService, PrimeNGConfig, PrimeTemplate, SharedModule, TreeNode } from 'primeng/api'; +import { OverlayOptions, OverlayService, PrimeNGConfig, PrimeTemplate, ScrollerOptions, SharedModule, TreeNode } from 'primeng/api'; import { DomHandler } from 'primeng/dom'; import { ChevronDownIcon } from 'primeng/icons/chevrondown'; import { SearchIcon } from 'primeng/icons/search'; @@ -127,7 +127,7 @@ export const TREESELECT_VALUE_ACCESSOR: any = { -
+
@@ -343,6 +346,21 @@ export class TreeSelect implements AfterContentInit { * @group Props */ @Input() resetFilterOnHide: boolean = true; + /** + * Whether the data should be loaded on demand during scroll. + * @group Props + */ + @Input() virtualScroll: boolean | undefined; + /** + * Height of an item in the list for VirtualScrolling. + * @group Props + */ + @Input() virtualScrollItemSize: number | undefined; + /** + * Whether to use the scroller feature. The properties of scroller component can be used like an object in it. + * @group Props + */ + @Input() virtualScrollOptions: ScrollerOptions | undefined; /** * An array of treenodes. * @defaultValue undefined diff --git a/src/app/showcase/doc/treeselect/treeselectdoc.module.ts b/src/app/showcase/doc/treeselect/treeselectdoc.module.ts index 04a5c62d26f..bccbc3e1cc9 100644 --- a/src/app/showcase/doc/treeselect/treeselectdoc.module.ts +++ b/src/app/showcase/doc/treeselect/treeselectdoc.module.ts @@ -16,10 +16,11 @@ import { InvalidDoc } from './invaliddoc'; import { MultipleDoc } from './multipledoc'; import { ReactiveFormsDoc } from './reactiveformsdoc'; import { StyleDoc } from './styledoc'; +import { VirtualScrollDoc } from './virtualscrolldoc'; @NgModule({ imports: [CommonModule, AppCodeModule, AppDocModule, TreeSelectModule, FormsModule, ReactiveFormsModule, RouterModule], exports: [AppDocModule], - declarations: [ImportDoc, BasicDoc, MultipleDoc, CheckboxDoc, FilterDoc, FloatLabelDoc, InvalidDoc, DisabledDoc, StyleDoc, AccessibilityDoc, ReactiveFormsDoc] + declarations: [ImportDoc, BasicDoc, MultipleDoc, CheckboxDoc, VirtualScrollDoc, FilterDoc, FloatLabelDoc, InvalidDoc, DisabledDoc, StyleDoc, AccessibilityDoc, ReactiveFormsDoc] }) export class TreeSelectDocModule {} diff --git a/src/app/showcase/doc/treeselect/virtualscrolldoc.ts b/src/app/showcase/doc/treeselect/virtualscrolldoc.ts new file mode 100644 index 00000000000..81d617a48c9 --- /dev/null +++ b/src/app/showcase/doc/treeselect/virtualscrolldoc.ts @@ -0,0 +1,54 @@ +import { Component, Input } from '@angular/core'; +import { Code } from '../../domain/code'; +import { NodeService } from '../../service/nodeservice'; + +@Component({ + selector: 'virtual-scroll-doc', + template: ` + +

VirtualScrolling is an efficient way of rendering the options by displaying a small subset of data in the viewport at any time. When dealing with huge number of options, it is suggested to enable VirtualScrolling to avoid performance + issues. Usage is simple as setting virtualScroll property to true and defining virtualScrollItemSize to specify the height of an item.

+
+
+ +
+ ` +}) +export class VirtualScrollDoc { + + nodes!: any[]; + + selectedNodes: any; + + constructor(private nodeService: NodeService) { + this.nodeService.getLargeTreeNodes().then((files) => (this.nodes = files)); + } + + code: Code = { + basic: ``, + html: ` +
+ +
`, + typescript: ` +import { Component } from '@angular/core'; +import { NodeService } from '../../service/nodeservice'; + +@Component({ + selector: 'tree-select-virtual-scroll-demo', + templateUrl: './tree-select-virtual-scroll-demo.html' +}) +export class TreeSelectVirtualScrollDemo { + nodes!: any[]; + + selectedNodes: any; + + constructor(private nodeService: NodeService) { + this.nodeService.getLargeTreeNodes().then((files) => (this.nodes = files)); + } +}`, + + service: ['NodeService'], + }; +} diff --git a/src/app/showcase/pages/treeselect/treeselectdemo.ts b/src/app/showcase/pages/treeselect/treeselectdemo.ts index d55f0958cac..ce3d7a9ede4 100644 --- a/src/app/showcase/pages/treeselect/treeselectdemo.ts +++ b/src/app/showcase/pages/treeselect/treeselectdemo.ts @@ -10,6 +10,7 @@ import { ImportDoc } from '../../doc/treeselect/importdoc'; import { InvalidDoc } from '../../doc/treeselect/invaliddoc'; import { MultipleDoc } from '../../doc/treeselect/multipledoc'; import { StyleDoc } from '../../doc/treeselect/styledoc'; +import { VirtualScrollDoc } from '../../doc/treeselect/virtualscrolldoc'; @Component({ templateUrl: './treeselectdemo.html' @@ -41,6 +42,11 @@ export class TreeSelectDemo { label: 'Checkbox', component: CheckboxDoc }, + { + id: 'virtual-scroll-doc', + label: 'Virtual Scroll', + component: VirtualScrollDoc + }, { id: 'filter', label: 'Filter', diff --git a/src/app/showcase/service/nodeservice.ts b/src/app/showcase/service/nodeservice.ts index 8f306a1d432..35f390d08f2 100755 --- a/src/app/showcase/service/nodeservice.ts +++ b/src/app/showcase/service/nodeservice.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { TreeNode } from "../../components/api/treenode"; @Injectable() export class NodeService { @@ -763,6 +764,35 @@ export class NodeService { ]; } + getDynamicTreeNodes(parentCount: number, childrenCount: number): TreeNode[] { + const nodes: TreeNode[] = []; + + for (let parentIndex = 0; parentIndex < parentCount; parentIndex++) { + const children: TreeNode[] = []; + + for (let childIndex = 0; childIndex < childrenCount; childIndex++) { + children.push({ + key: `${parentIndex}-${childIndex}`, + label: `Child ${parentIndex}-${childIndex}`, + selectable: true, + }); + } + + nodes.push({ + key: parentIndex.toString(), + label: `Parent ${parentIndex}`, + selectable: true, + children: children, + }); + } + + return nodes; + } + + getLargeTreeNodes() { + return Promise.resolve(this.getDynamicTreeNodes(10, 100)); + } + getTreeTableNodes() { return Promise.resolve(this.getTreeTableNodesData()); }