Skip to content

Instantly share code, notes, and snippets.

@killan
Created July 6, 2025 14:23
Show Gist options
  • Select an option

  • Save killan/f157c89b5462a16b214287ab70d5e4e9 to your computer and use it in GitHub Desktop.

Select an option

Save killan/f157c89b5462a16b214287ab70d5e4e9 to your computer and use it in GitHub Desktop.
primeng-simple-table updated v19
import { Directive, effect, EffectRef, inject, input, OnInit, ViewContainerRef } from '@angular/core';
import { CellComponentConfig } from '../interfaces/components/cell-components';
@Directive({
selector: '[cellComponentsHost]'
})
export class CellComponentsHostDirective implements OnInit {
#viewContainerRef = inject(ViewContainerRef)
items = input<CellComponentConfig[]>([], {
alias: 'cellComponentsHost'
})
rowData = input<any>([])
field = input<string>('')
render: EffectRef = effect(() => {
this.initContent()
})
ngOnInit(): void {
this.initContent()
}
initContent(): void {
// Clean
this.#viewContainerRef.clear()
// Add each item
this.items().forEach((item) => {
const component = this.#viewContainerRef.createComponent(item.component)
component.setInput('rowData', this.rowData())
component.setInput('field', this.field())
component.setInput('options', item.options)
component.setInput('events', item.events)
})
}
}
import { InputSignal } from '@angular/core';
export interface CellComponentConfig {
component: any
options?: any
events?: any
}
export interface CellComponent {
rowData: InputSignal<any>
field: InputSignal<string>
options?: InputSignal<any>
events?: InputSignal<any>
}
<p-table [value]="data()" [columns]="cols()" stripedRows [rowHover]="true" [dataKey]="dataKey()" [sortField]="sortField()"
[sortOrder]="sortOrder()" class="w-full">
<ng-template #header let-columns>
<tr>
@for (col of columns; track col.field) {
<th [pSortableColumn]="col.field" [pSortableColumnDisabled]="!col.sortable">
{{ col.header }}
</th>
}
</tr>
</ng-template>
<ng-template #body let-rowData let-columns="columns">
<tr>
@for (col of columns; track col.field) {
<td>
@if (!col.components) {
<div [outerHTML]="col.renderer(rowData, col.field)"></div>
} @else {
<ng-container [cellComponentsHost]="col.components" [rowData]="rowData" [field]="col.field"></ng-container>
}
</td>
}
</tr>
</ng-template>
</p-table>
import { Component, effect, input, model } from '@angular/core';
import { TableModule } from 'primeng/table';
import { ColumnDefinition } from '../../interfaces/components/table';
import { CellRenderer } from '../../services/cell-renderer.service';
import { CellComponentsHostDirective } from '../../directives/cell-components-host';
@Component({
selector: 'oma-table',
imports: [
TableModule,
CellComponentsHostDirective
],
templateUrl: './table.component.html',
})
export class TableComponent {
data = input<any[]>([])
dataKey = input("id")
sortField = input("id")
sortOrder = input(1)
cols = model<ColumnDefinition[]>([])
constructor() {
effect(() => {
const cols = this.cols()
cols.forEach((c) => {
if (!c.renderer) {
c.renderer = CellRenderer.none
}
if (!c.sortable) {
c.sortable = false
}
})
});
}
}
import { CellComponentConfig } from './cell-components';
export interface ColumnDefinition {
field: string
header: string
renderer?: (rowData: any, field: string) => string
sortable?: boolean
components?: CellComponentConfig[]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment