A powerful Angular table component built on PrimeNG Table with advanced features for data display, filtering, sorting, selection, and inline editing.
npm install ngx-st-primeng-tablesngx-st-primeng-table component extends PrimeNG Table with enterprise features including:
bash
npm install ngx-st-primeng-tables primeng primeicons
`
Import the module in your application:
`typescript
import { NgxStPrimengTablesModule } from 'ngx-st-primeng-tables';
@NgModule({
imports: [
NgxStPrimengTablesModule
]
})
export class AppModule { }
`
---
Basic Usage
`html
[data]="users"
[columns]="columns"
[rows]="10"
tableTitle="Users List">
`
`typescript
export class MyComponent {
users = [
{ id: 1, name: 'John Doe', email: 'john@example.com', active: true },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', active: false }
];
columns: StPrimengTableColumnModel[] = [
{ field: 'id', header: 'ID', type: 'number', width: '80px' },
{ field: 'name', header: 'Name', type: 'string' },
{ field: 'email', header: 'Email', type: 'string' },
{ field: 'active', header: 'Active', type: 'boolean', width: '100px' }
];
}
`
---
Inputs
$3
#### data
- Type: any[] (required)
- Description: Array of data objects to display in the table.
- Example:
`typescript
[data]="users"
`
#### columns
- Type: StPrimengTableColumnModel[] (required)
- Description: Column definitions that configure display, sorting, filtering, and editing.
- Example:
`typescript
[columns]="columnDefs"
`
#### tableTitle
- Type: string
- Default: ''
- Description: Title displayed in the table caption.
- Example:
`typescript
tableTitle="User Management"
`
#### localTable
- Type: boolean
- Default: true
- Description: When true, sorting/filtering handled client-side. When false, enables lazy loading mode.
- Example:
`typescript
[localTable]="false"
[totalRecords]="totalCount"
(loadData)="onLoadData($event)"
`
#### totalRecords
- Type: number
- Default: 0
- Description: Total number of records (for server-side pagination). Required when localTable is false.
- Example:
`typescript
[totalRecords]="1000"
`
$3
#### rows
- Type: number (model - two-way binding)
- Default: 10
- Description: Number of rows per page.
- Example:
`typescript
[(rows)]="pageSize"
`
#### rowsPerPageOptions
- Type: number[]
- Default: [5, 10, 20, 25]
- Description: Options for rows per page dropdown.
- Example:
`typescript
[rowsPerPageOptions]="[10, 25, 50, 100]"
`
$3
#### showGlobalSearch
- Type: boolean
- Default: true
- Description: Shows global search input that searches across all columns.
- Example:
`typescript
[showGlobalSearch]="true"
[globalSearchLabel]="'Search all fields'"
`
#### globalSearchLabel
- Type: string
- Default: 'Search'
- Description: Placeholder text for global search input.
- Example:
`typescript
globalSearchLabel="Search users..."
`
#### columnResize
- Type: boolean
- Default: false
- Description: Enables column resizing by dragging column borders.
- Example:
`typescript
[columnResize]="true"
`
#### columnReorder
- Type: boolean
- Default: false
- Description: Enables column reordering by drag and drop.
- Example:
`typescript
[columnReorder]="true"
`
#### columnSelect
- Type: boolean
- Default: false
- Description: Enables column visibility selection (show/hide columns).
- Example:
`typescript
[columnSelect]="true"
`
#### useMobileView
- Type: boolean
- Default: false
- Description: Enables responsive mobile view for narrow screens.
- Example:
`typescript
[useMobileView]="true"
`
$3
#### localStorageId
- Type: string
- Default: ''
- Description: Key for storing table state in localStorage (pagination, sorting, filters, column order). If empty, state is not persisted.
- Example:
`typescript
localStorageId="users-table-state"
`
#### bindSearchToUrl
- Type: boolean
- Default: false
- Description: Stores filters and pagination in URL query parameters. Takes precedence over localStorage.
- Example:
`typescript
[bindSearchToUrl]="true"
`
$3
#### selectable
- Type: StPrimengTableSelectableOptionsModel | null
- Default: null
- Description: Configuration object for row selection feature.
- Example:
`typescript
[selectable]="selectConfig"
selectConfig: StPrimengTableSelectableOptionsModel = {
active: true,
multiple: true,
selectedLabel: 'Selected Users',
selectAllAvailable: true,
showSelectTotal: true
};
`
#### selectedRows
- Type: any | any[]
- Description: Currently selected row(s). Use two-way binding.
- Example:
`typescript
[(selectedRows)]="selectedUsers"
`
#### initSelectRows
- Type: any | any[]
- Description: Initial row selection when table loads.
- Example:
`typescript
[initSelectRows]="preSelectedUsers"
`
#### selectedRowChipsContent
- Type: (row: any) => string
- Description: Function to generate display text for selected row chips.
- Example:
`typescript
[selectedRowChipsContent]="formatSelectedChip"
formatSelectedChip(row: any): string {
return ${row.name} (${row.email});
}
`
$3
#### onRowClick
- Type: (row: any) => void
- Description: Function called when a row is clicked (if selection is not active).
- Example:
`typescript
[onRowClick]="navigateToDetail"
navigateToDetail(row: any): void {
this.router.navigate(['/users', row.id]);
}
`
#### addNewButton
- Type: StPrimengTableAddNewActionModel | null
- Default: null
- Description: Configuration for "Add New" button in table caption.
- Example:
`typescript
[addNewButton]="addNewConfig"
addNewConfig: StPrimengTableAddNewActionModel = {
label: 'Add User',
action: () => this.openCreateDialog()
};
`
$3
#### rowEditing
- Type: boolean
- Default: false
- Description: Enables inline row editing with save/cancel buttons.
- Example:
`typescript
[rowEditing]="true"
(updateRowEmitter)="onRowUpdate($event)"
`
#### canRowEditByField
- Type: string
- Default: ''
- Description: Field name in row data that determines if row is editable (truthy = editable).
- Example:
`typescript
canRowEditByField="isEditable"
// Row must have isEditable: true to be edited
`
$3
#### filterInCaption
- Type: boolean
- Default: false
- Description: Displays filter inputs in caption area instead of column headers.
- Example:
`typescript
[filterInCaption]="true"
`
$3
#### loading
- Type: boolean
- Default: false
- Description: Shows loading spinner overlay on table.
- Example:
`typescript
[loading]="isLoading"
`
---
Outputs
$3
- Type: EventEmitter
- Description: Emitted when data needs to be loaded (lazy loading mode). Contains pagination, sorting, and filter information.
- Example:
`typescript
(loadData)="onLazyLoad($event)"
onLazyLoad(event: LazyLoadEvent): void {
this.loading = true;
this.userService.getUsers({
page: event.first! / event.rows!,
size: event.rows!,
sortField: event.sortField,
sortOrder: event.sortOrder,
filters: event.filters
}).subscribe(result => {
this.users = result.data;
this.totalRecords = result.total;
this.loading = false;
});
}
`
$3
- Type: EventEmitter
- Description: Emitted when row selection changes.
- Example:
`typescript
(selectedRowsEmitter)="onSelectionChange($event)"
onSelectionChange(selected: any[]): void {
console.log('Selected rows:', selected);
}
`
$3
- Type: EventEmitter
- Description: Emitted when a row is saved after inline editing.
- Example:
`typescript
(updateRowEmitter)="onRowSaved($event)"
onRowSaved(row: any): void {
this.userService.updateUser(row).subscribe(() => {
this.snackBar.success('User updated successfully');
});
}
`
---
Models
$3
`typescript
interface StPrimengTableColumnModel {
// Basic Properties
field: string; // Data field name (required)
header: string; // Column header text (required)
selectColumnLabel?: string; // Label for column in column selector
type?: 'string' | 'date' | 'selection' | 'number' |
'qty-input' | 'number-input' | 'boolean' | 'custom-template';
width?: string; // CSS width (e.g., '150px', '20%')
// Sorting & Filtering
sort?: boolean; // Enable sorting (default: true)
filter?: boolean; // Enable filtering (default: true)
customFilterOptions?: { // Custom dropdown filter
title: string;
data: Observable;
optionLabel: string;
optionValue: string;
};
// Display
flexRight?: boolean; // Align content right
translateValue?: { // Map values to display labels
[value: string]: string;
};
customValueDisplay?: (row: any) => string; // Custom display function
customTemplate?: TemplateRef; // Custom cell template
// Actions Column
actions?: StPrimengTableActionColumnModel[];
actionsInMenu?: boolean; // Show actions in dropdown menu
// Editing
editRowDisabled?: boolean; // Disable editing for this column
onValueChanged?: (row: any) => void; // Callback on value change
}
`
$3
`typescript
interface StPrimengTableActionColumnModel {
iconName: string; // Material icon name
iconClass?: string; // Additional CSS class
tooltipName: string; // Tooltip text
iconColor?: 'primary' | 'warn' | 'accent';
// Action (choose one)
action?: (row: any) => void; // Function to call
url?: string[]; // Router navigation path
// Conditional Display
show?: (row: any) => boolean; // Show/hide based on row data
}
`
$3
`typescript
interface StPrimengTableSelectableOptionsModel {
active: boolean; // Enable selection
multiple: boolean; // Multiple vs single selection
selectedLabel?: string; // Label for selected items section
disableSelectFieldName?: string; // Field name to disable selection for row
selectAllAvailable?: boolean; // Show "Select All" checkbox
selectionPageOnly?: boolean; // Select all only on current page
showSelectTotal?: boolean; // Show count of selected items
}
`
$3
`typescript
interface StPrimengTableAddNewActionModel {
label: string; // Button text
action: () => void; // Function to call when clicked
}
`
---
Features
$3
Local Mode (localTable: true):
- All data loaded at once
- Sorting and filtering handled client-side
- Fast for datasets under 1000 rows
Lazy Mode (localTable: false):
- Data loaded page by page from server
- Sorting and filtering handled server-side
- Required for large datasets
$3
- string: Text display and filtering
- number: Numeric display with right alignment
- boolean: Checkbox display
- date: Date formatting and date range filtering
- qty-input: Editable quantity input with +/- buttons
- number-input: Editable number input
- custom-template: Use your own template
$3
Table automatically saves and restores:
- Current page and page size
- Sort field and direction
- Filter values
- Column order (if reordering enabled)
- Column visibility (if column select enabled)
$3
When enabled, table switches to card-based layout on small screens for better usability.
---
Examples
$3
`typescript
columns: StPrimengTableColumnModel[] = [
{
field: 'id',
header: 'ID',
type: 'number',
width: '80px',
sort: true,
filter: true
},
{
field: 'name',
header: 'Name',
type: 'string',
sort: true,
filter: true
},
{
field: 'email',
header: 'Email',
type: 'string',
sort: true,
filter: true
},
{
field: 'active',
header: 'Status',
type: 'boolean',
width: '100px'
}
];
`
`html
[data]="users"
[columns]="columns"
[rows]="10"
[showGlobalSearch]="true"
tableTitle="Users">
`
$3
`typescript
columns: StPrimengTableColumnModel[] = [
{ field: 'name', header: 'Name', type: 'string' },
{ field: 'email', header: 'Email', type: 'string' },
{
field: 'actions',
header: 'Actions',
width: '150px',
flexRight: true,
actions: [
{
iconName: 'edit',
tooltipName: 'Edit',
iconColor: 'primary',
action: (row) => this.editUser(row)
},
{
iconName: 'delete',
tooltipName: 'Delete',
iconColor: 'warn',
action: (row) => this.deleteUser(row),
show: (row) => row.canDelete // Conditional display
},
{
iconName: 'visibility',
tooltipName: 'View Details',
url: ['/users', 'id'] // Router navigation
}
]
}
];
`
$3
`typescript
selectConfig: StPrimengTableSelectableOptionsModel = {
active: true,
multiple: true,
selectedLabel: 'Selected Users',
selectAllAvailable: true,
selectionPageOnly: false,
showSelectTotal: true,
disableSelectFieldName: 'isArchived' // Can't select archived users
};
selectedUsers: any[] = [];
`
`html
[data]="users"
[columns]="columns"
[selectable]="selectConfig"
[(selectedRows)]="selectedUsers"
[selectedRowChipsContent]="formatChip"
(selectedRowsEmitter)="onSelectionChange($event)">
`
`typescript
formatChip(row: any): string {
return ${row.name} (${row.email});
}
onSelectionChange(selected: any[]): void {
console.log(${selected.length} users selected);
}
`
$3
`typescript
users: any[] = [];
totalRecords = 0;
loading = false;
`
`html
[localTable]="false"
[data]="users"
[columns]="columns"
[totalRecords]="totalRecords"
[rows]="10"
[loading]="loading"
(loadData)="loadUsers($event)">
`
`typescript
loadUsers(event: LazyLoadEvent): void {
this.loading = true;
const params = {
page: event.first! / event.rows!,
size: event.rows!,
sortField: event.sortField as string,
sortOrder: event.sortOrder === 1 ? 'asc' : 'desc',
globalFilter: event.globalFilter,
filters: event.filters
};
this.userService.getUsers(params).subscribe(response => {
this.users = response.data;
this.totalRecords = response.total;
this.loading = false;
});
}
`
$3
`typescript
columns: StPrimengTableColumnModel[] = [
{ field: 'name', header: 'Name', type: 'string' },
{ field: 'email', header: 'Email', type: 'string' },
{
field: 'quantity',
header: 'Quantity',
type: 'qty-input', // Editable quantity with +/- buttons
onValueChanged: (row) => this.calculateTotal(row)
},
{ field: 'active', header: 'Active', type: 'boolean' }
];
`
`html
[data]="users"
[columns]="columns"
[rowEditing]="true"
canRowEditByField="isEditable"
(updateRowEmitter)="saveUser($event)">
`
`typescript
saveUser(user: any): void {
this.userService.updateUser(user).subscribe(() => {
this.snackBar.success('User updated');
});
}
`
$3
`typescript
columns: StPrimengTableColumnModel[] = [
{ field: 'name', header: 'Name', type: 'string' },
{
field: 'department',
header: 'Department',
type: 'string',
customFilterOptions: {
title: 'Filter by Department',
data: this.departmentService.getDepartments(), // Observable
optionLabel: 'name',
optionValue: 'id'
}
}
];
`
$3
`typescript
columns: StPrimengTableColumnModel[] = [
{ field: 'name', header: 'Name', type: 'string' },
{
field: 'status',
header: 'Status',
type: 'custom-template',
customTemplate: this.statusTemplate
}
];
@ViewChild('statusTemplate') statusTemplate: TemplateRef;
`
`html
{{ row.status | uppercase }}
[data]="users"
[columns]="columns">
`
$3
`html
[data]="users"
[columns]="columns"
localStorageId="my-users-table"
[columnSelect]="true"
[columnReorder]="true">
[data]="users"
[columns]="columns"
[bindSearchToUrl]="true">
`
$3
`typescript
export class UsersComponent {
users: any[] = [];
totalRecords = 0;
loading = false;
selectedUsers: any[] = [];
pageSize = 10;
columns: StPrimengTableColumnModel[] = [
{ field: 'id', header: 'ID', type: 'number', width: '80px', sort: true },
{ field: 'name', header: 'Name', type: 'string', sort: true, filter: true },
{ field: 'email', header: 'Email', type: 'string', sort: true, filter: true },
{
field: 'role',
header: 'Role',
type: 'string',
translateValue: {
'admin': 'Administrator',
'user': 'Regular User',
'guest': 'Guest'
}
},
{ field: 'active', header: 'Active', type: 'boolean', width: '100px' },
{ field: 'createdAt', header: 'Created', type: 'date', width: '120px' },
{
field: 'actions',
header: '',
width: '120px',
flexRight: true,
actions: [
{
iconName: 'edit',
tooltipName: 'Edit User',
iconColor: 'primary',
action: (row) => this.editUser(row)
},
{
iconName: 'delete',
tooltipName: 'Delete User',
iconColor: 'warn',
action: (row) => this.deleteUser(row),
show: (row) => row.role !== 'admin'
}
]
}
];
selectConfig: StPrimengTableSelectableOptionsModel = {
active: true,
multiple: true,
selectedLabel: 'Selected Users',
selectAllAvailable: true,
showSelectTotal: true
};
addNewConfig: StPrimengTableAddNewActionModel = {
label: 'Add User',
action: () => this.openCreateDialog()
};
loadData(event: LazyLoadEvent): void {
this.loading = true;
this.userService.getUsers(event).subscribe(response => {
this.users = response.data;
this.totalRecords = response.total;
this.loading = false;
});
}
}
`
`html
[localTable]="false"
[data]="users"
[columns]="columns"
[totalRecords]="totalRecords"
[(rows)]="pageSize"
[rowsPerPageOptions]="[10, 25, 50, 100]"
[loading]="loading"
[showGlobalSearch]="true"
globalSearchLabel="Search users..."
tableTitle="User Management"
[columnResize]="true"
[columnReorder]="true"
[columnSelect]="true"
[selectable]="selectConfig"
[(selectedRows)]="selectedUsers"
[addNewButton]="addNewConfig"
[useMobileView]="true"
localStorageId="users-table"
(loadData)="loadData($event)"
(selectedRowsEmitter)="onSelectionChange($event)">
`
---
Build
Run ng build ngx-st-primeng-tables to build the project. The build artifacts will be stored in the dist/ directory.
Publishing
After building your library with ng build ngx-st-primeng-tables, go to the dist folder cd dist/ngx-st-primeng-tables and run npm publish`.