Skip to content

Commit

Permalink
Merge pull request #13771 from GaetanRouzies/master
Browse files Browse the repository at this point in the history
Feature : Add virtual scroll on Tree Select Component
  • Loading branch information
cetincakiroglu authored Mar 22, 2024
2 parents b4cb0cf + 82a18b1 commit c943671
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 3 deletions.
22 changes: 20 additions & 2 deletions src/app/components/treeselect/treeselect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -127,7 +127,7 @@ export const TREESELECT_VALUE_ACCESSOR: any = {
</span>
</button>
</div>
<div class="p-treeselect-items-wrapper" [ngStyle]="{ 'max-height': scrollHeight }">
<div class="p-treeselect-items-wrapper" [ngStyle]="{ 'max-height': scrollHeight }" >
<p-tree
#tree
[value]="options"
Expand All @@ -147,6 +147,9 @@ export const TREESELECT_VALUE_ACCESSOR: any = {
[filterPlaceholder]="filterPlaceholder"
[filterLocale]="filterLocale"
[filteredNodes]="filteredNodes"
[virtualScroll]="virtualScroll"
[virtualScrollItemSize]="virtualScrollItemSize"
[virtualScrollOptions]="virtualScrollOptions"
[_templateMap]="templateMap"
>
<ng-container *ngIf="emptyTemplate">
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/app/showcase/doc/treeselect/treeselectdoc.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
54 changes: 54 additions & 0 deletions src/app/showcase/doc/treeselect/virtualscrolldoc.ts
Original file line number Diff line number Diff line change
@@ -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: `
<app-docsectiontext>
<p>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 <i>virtualScroll</i> property to true and defining <i>virtualScrollItemSize</i> to specify the height of an item.</p>
</app-docsectiontext>
<div class="card flex justify-content-center">
<p-treeSelect class="w-full md:w-20rem" containerStyleClass="w-full" [(ngModel)]="selectedNodes" [options]="nodes" display="chip" [metaKeySelection]="false" selectionMode="checkbox" placeholder="Select Item"
[virtualScroll]="true" [virtualScrollItemSize]="46" [virtualScrollOptions]="{ scrollHeight: '200px' }"></p-treeSelect>
</div>
<app-code [code]="code" selector="tree-select-virtual-scroll-demo"></app-code>`
})
export class VirtualScrollDoc {

nodes!: any[];

selectedNodes: any;

constructor(private nodeService: NodeService) {
this.nodeService.getLargeTreeNodes().then((files) => (this.nodes = files));
}

code: Code = {
basic: `<p-treeSelect class="w-full md:w-20rem" containerStyleClass="w-full" [(ngModel)]="selectedNodes" [options]="nodes" display="chip" [metaKeySelection]="false" selectionMode="checkbox" placeholder="Select Item" [virtualScroll]="true" [virtualScrollItemSize]="46" [virtualScrollOptions]="{scrollHeight: '200px'}"></p-treeSelect>`,
html: `
<div class="card flex justify-content-center">
<p-treeSelect class="w-full md:w-20rem" containerStyleClass="w-full" [(ngModel)]="selectedNodes" [options]="nodes" display="chip" [metaKeySelection]="false" selectionMode="checkbox" placeholder="Select Item" [virtualScroll]="true" [virtualScrollItemSize]="46" [virtualScrollOptions]="{scrollHeight: '200px'}"></p-treeSelect>
</div>`,
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'],
};
}
6 changes: 6 additions & 0 deletions src/app/showcase/pages/treeselect/treeselectdemo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -41,6 +42,11 @@ export class TreeSelectDemo {
label: 'Checkbox',
component: CheckboxDoc
},
{
id: 'virtual-scroll-doc',
label: 'Virtual Scroll',
component: VirtualScrollDoc
},
{
id: 'filter',
label: 'Filter',
Expand Down
30 changes: 30 additions & 0 deletions src/app/showcase/service/nodeservice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Injectable } from '@angular/core';
import { TreeNode } from "../../components/api/treenode";

@Injectable()
export class NodeService {
Expand Down Expand Up @@ -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());
}
Expand Down

0 comments on commit c943671

Please sign in to comment.