ngx-st-primeng-tables
v19.0.0
Published
A powerful Angular table component built on PrimeNG Table with advanced features for data display, filtering, sorting, selection, and inline editing.
Readme
NgxStPrimengTables
A powerful Angular table component built on PrimeNG Table with advanced features for data display, filtering, sorting, selection, and inline editing.
Table of Contents
Overview
The ngx-st-primeng-table component extends PrimeNG Table with enterprise features including:
- Local and server-side (lazy) data loading
- Advanced filtering with custom options
- Column selection, reordering, and resizing
- Single and multiple row selection
- Inline row editing
- Persistent table state in localStorage or URL
- Mobile-responsive view
- Custom templates for cells and actions
- Export and pagination
Installation
npm install ngx-st-primeng-tables primeng primeiconsImport the module in your application:
import { NgxStPrimengTablesModule } from 'ngx-st-primeng-tables';
@NgModule({
imports: [
NgxStPrimengTablesModule
]
})
export class AppModule { }Basic Usage
<ngx-st-primeng-table
[data]="users"
[columns]="columns"
[rows]="10"
tableTitle="Users List">
</ngx-st-primeng-table>export class MyComponent {
users = [
{ id: 1, name: 'John Doe', email: '[email protected]', active: true },
{ id: 2, name: 'Jane Smith', email: '[email protected]', 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
Basic Configuration
data
- Type:
any[](required) - Description: Array of data objects to display in the table.
- Example:
[data]="users"
columns
- Type:
StPrimengTableColumnModel[](required) - Description: Column definitions that configure display, sorting, filtering, and editing.
- Example:
[columns]="columnDefs"
tableTitle
- Type:
string - Default:
'' - Description: Title displayed in the table caption.
- Example:
tableTitle="User Management"
localTable
- Type:
boolean - Default:
true - Description: When true, sorting/filtering handled client-side. When false, enables lazy loading mode.
- Example:
[localTable]="false" [totalRecords]="totalCount" (loadData)="onLoadData($event)"
totalRecords
- Type:
number - Default:
0 - Description: Total number of records (for server-side pagination). Required when
localTableis false. - Example:
[totalRecords]="1000"
Pagination
rows
- Type:
number(model - two-way binding) - Default:
10 - Description: Number of rows per page.
- Example:
[(rows)]="pageSize"
rowsPerPageOptions
- Type:
number[] - Default:
[5, 10, 20, 25] - Description: Options for rows per page dropdown.
- Example:
[rowsPerPageOptions]="[10, 25, 50, 100]"
Display & Layout
showGlobalSearch
- Type:
boolean - Default:
true - Description: Shows global search input that searches across all columns.
- Example:
[showGlobalSearch]="true" [globalSearchLabel]="'Search all fields'"
globalSearchLabel
- Type:
string - Default:
'Search' - Description: Placeholder text for global search input.
- Example:
globalSearchLabel="Search users..."
columnResize
- Type:
boolean - Default:
false - Description: Enables column resizing by dragging column borders.
- Example:
[columnResize]="true"
columnReorder
- Type:
boolean - Default:
false - Description: Enables column reordering by drag and drop.
- Example:
[columnReorder]="true"
columnSelect
- Type:
boolean - Default:
false - Description: Enables column visibility selection (show/hide columns).
- Example:
[columnSelect]="true"
useMobileView
- Type:
boolean - Default:
false - Description: Enables responsive mobile view for narrow screens.
- Example:
[useMobileView]="true"
State Persistence
localStorageId
- Type:
string - Default:
'' - Description: Key for storing table state in localStorage (pagination, sorting, filters, column order). If empty, state is not persisted.
- Example:
localStorageId="users-table-state"
bindSearchToUrl
- Type:
boolean - Default:
false - Description: Stores filters and pagination in URL query parameters. Takes precedence over localStorage.
- Example:
[bindSearchToUrl]="true"
Row Selection
selectable
- Type:
StPrimengTableSelectableOptionsModel | null - Default:
null - Description: Configuration object for row selection feature.
- Example:
[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:
[(selectedRows)]="selectedUsers"
initSelectRows
- Type:
any | any[] - Description: Initial row selection when table loads.
- Example:
[initSelectRows]="preSelectedUsers"
selectedRowChipsContent
- Type:
(row: any) => string - Description: Function to generate display text for selected row chips.
- Example:
[selectedRowChipsContent]="formatSelectedChip" formatSelectedChip(row: any): string { return `${row.name} (${row.email})`; }
Row Actions
onRowClick
- Type:
(row: any) => void - Description: Function called when a row is clicked (if selection is not active).
- Example:
[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:
[addNewButton]="addNewConfig" addNewConfig: StPrimengTableAddNewActionModel = { label: 'Add User', action: () => this.openCreateDialog() };
Row Editing
rowEditing
- Type:
boolean - Default:
false - Description: Enables inline row editing with save/cancel buttons.
- Example:
[rowEditing]="true" (updateRowEmitter)="onRowUpdate($event)"
canRowEditByField
- Type:
string - Default:
'' - Description: Field name in row data that determines if row is editable (truthy = editable).
- Example:
canRowEditByField="isEditable" // Row must have isEditable: true to be edited
Filters
filterInCaption
- Type:
boolean - Default:
false - Description: Displays filter inputs in caption area instead of column headers.
- Example:
[filterInCaption]="true"
Loading State
loading
- Type:
boolean - Default:
false - Description: Shows loading spinner overlay on table.
- Example:
[loading]="isLoading"
Outputs
loadData
- Type:
EventEmitter<LazyLoadEvent> - Description: Emitted when data needs to be loaded (lazy loading mode). Contains pagination, sorting, and filter information.
- Example:
(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; }); }
selectedRowsEmitter
- Type:
EventEmitter<any> - Description: Emitted when row selection changes.
- Example:
(selectedRowsEmitter)="onSelectionChange($event)" onSelectionChange(selected: any[]): void { console.log('Selected rows:', selected); }
updateRowEmitter
- Type:
EventEmitter<any> - Description: Emitted when a row is saved after inline editing.
- Example:
(updateRowEmitter)="onRowSaved($event)" onRowSaved(row: any): void { this.userService.updateUser(row).subscribe(() => { this.snackBar.success('User updated successfully'); }); }
Models
StPrimengTableColumnModel
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<any[]>;
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<any>; // 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
}StPrimengTableActionColumnModel
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
}StPrimengTableSelectableOptionsModel
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
}StPrimengTableAddNewActionModel
interface StPrimengTableAddNewActionModel {
label: string; // Button text
action: () => void; // Function to call when clicked
}Features
Local vs Lazy Loading
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
Column Types
- 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
State Persistence
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)
Mobile View
When enabled, table switches to card-based layout on small screens for better usability.
Examples
Basic Table with Sorting and Filtering
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'
}
];<ngx-st-primeng-table
[data]="users"
[columns]="columns"
[rows]="10"
[showGlobalSearch]="true"
tableTitle="Users">
</ngx-st-primeng-table>Table with Actions Column
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
}
]
}
];Table with Row Selection
selectConfig: StPrimengTableSelectableOptionsModel = {
active: true,
multiple: true,
selectedLabel: 'Selected Users',
selectAllAvailable: true,
selectionPageOnly: false,
showSelectTotal: true,
disableSelectFieldName: 'isArchived' // Can't select archived users
};
selectedUsers: any[] = [];<ngx-st-primeng-table
[data]="users"
[columns]="columns"
[selectable]="selectConfig"
[(selectedRows)]="selectedUsers"
[selectedRowChipsContent]="formatChip"
(selectedRowsEmitter)="onSelectionChange($event)">
</ngx-st-primeng-table>formatChip(row: any): string {
return `${row.name} (${row.email})`;
}
onSelectionChange(selected: any[]): void {
console.log(`${selected.length} users selected`);
}Lazy Loading Table (Server-Side)
users: any[] = [];
totalRecords = 0;
loading = false;<ngx-st-primeng-table
[localTable]="false"
[data]="users"
[columns]="columns"
[totalRecords]="totalRecords"
[rows]="10"
[loading]="loading"
(loadData)="loadUsers($event)">
</ngx-st-primeng-table>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;
});
}Table with Inline Editing
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' }
];<ngx-st-primeng-table
[data]="users"
[columns]="columns"
[rowEditing]="true"
canRowEditByField="isEditable"
(updateRowEmitter)="saveUser($event)">
</ngx-st-primeng-table>saveUser(user: any): void {
this.userService.updateUser(user).subscribe(() => {
this.snackBar.success('User updated');
});
}Table with Custom Filter
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'
}
}
];Table with Custom Template
columns: StPrimengTableColumnModel[] = [
{ field: 'name', header: 'Name', type: 'string' },
{
field: 'status',
header: 'Status',
type: 'custom-template',
customTemplate: this.statusTemplate
}
];
@ViewChild('statusTemplate') statusTemplate: TemplateRef<any>;<ng-template #statusTemplate let-row="row">
<span class="status-badge" [ngClass]="row.status">
{{ row.status | uppercase }}
</span>
</ng-template>
<ngx-st-primeng-table
[data]="users"
[columns]="columns">
</ngx-st-primeng-table>Table with State Persistence
<!-- Save to localStorage -->
<ngx-st-primeng-table
[data]="users"
[columns]="columns"
localStorageId="my-users-table"
[columnSelect]="true"
[columnReorder]="true">
</ngx-st-primeng-table>
<!-- Save to URL (better for sharing links) -->
<ngx-st-primeng-table
[data]="users"
[columns]="columns"
[bindSearchToUrl]="true">
</ngx-st-primeng-table>Full-Featured Table Example
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;
});
}
}<ngx-st-primeng-table
[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)">
</ngx-st-primeng-table>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.
