Skip to content

Commit

Permalink
Merge pull request #15580 from primefaces/issue-15579
Browse files Browse the repository at this point in the history
Fixed #15579 - TreeSelect | Add lazy support
  • Loading branch information
cetincakiroglu authored May 15, 2024
2 parents 9197738 + fff6c1c commit 5b56912
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/app/components/treeselect/treeselect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ export const TREESELECT_VALUE_ACCESSOR: any = {
[virtualScrollItemSize]="virtualScrollItemSize"
[virtualScrollOptions]="virtualScrollOptions"
[_templateMap]="templateMap"
[loading]="loading"
>
<ng-container *ngIf="emptyTemplate">
<ng-template pTemplate="empty">
Expand Down Expand Up @@ -425,6 +426,11 @@ export class TreeSelect implements AfterContentInit {
this._hideTransitionOptions = val;
console.warn('The hideTransitionOptions property is deprecated since v14.2.0, use overlayOptions property instead.');
}
/**
* Displays a loader to indicate data load is in progress.
* @group Props
*/
@Input({ transform: booleanAttribute }) loading: boolean | undefined;
/**
* Callback to invoke when a node is expanded.
* @param {TreeSelectNodeExpandEvent} event - Custom node expand event.
Expand Down
228 changes: 228 additions & 0 deletions src/app/showcase/doc/treeselect/lazydoc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
import { ChangeDetectorRef, Component } from '@angular/core';
import { Code } from '@domain/code';
import { NodeService } from '@service/nodeservice';
import { TreeNode } from 'primeng/api';

@Component({
selector: 'lazy-doc',
template: `
<app-docsectiontext>
<p>Lazy loading is useful when dealing with huge datasets, in this example nodes are dynamically loaded on demand using <i>loading</i> property and <i>onNodeExpand</i> method.</p>
</app-docsectiontext>
<div class="card flex justify-content-center">
<p-treeSelect
class="w-full"
containerStyleClass="w-full"
[(ngModel)]="selectedNodes"
[loading]="loading"
(onNodeExpand)="onNodeExpand($event)"
[options]="nodes"
display="chip"
[metaKeySelection]="false"
selectionMode="checkbox"
placeholder="Select Item"
[loading]="loading"
/>
</div>
<app-code [code]="code" selector="tree-select-basic-demo"></app-code>
`
})
export class LazyDoc {
selectedNodes: TreeNode[] = [];

nodes!: TreeNode[];

loading: boolean = false;

constructor(private cd: ChangeDetectorRef) {}

ngOnInit() {
this.loading = true;

setTimeout(() => {
this.nodes = this.initiateNodes();
this.loading = false;
this.cd.markForCheck();
}, 2000);
}

initiateNodes(): TreeNode[] {
return [
{
key: '0',
label: 'Node 0',
leaf: false
},
{
key: '1',
label: 'Node 1',
leaf: false
},
{
key: '2',
label: 'Node 2',
leaf: false
}
];
}

onNodeExpand(event: any) {
if (!event.node.children) {
this.loading = true;

setTimeout(() => {
let _node = { ...event.node };
_node.children = [];

for (let i = 0; i < 1500; i++) {
_node.children.push({
key: event.node.key + '-' + i,
label: 'Lazy ' + event.node.label + '-' + i
});
}

this.nodes[parseInt(event.node.key, 10)] = _node;

this.loading = false;
this.cd.markForCheck();
}, 500);
}
}

code: Code = {
basic: `<p-treeSelect
class="w-full"
containerStyleClass="w-full"
[(ngModel)]="selectedNodes"
[loading]="loading"
(onNodeExpand)="onNodeExpand($event)"
[options]="nodes"
display="chip"
[metaKeySelection]="false"
selectionMode="checkbox"
placeholder="Select Item"
[loading]="loading"
/>`,

html: `<div class="card flex justify-content-center">
<p-treeSelect
class="w-full"
containerStyleClass="w-full"
[(ngModel)]="selectedNodes"
[loading]="loading"
(onNodeExpand)="onNodeExpand($event)"
[options]="nodes"
display="chip"
[metaKeySelection]="false"
selectionMode="checkbox"
placeholder="Select Item"
[loading]="loading"
/>
</div>`,

typescript: `import { Component } from '@angular/core';
import { NodeService } from '@service/nodeservice';
import { FormsModule } from '@angular/forms';
import { TreeSelectModule } from 'primeng/treeselect';
@Component({
selector: 'tree-select-lazy-demo',
templateUrl: './tree-select-lazy-demo.html',
standalone: true,
imports: [FormsModule, TreeSelectModule]
})
export class TreeSelectLazyDemo {
selectedNodes: TreeNode[] = [];
nodes!: TreeNode[];
loading: boolean = false;
constructor(private cd: ChangeDetectorRef) {}
ngOnInit() {
this.loading = true;
setTimeout(() => {
this.nodes = this.initiateNodes();
this.loading = false;
this.cd.markForCheck();
}, 2000);
}
initiateNodes(): TreeNode[] {
return [
{
key: '0',
label: 'Node 0',
leaf: false
},
{
key: '1',
label: 'Node 1',
leaf: false
},
{
key: '2',
label: 'Node 2',
leaf: false
}
];
}
onNodeExpand(event: any) {
if (!event.node.children) {
this.loading = true;
setTimeout(() => {
let _node = { ...event.node };
_node.children = [];
for (let i = 0; i < 150; i++) {
_node.children.push({
key: event.node.key + '-' + i,
label: 'Lazy ' + event.node.label + '-' + i
});
}
this.nodes[parseInt(event.node.key, 10)] = _node;
this.loading = false;
this.cd.markForCheck();
}, 500);
}
}
}`,

service: ['NodeService'],

data: `
/* NodeService */
{
key: '0',
label: 'Documents',
data: 'Documents Folder',
icon: 'pi pi-fw pi-inbox',
children: [
{
key: '0-0',
label: 'Work',
data: 'Work Folder',
icon: 'pi pi-fw pi-cog',
children: [
{ key: '0-0-0', label: 'Expenses.doc', icon: 'pi pi-fw pi-file', data: 'Expenses Document' },
{ key: '0-0-1', label: 'Resume.doc', icon: 'pi pi-fw pi-file', data: 'Resume Document' }
]
},
{
key: '0-1',
label: 'Home',
data: 'Home Folder',
icon: 'pi pi-fw pi-home',
children: [{ key: '0-1-0', label: 'Invoices.txt', icon: 'pi pi-fw pi-file', data: 'Invoices for this month' }]
}
]
},
...`
};
}
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 @@ -19,10 +19,11 @@ import { StyleDoc } from './styledoc';
import { VirtualScrollDoc } from './virtualscrolldoc';
import { FloatLabelModule } from 'primeng/floatlabel';
import { FilledDoc } from './filleddoc';
import { LazyDoc } from './lazydoc';

@NgModule({
imports: [CommonModule, AppCodeModule, AppDocModule, TreeSelectModule, FormsModule, ReactiveFormsModule, RouterModule, FloatLabelModule],
exports: [AppDocModule],
declarations: [ImportDoc, BasicDoc, MultipleDoc, CheckboxDoc, VirtualScrollDoc, FilterDoc, FloatLabelDoc, InvalidDoc, DisabledDoc, StyleDoc, AccessibilityDoc, ReactiveFormsDoc, FilledDoc]
declarations: [ImportDoc, BasicDoc, MultipleDoc, CheckboxDoc, LazyDoc, VirtualScrollDoc, FilterDoc, FloatLabelDoc, InvalidDoc, DisabledDoc, StyleDoc, AccessibilityDoc, ReactiveFormsDoc, FilledDoc]
})
export class TreeSelectDocModule {}
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 @@ -12,6 +12,7 @@ import { MultipleDoc } from '@doc/treeselect/multipledoc';
import { StyleDoc } from '@doc/treeselect/styledoc';
import { VirtualScrollDoc } from '@doc/treeselect/virtualscrolldoc';
import { FilledDoc } from '@doc/treeselect/filleddoc';
import { LazyDoc } from '@doc/treeselect/lazydoc';

@Component({
templateUrl: './treeselectdemo.html'
Expand Down Expand Up @@ -48,6 +49,11 @@ export class TreeSelectDemo {
label: 'Virtual Scroll',
component: VirtualScrollDoc
},
{
id: 'lazy',
label: 'Lazy',
component: LazyDoc
},
{
id: 'filter',
label: 'Filter',
Expand Down

0 comments on commit 5b56912

Please sign in to comment.