0
# Data Display
1
2
PrimeNG provides 11 powerful components for displaying and organizing data, from simple lists to complex interactive tables and visualizations.
3
4
## Table Components
5
6
### Table
7
8
Advanced data table with sorting, filtering, pagination, and selection.
9
10
```typescript { .api }
11
// Import
12
import { Table } from 'primeng/table';
13
// Module: TableModule
14
15
// Component Interface
16
interface TableProps {
17
value?: any[];
18
columns?: any[];
19
paginator?: boolean;
20
rows?: number;
21
first?: number;
22
pageLinks?: number;
23
rowsPerPageOptions?: number[];
24
alwaysShowPaginator?: boolean;
25
paginatorPosition?: 'top' | 'bottom' | 'both';
26
paginatorDropdownAppendTo?: any;
27
currentPageReportTemplate?: string;
28
showCurrentPageReport?: boolean;
29
showJumpToPageDropdown?: boolean;
30
showFirstLastIcon?: boolean;
31
showPageLinks?: boolean;
32
defaultSortOrder?: number;
33
sortMode?: 'single' | 'multiple';
34
sortField?: string;
35
sortOrder?: number;
36
multiSortMeta?: SortMeta[];
37
selection?: any;
38
selectionMode?: 'single' | 'multiple';
39
compareSelectionBy?: string;
40
dataKey?: string;
41
metaKeySelection?: boolean;
42
rowTrackBy?: Function;
43
lazy?: boolean;
44
lazyLoadOnInit?: boolean;
45
csvSeparator?: string;
46
exportFilename?: string;
47
filters?: { [key: string]: FilterMetadata };
48
globalFilterFields?: string[];
49
filterDelay?: number;
50
filterLocale?: string;
51
expandedRowKeys?: { [key: string]: boolean };
52
editMode?: 'cell' | 'row';
53
editingRowKeys?: { [key: string]: boolean };
54
rowGroupMode?: 'subheader' | 'rowspan';
55
groupRowsBy?: string;
56
expandableRowGroups?: boolean;
57
expandedRowGroups?: any[];
58
scrollable?: boolean;
59
scrollDirection?: string;
60
scrollHeight?: string;
61
virtualScroll?: boolean;
62
virtualScrollItemSize?: number;
63
virtualScrollOptions?: ScrollerOptions;
64
frozenColumns?: any[];
65
frozenValue?: any[];
66
resizableColumns?: boolean;
67
columnResizeMode?: string;
68
reorderableColumns?: boolean;
69
loading?: boolean;
70
loadingIcon?: string;
71
rowHover?: boolean;
72
customSort?: boolean;
73
showLoader?: boolean;
74
responsiveLayout?: string;
75
breakpoint?: string;
76
tableStyle?: any;
77
tableStyleClass?: string;
78
rowClass?: string;
79
rowStyle?: any;
80
rowData?: any;
81
rowIndex?: number;
82
}
83
84
// Events
85
interface TableRowSelectEvent {
86
originalEvent: Event;
87
data: any;
88
type: 'row' | 'radiobutton' | 'checkbox';
89
index: number;
90
}
91
92
interface TableRowUnSelectEvent {
93
originalEvent: Event;
94
data: any;
95
type: 'row' | 'radiobutton' | 'checkbox';
96
index: number;
97
}
98
99
interface TableSelectAllChangeEvent {
100
originalEvent: Event;
101
checked: boolean;
102
}
103
104
interface TableRowEditInitEvent {
105
originalEvent: Event;
106
data: any;
107
field: string;
108
index: number;
109
}
110
111
interface TableRowEditSaveEvent {
112
originalEvent: Event;
113
data: any;
114
field: string;
115
index: number;
116
}
117
118
interface TableRowEditCancelEvent {
119
originalEvent: Event;
120
data: any;
121
field: string;
122
index: number;
123
}
124
125
interface TableSortEvent {
126
originalEvent: Event;
127
data?: any[];
128
mode?: string;
129
field?: string;
130
order?: number;
131
multiSortMeta?: SortMeta[];
132
}
133
134
interface TableFilterEvent {
135
originalEvent: Event;
136
filters: { [key: string]: FilterMetadata };
137
filteredValue?: any[];
138
}
139
140
interface TablePageEvent {
141
originalEvent: Event;
142
first: number;
143
rows: number;
144
page: number;
145
pageCount: number;
146
}
147
148
// Usage Example
149
@Component({
150
template: `
151
<p-table
152
[value]="products"
153
[paginator]="true"
154
[rows]="10"
155
[showCurrentPageReport]="true"
156
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
157
[rowsPerPageOptions]="[10,25,50]"
158
dataKey="id"
159
[rowHover]="true"
160
[loading]="loading"
161
[globalFilterFields]="['name','country.name','representative.name','status']"
162
(onRowSelect)="onRowSelect($event)"
163
(onRowUnselect)="onRowUnselect($event)">
164
165
<ng-template pTemplate="caption">
166
<div class="flex">
167
<button pButton label="Clear" class="p-button-outlined" icon="pi pi-filter-slash" (click)="clear(table)"></button>
168
<span class="p-input-icon-left ml-auto">
169
<i class="pi pi-search"></i>
170
<input pInputText type="text" (input)="table.filterGlobal($event.target.value, 'contains')" placeholder="Search keyword" />
171
</span>
172
</div>
173
</ng-template>
174
175
<ng-template pTemplate="header">
176
<tr>
177
<th style="width: 3rem">
178
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
179
</th>
180
<th pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th>
181
<th pSortableColumn="country.name">Country <p-sortIcon field="country.name"></p-sortIcon></th>
182
<th pSortableColumn="representative.name">Agent <p-sortIcon field="representative.name"></p-sortIcon></th>
183
<th pSortableColumn="status">Status <p-sortIcon field="status"></p-sortIcon></th>
184
<th pSortableColumn="activity">Activity <p-sortIcon field="activity"></p-sortIcon></th>
185
</tr>
186
</ng-template>
187
188
<ng-template pTemplate="body" let-product let-rowIndex="rowIndex">
189
<tr [pSelectableRow]="product" [pSelectableRowIndex]="rowIndex">
190
<td>
191
<p-tableCheckbox [value]="product"></p-tableCheckbox>
192
</td>
193
<td>{{product.name}}</td>
194
<td>
195
<img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + product.country.code" style="width: 20px">
196
<span class="ml-1 vertical-align-middle">{{product.country.name}}</span>
197
</td>
198
<td>
199
<img [alt]="product.representative.name" src="assets/showcase/images/demo/avatar/{{product.representative.image}}" width="32" style="vertical-align: middle" />
200
<span class="ml-1 vertical-align-middle">{{product.representative.name}}</span>
201
</td>
202
<td>
203
<span [class]="'customer-badge status-' + product.status">{{product.status}}</span>
204
</td>
205
<td>
206
<p-progressbar [value]="product.activity" [showValue]="false"></p-progressbar>
207
</td>
208
</tr>
209
</ng-template>
210
</p-table>
211
`
212
})
213
export class TableComponent {
214
products: Product[] = [];
215
selectedProducts: Product[] = [];
216
loading: boolean = false;
217
218
onRowSelect(event: TableRowSelectEvent) {
219
// Handle row selection
220
}
221
}
222
```
223
224
### TreeTable
225
226
Hierarchical data table with tree structure.
227
228
```typescript { .api }
229
// Import
230
import { TreeTable } from 'primeng/treetable';
231
// Module: TreeTableModule
232
233
// Component Interface
234
interface TreeTableProps {
235
value?: TreeNode[];
236
columns?: any[];
237
selection?: any;
238
selectionMode?: 'single' | 'multiple' | 'checkbox';
239
dataKey?: string;
240
compareSelectionBy?: string;
241
metaKeySelection?: boolean;
242
rows?: number;
243
first?: number;
244
paginator?: boolean;
245
pageLinks?: number;
246
rowsPerPageOptions?: number[];
247
alwaysShowPaginator?: boolean;
248
paginatorPosition?: 'top' | 'bottom' | 'both';
249
sortMode?: 'single' | 'multiple';
250
sortField?: string;
251
sortOrder?: number;
252
multiSortMeta?: SortMeta[];
253
customSort?: boolean;
254
scrollable?: boolean;
255
scrollDirection?: string;
256
scrollHeight?: string;
257
frozenWidth?: string;
258
frozenColumns?: any[];
259
resizableColumns?: boolean;
260
columnResizeMode?: string;
261
reorderableColumns?: boolean;
262
loading?: boolean;
263
loadingIcon?: string;
264
rowHover?: boolean;
265
trackBy?: Function;
266
filters?: { [key: string]: FilterMetadata };
267
globalFilterFields?: string[];
268
filterDelay?: number;
269
filterMode?: string;
270
filterLocale?: string;
271
tableStyle?: any;
272
tableStyleClass?: string;
273
}
274
275
// Usage
276
@Component({
277
template: `
278
<p-treetable [value]="files" [columns]="cols" selectionMode="checkbox" [(selection)]="selectedFiles">
279
<ng-template pTemplate="header" let-columns>
280
<tr>
281
<th *ngFor="let col of columns">
282
{{col.header}}
283
</th>
284
</tr>
285
</ng-template>
286
<ng-template pTemplate="body" let-rowNode let-rowData="rowData" let-columns="columns">
287
<tr [ttSelectableRow]="rowNode">
288
<td *ngFor="let col of columns; let i = index">
289
<p-treeTableToggler [rowNode]="rowNode" *ngIf="i == 0"></p-treeTableToggler>
290
<p-treeTableCheckbox [value]="rowNode" *ngIf="i == 0"></p-treeTableCheckbox>
291
{{rowData[col.field]}}
292
</td>
293
</tr>
294
</ng-template>
295
</p-treetable>
296
`
297
})
298
```
299
300
## List and Grid Components
301
302
### DataView
303
304
Flexible data presentation with list and grid layouts.
305
306
```typescript { .api }
307
// Import
308
import { DataView } from 'primeng/dataview';
309
// Module: DataViewModule
310
311
// Component Interface
312
interface DataViewProps {
313
value?: any[];
314
layout?: 'list' | 'grid';
315
paginator?: boolean;
316
rows?: number;
317
first?: number;
318
totalRecords?: number;
319
pageLinks?: number;
320
rowsPerPageOptions?: number[];
321
paginatorPosition?: 'top' | 'bottom' | 'both';
322
alwaysShowPaginator?: boolean;
323
paginatorDropdownAppendTo?: any;
324
currentPageReportTemplate?: string;
325
showCurrentPageReport?: boolean;
326
showJumpToPageDropdown?: boolean;
327
showFirstLastIcon?: boolean;
328
showPageLinks?: boolean;
329
lazy?: boolean;
330
emptyMessage?: string;
331
trackBy?: Function;
332
filterBy?: string;
333
filterLocale?: string;
334
loading?: boolean;
335
loadingIcon?: string;
336
sortField?: string;
337
sortOrder?: number;
338
}
339
340
// Usage
341
@Component({
342
template: `
343
<p-dataview
344
[value]="products"
345
[paginator]="true"
346
[rows]="9"
347
filterBy="name"
348
[sortField]="sortField"
349
[sortOrder]="sortOrder"
350
layout="grid">
351
352
<ng-template pTemplate="header">
353
<div class="flex flex-column md:flex-row md:justify-content-between">
354
<span class="p-input-icon-left mb-2 md:mb-0">
355
<i class="pi pi-search"></i>
356
<input type="search" pInputText placeholder="Search by Name" (input)="filter($event)" />
357
</span>
358
<p-dataviewlayoutoptions></p-dataviewlayoutoptions>
359
</div>
360
</ng-template>
361
362
<ng-template let-product pTemplate="listItem">
363
<div class="col-12">
364
<div class="flex flex-column xl:flex-row xl:align-items-start p-4 gap-4">
365
<img class="w-9 sm:w-16rem xl:w-10rem shadow-2 block xl:block mx-auto border-round" [src]="'assets/showcase/images/demo/product/' + product.image" [alt]="product.name" />
366
<div class="flex flex-column sm:flex-row justify-content-between align-items-center xl:align-items-start flex-1 gap-4">
367
<div class="flex flex-column align-items-center sm:align-items-start gap-3">
368
<div class="text-2xl font-bold text-900">{{product.name}}</div>
369
<p-rating [ngModel]="product.rating" [readonly]="true" [cancel]="false"></p-rating>
370
<div class="flex align-items-center gap-3">
371
<span class="flex align-items-center gap-2">
372
<i class="pi pi-tag"></i>
373
<span class="font-semibold">{{product.category}}</span>
374
</span>
375
<p-tag [value]="product.inventoryStatus" [severity]="getSeverity(product)"></p-tag>
376
</div>
377
</div>
378
<div class="flex sm:flex-column align-items-center sm:align-items-end gap-3 sm:gap-2">
379
<span class="text-2xl font-semibold">${{product.price}}</span>
380
<button pButton pRipple [disabled]="product.inventoryStatus === 'OUTOFSTOCK'" class="p-button-rounded" icon="pi pi-shopping-cart"></button>
381
</div>
382
</div>
383
</div>
384
</div>
385
</ng-template>
386
387
<ng-template let-product pTemplate="gridItem">
388
<div class="col-12 sm:col-6 lg:col-12 xl:col-4 p-2">
389
<div class="p-4 border-1 surface-border surface-card border-round">
390
<div class="flex flex-wrap align-items-center justify-content-between gap-2">
391
<div class="flex align-items-center gap-2">
392
<i class="pi pi-tag"></i>
393
<span class="font-semibold">{{product.category}}</span>
394
</div>
395
<p-tag [value]="product.inventoryStatus" [severity]="getSeverity(product)"></p-tag>
396
</div>
397
<div class="flex flex-column align-items-center gap-3 py-5">
398
<img class="w-9 shadow-2 border-round" [src]="'assets/showcase/images/demo/product/' + product.image" [alt]="product.name" />
399
<div class="text-2xl font-bold">{{product.name}}</div>
400
<p-rating [ngModel]="product.rating" [readonly]="true" [cancel]="false"></p-rating>
401
</div>
402
<div class="flex align-items-center justify-content-between">
403
<span class="text-2xl font-semibold">${{product.price}}</span>
404
<button pButton pRipple [disabled]="product.inventoryStatus === 'OUTOFSTOCK'" class="p-button-rounded" icon="pi pi-shopping-cart"></button>
405
</div>
406
</div>
407
</div>
408
</ng-template>
409
</p-dataview>
410
`
411
})
412
```
413
414
### Tree
415
416
Hierarchical tree structure display.
417
418
```typescript { .api }
419
// Import
420
import { Tree } from 'primeng/tree';
421
// Module: TreeModule
422
423
// Component Interface
424
interface TreeProps {
425
value?: TreeNode[];
426
selectionMode?: 'single' | 'multiple' | 'checkbox';
427
selection?: any;
428
loading?: boolean;
429
loadingIcon?: string;
430
emptyMessage?: string;
431
ariaLabel?: string;
432
togglerAriaLabel?: string;
433
ariaLabelledBy?: string;
434
validateDrop?: boolean;
435
filter?: boolean;
436
filterBy?: string;
437
filterMode?: string;
438
filterPlaceholder?: string;
439
filteredNodes?: TreeNode[];
440
filterLocale?: string;
441
scrollHeight?: string;
442
virtualScroll?: boolean;
443
virtualNodeHeight?: number;
444
minBufferPx?: number;
445
maxBufferPx?: number;
446
indentation?: number;
447
layout?: string;
448
draggableScope?: any;
449
droppableScope?: any;
450
draggableNodes?: boolean;
451
droppableNodes?: boolean;
452
metaKeySelection?: boolean;
453
propagateSelectionUp?: boolean;
454
propagateSelectionDown?: boolean;
455
trackBy?: Function;
456
}
457
458
// Events
459
interface TreeNodeSelectEvent {
460
originalEvent: Event;
461
node: TreeNode;
462
}
463
464
interface TreeNodeUnSelectEvent {
465
originalEvent: Event;
466
node: TreeNode;
467
}
468
469
interface TreeNodeExpandEvent {
470
originalEvent: Event;
471
node: TreeNode;
472
}
473
474
interface TreeNodeCollapseEvent {
475
originalEvent: Event;
476
node: TreeNode;
477
}
478
479
interface TreeNodeDropEvent {
480
originalEvent: Event;
481
node: TreeNode;
482
subNodes: TreeNode[];
483
index: number;
484
scope: any;
485
}
486
487
// Usage
488
@Component({
489
template: `
490
<p-tree
491
[value]="files"
492
selectionMode="multiple"
493
[(selection)]="selectedFiles"
494
[filter]="true"
495
filterPlaceholder="Search files"
496
(onNodeSelect)="onNodeSelect($event)"
497
(onNodeUnselect)="onNodeUnselect($event)">
498
<ng-template let-node pTemplate="default">
499
<span>{{node.label}}</span>
500
</ng-template>
501
</p-tree>
502
`
503
})
504
```
505
506
## Media Components
507
508
### Galleria
509
510
Image gallery with thumbnails and navigation.
511
512
```typescript { .api }
513
// Import
514
import { Galleria } from 'primeng/galleria';
515
// Module: GalleriaModule
516
517
// Component Interface
518
interface GalleriaProps {
519
value?: any[];
520
activeIndex?: number;
521
fullScreen?: boolean;
522
id?: string;
523
item?: any;
524
circular?: boolean;
525
showItemNavigators?: boolean;
526
showIndicators?: boolean;
527
slideShowActive?: boolean;
528
changeItemOnIndicatorHover?: boolean;
529
autoPlay?: boolean;
530
transitionInterval?: number;
531
showThumbnails?: boolean;
532
thumbnailsPosition?: string;
533
verticalThumbnailViewPortHeight?: number;
534
showItemNavigatorsOnHover?: boolean;
535
showIndicatorsOnItem?: boolean;
536
indicatorsPosition?: string;
537
baseZIndex?: number;
538
maskClass?: string;
539
containerClass?: string;
540
containerStyle?: any;
541
showTransitionOptions?: string;
542
hideTransitionOptions?: string;
543
}
544
545
// Usage
546
@Component({
547
template: `
548
<p-galleria
549
[(value)]="images"
550
[responsiveOptions]="responsiveOptions"
551
[containerStyle]="{'max-width': '640px'}"
552
[numVisible]="5"
553
[circular]="true"
554
[fullScreen]="true"
555
[showItemNavigators]="true"
556
[showThumbnails]="false">
557
<ng-template pTemplate="item" let-item>
558
<img [src]="item.previewImageSrc" [alt]="item.alt" style="width: 100%; display: block;" />
559
</ng-template>
560
<ng-template pTemplate="thumbnail" let-item>
561
<div class="grid grid-nogutter justify-content-center">
562
<img [src]="item.thumbnailImageSrc" [alt]="item.alt" style="display: block;" />
563
</div>
564
</ng-template>
565
</p-galleria>
566
`
567
})
568
```
569
570
### Carousel
571
572
Content carousel with navigation and indicators.
573
574
```typescript { .api }
575
// Import
576
import { Carousel } from 'primeng/carousel';
577
// Module: CarouselModule
578
579
// Component Interface
580
interface CarouselProps {
581
value?: any[];
582
page?: number;
583
numVisible?: number;
584
numScroll?: number;
585
responsiveOptions?: CarouselResponsiveOption[];
586
orientation?: 'horizontal' | 'vertical';
587
verticalViewPortHeight?: string;
588
contentClass?: string;
589
indicatorsContentClass?: string;
590
circular?: boolean;
591
showIndicators?: boolean;
592
showNavigators?: boolean;
593
autoplayInterval?: number;
594
}
595
596
interface CarouselResponsiveOption {
597
breakpoint: string;
598
numVisible: number;
599
numScroll: number;
600
}
601
602
// Usage
603
@Component({
604
template: `
605
<p-carousel
606
[value]="products"
607
[numVisible]="3"
608
[numScroll]="1"
609
[circular]="true"
610
[autoplayInterval]="3000"
611
[responsiveOptions]="responsiveOptions">
612
<ng-template pTemplate="item" let-product>
613
<div class="border-1 surface-border border-round m-2 text-center py-5 px-3">
614
<div class="mb-3">
615
<img src="assets/showcase/images/demo/product/{{product.image}}" [alt]="product.name" class="w-6 shadow-2" />
616
</div>
617
<div>
618
<h4 class="mb-1">{{product.name}}</h4>
619
<h6 class="mt-0 mb-3">${{product.price}}</h6>
620
<p-tag [value]="product.inventoryStatus" [severity]="getSeverity(product)"></p-tag>
621
<div class="mt-5 flex flex-wrap gap-2 justify-content-center">
622
<button pButton type="button" class="p-button-rounded" icon="pi pi-search"></button>
623
<button pButton type="button" class="p-button-rounded p-button-success" icon="pi pi-star-fill"></button>
624
</div>
625
</div>
626
</div>
627
</ng-template>
628
</p-carousel>
629
`
630
})
631
```
632
633
### Image
634
635
Enhanced image display with preview and zoom.
636
637
```typescript { .api }
638
// Import
639
import { Image } from 'primeng/image';
640
// Module: ImageModule
641
642
// Component Interface
643
interface ImageProps {
644
imageClass?: string;
645
imageStyle?: any;
646
src?: string;
647
alt?: string;
648
width?: string;
649
height?: string;
650
appendTo?: any;
651
preview?: boolean;
652
showTransitionOptions?: string;
653
hideTransitionOptions?: string;
654
closeOnEscape?: boolean;
655
}
656
657
// Usage
658
@Component({
659
template: `
660
<p-image
661
src="assets/showcase/images/demo/galleria/galleria1.jpg"
662
alt="Image"
663
width="250"
664
[preview]="true">
665
</p-image>
666
`
667
})
668
```
669
670
## Visualization Components
671
672
### Timeline
673
674
Chronological event display with custom templates.
675
676
```typescript { .api }
677
// Import
678
import { Timeline } from 'primeng/timeline';
679
// Module: TimelineModule
680
681
// Component Interface
682
interface TimelineProps {
683
value?: any[];
684
layout?: 'vertical' | 'horizontal';
685
align?: 'left' | 'right' | 'alternate' | 'top' | 'bottom';
686
styleClass?: string;
687
style?: any;
688
}
689
690
// Usage
691
@Component({
692
template: `
693
<p-timeline
694
[value]="events"
695
align="alternate"
696
styleClass="customized-timeline">
697
<ng-template pTemplate="marker" let-event>
698
<span class="custom-marker shadow-2" [style.backgroundColor]="event.color">
699
<i [ngClass]="event.icon"></i>
700
</span>
701
</ng-template>
702
<ng-template pTemplate="content" let-event>
703
<p-card [header]="event.status" [subheader]="event.date">
704
<img *ngIf="event.image" [src]="'assets/showcase/images/demo/product/' + event.image" [alt]="event.name" width="200" class="shadow-2" />
705
<p>{{event.description}}</p>
706
<button pButton pRipple label="Read more" class="p-button-text"></button>
707
</p-card>
708
</ng-template>
709
</p-timeline>
710
`
711
})
712
```
713
714
### OrganizationChart
715
716
Hierarchical organization structure display.
717
718
```typescript { .api }
719
// Import
720
import { OrganizationChart } from 'primeng/organizationchart';
721
// Module: OrganizationChartModule
722
723
// Component Interface
724
interface OrganizationChartProps {
725
value?: TreeNode[];
726
style?: any;
727
styleClass?: string;
728
selectionMode?: 'single' | 'multiple';
729
selection?: any;
730
preserveSpace?: boolean;
731
}
732
733
// Usage
734
@Component({
735
template: `
736
<p-organizationchart
737
[value]="data"
738
selectionMode="single"
739
[(selection)]="selectedNode">
740
<ng-template let-node pTemplate="person">
741
<div class="node-header ui-corner-top">{{node.label}}</div>
742
<div class="node-content">
743
<img src="assets/showcase/images/demo/avatar/{{node.data.avatar}}" width="32">
744
<div>{{node.data.name}}</div>
745
</div>
746
</ng-template>
747
</p-organizationchart>
748
`
749
})
750
```
751
752
## Status and Label Components
753
754
### Tag
755
756
Label/badge component for status display.
757
758
```typescript { .api }
759
// Import
760
import { Tag } from 'primeng/tag';
761
// Module: TagModule
762
763
// Component Interface
764
interface TagProps {
765
value?: string;
766
severity?: 'success' | 'secondary' | 'info' | 'warning' | 'danger' | 'contrast';
767
rounded?: boolean;
768
icon?: string;
769
styleClass?: string;
770
style?: any;
771
}
772
773
// Usage
774
@Component({
775
template: `
776
<p-tag value="New" severity="success"></p-tag>
777
<p-tag value="Pending" severity="warning" icon="pi pi-clock"></p-tag>
778
<p-tag value="Cancelled" severity="danger" [rounded]="true"></p-tag>
779
`
780
})
781
```
782
783
### ImageCompare
784
785
Side-by-side image comparison widget.
786
787
```typescript { .api }
788
// Import
789
import { ImageCompare } from 'primeng/imagecompare';
790
// Module: ImageCompareModule
791
792
// Component Interface
793
interface ImageCompareProps {
794
leftImageSrc?: string;
795
leftImageAlt?: string;
796
rightImageSrc?: string;
797
rightImageAlt?: string;
798
}
799
800
// Usage
801
@Component({
802
template: `
803
<p-imagecompare
804
leftImageSrc="assets/showcase/images/demo/galleria/galleria1.jpg"
805
rightImageSrc="assets/showcase/images/demo/galleria/galleria1s.jpg"
806
leftImageAlt="Left Image"
807
rightImageAlt="Right Image">
808
</p-imagecompare>
809
`
810
})
811
```
812
813
## Lazy Loading and Virtual Scrolling
814
815
Many data display components support lazy loading and virtual scrolling for performance with large datasets:
816
817
```typescript
818
// Lazy Loading Example
819
export class LazyLoadingComponent {
820
products: Product[] = [];
821
totalRecords: number = 0;
822
loading: boolean = false;
823
824
loadProducts(event: LazyLoadEvent) {
825
this.loading = true;
826
827
// Simulate API call
828
setTimeout(() => {
829
this.productService.getProducts(event).then(data => {
830
this.products = data.products;
831
this.totalRecords = data.totalRecords;
832
this.loading = false;
833
});
834
}, 1000);
835
}
836
}
837
838
// Template
839
@Component({
840
template: `
841
<p-table
842
[value]="products"
843
[lazy]="true"
844
[loading]="loading"
845
[totalRecords]="totalRecords"
846
[paginator]="true"
847
[rows]="10"
848
(onLazyLoad)="loadProducts($event)">
849
</p-table>
850
`
851
})
852
```
853
854
## Data Filtering and Sorting
855
856
Advanced filtering and sorting capabilities:
857
858
```typescript { .api }
859
// Filter Metadata Interface
860
interface FilterMetadata {
861
value?: any;
862
matchMode?: string;
863
operator?: string;
864
}
865
866
// Filter Match Modes
867
const FilterMatchMode = {
868
STARTS_WITH: 'startsWith',
869
CONTAINS: 'contains',
870
NOT_CONTAINS: 'notContains',
871
ENDS_WITH: 'endsWith',
872
EQUALS: 'equals',
873
NOT_EQUALS: 'notEquals',
874
LESS_THAN: 'lt',
875
LESS_THAN_OR_EQUAL_TO: 'lte',
876
GREATER_THAN: 'gt',
877
GREATER_THAN_OR_EQUAL_TO: 'gte',
878
BETWEEN: 'between',
879
IN: 'in',
880
IS: 'is',
881
IS_NOT: 'isNot',
882
BEFORE: 'before',
883
AFTER: 'after',
884
DATE_IS: 'dateIs',
885
DATE_IS_NOT: 'dateIsNot',
886
DATE_BEFORE: 'dateBefore',
887
DATE_AFTER: 'dateAfter'
888
};
889
890
// Sort Meta Interface
891
interface SortMeta {
892
field: string;
893
order: number;
894
}
895
```