tablor-core
Version:
Core features for data tables, grids, and advanced search, pagination, and sorting in Angular.
510 lines (391 loc) β’ 11.7 kB
Markdown
# Tablor-Core - Stable π
**Create beautiful datatables, grid views, and more effortlessly with Tablor-Core!**
Leverage powerful features already implementedβyou just need to focus on your UI.
## π‘ Why Choose Tablor-Core?
Tablor-Core offers an extensive toolkit for building interactive and dynamic datatables with minimal effort. Whether you're creating grid views or advanced data management UIs, Tablor-Core has you covered.
## Demo
- Minimal setup with dataset for your own test implementation:
**π [Try It Yourself](https://stackblitz.com/github/TIPUzee/tablor-core-demo/tree/base-workspace?ctl=1&embed=1&file=src%2Fapp%2Fapp.component.ts)**
- Fully functioning preview with plain HTML UI:
**π [Plain HTML Preview](https://stackblitz.com/github/TIPUzee/tablor-core-demo/tree/plain-html-showcase?ctl=1&embed=1&file=src%2Fapp%2Fapp.component.ts&view=preview)**
- Fully functioning preview with Spartan UI:
**π [Spartan UI Preview](https://stackblitz.com/github/TIPUzee/tablor-core-demo/tree/spartan-ui-showcase?ctl=1&embed=1&file=src%2Fapp%2Fapp.component.ts&view=preview)**
## π οΈ Installation
```bash
npm install tablor-core
```
## π Features at a Glance
### Sorting
- **Basic Sorting**
- **Custom Sorting Toggle Orders**
- **Multi-Field Sorting**
- Example: Sort transactions by **bank names**, then **nested sort by transaction date**.
### π Search
- **Search Within Previous Results**
- **Merge Results into Previous Searches**
- **Field-Specific Search Criteria**
#### **Search By String Query**
- Include specific fields.
- Custom functions for converting numbers, dates, booleans, nulls, and undefined values to searchable strings.
- Word matching with:
- **StartsWith**, **EndsWith**, **Contains**, **ExactMatch**
- Search words **in order** or **any order**.
- Search **consecutive** or **non-consecutive** words.
#### **Advanced Search Capabilities**
- Search by **date ranges** (multiple ranges for multiple fields).
- Search by **number ranges** (multiple ranges for multiple fields).
- Search by **exact values** (multiple values for multiple fields).
- Use **custom search functions**.
- **Revert Search Results**: Replace searched items with those not searched.
### π Pagination
- Navigate pages with ease:
- **Go To Page**
- **Set Items Per Page**
- Display **all items** on a single page.
### ποΈ Item Selection
- Select and retrieve items with flexibility:
- Get **selected items**.
- Get items **within the page** or **outside the page**.
### β‘ Event-Based System
- Fully event-driven for seamless integration:
- Events for **page changes**, **sorting updates**, **search criteria changes**, **item selection changes**, **deletions**, and more.
## How to Use Tablor-Core
### 1. Define Your Data and Fields
#### `user.interface.ts`
```typescript
import { TablorCoreTypes as TcT } from 'tablor-core';
export type User = {
id: number;
name: string;
email: string;
dob: Date | null;
cgpa: number,
};
export type UserTcT = TcT<User>;
export const userFields: UserTcT['RegularFields'] = {
id: { title: 'ID' },
name: { title: 'Name' },
email: { title: 'Email' },
dob: { title: 'Date of Birth' },
cgpa: { title: 'CGPA' },
};
```
#### `user.data.ts`
```typescript
import { User } from './user.interface';
export const users: User[] = [
{ id: 1, name: 'John Doe', email: 'M3u5W@example.com', dob: new Date('1990-01-01'), cgpa: 3.7 },
{ id: 2, name: 'Jane Smith', email: 'H7Uwq@example.com', dob: null, cgpa: 3.0 },
// Add more data as needed...
];
```
### 2. Initialize TablorCore in Your Component
#### `my.component.ts`
```typescript
import { Component } from '@angular/core';
import { TablorCore } from 'tablor-core';
import { User, UserTcT, userFields } from './user.interface';
import { users } from './user.data';
@Component({
selector: 'my-component',
templateUrl: './my.component.html',
styleUrls: ['./my.component.scss'],
})
export class MyComponent
{
readonly tablor: TablorCore<User> = new TablorCore();
constructor()
{
this.tablor.initializeFields(userFields);
this.tablor.initializeItems(users);
}
}
```
### 3. Use TablorCore in Templates
#### `my.component.html`
```html
<table>
<thead>
<tr>
<th *ngFor="let field of tablor.getFieldsAsArray()">
{{ field.title }}
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of tablor.getPaginatedItems()">
<td *ngFor="let field of tablor.getFieldsAsArray()">
{{ item[field.key] }}
</td>
</tr>
</tbody>
</table>
<button (click)="tablor.setPageNb(tablor.getPageNb() + 1)">
Next Page
</button>
```
### 4. Sorting Examples
#### Sort by Single Field
```typescript
tablor.sort({
field: 'name',
order: 'Toggle',
insertBehavior: {
insertAt: 0,
},
clear: {
target: 'AllNested',
},
});
```
#### Sort by Multiple Nested Fields
Use cases: Sort transactions by **transaction amount**, then **nested sort by transaction date**. Means if there are multiple transactions with the same amount, older transactions should show up first.
```typescript
tablor.sort({
field: 'name',
order: 'DESC',
});
tablor.sort({
field: 'dob',
order: 'ASC',
});
// Items will be sorted first by name as desc order, then by date of birth as asc order.
// e.g.
// Zeeshan Nadeem (1990-01-01) // there are multiple items with the same name
// Zeeshan Nadeem (1995-01-01)
// Zeeshan Nadeem (2000-01-01)
// John Doe (1990-01-01)
// Jahn Doe (1991-01-01)
// Jane Smith (null)
```
#### Handle undefined and null values for sorting
```typescript
tablor.sort({
field: 'dob',
order: 'Toggle',
prioritizeNulls: 'AlwaysLast',
prioritizeUndefineds: 'AlwaysLast',
insertBehavior: {
insertAt: 0,
},
clear: {
target: 'AllNested',
},
});
// Possible options: 'AlwaysFirst' | 'AlwaysLast' | 'FirstOnASC' | 'LastOnASC'
// 'FirstOnASC' means if sorted by ASC order, null/undefined values will be sorted first.
// And if sorted by DESC order, it will be sorted last.
```
### 5. Searching Examples
#### Search by String Query
```typescript
tablor.searchByStringQuery({
query: 'Zeeshan Nadeem',
includeFields: ['name', 'email'],
prevResults: {
action: 'Clear',
scope: 'All',
},
});
```
#### Search by String with Non-String Conversion
```typescript
tablor.searchByStringQuery({
query: 'Zeeshan 31 Mar',
includeFields: ['name', 'dob'],
convertToString: {
string: s => s,
number: n => n.toString(),
date: d => d.toGMTString(),
boolean: b => b.toString(),
null: () => 'null',
undefined: () => 'undefined',
},
prevResults: {
action: 'Clear',
scope: 'All',
},
});
```
### 6. Advanced Search Examples
#### Search by Date Ranges
```typescript
tablor.searchByDateTimesRanges({
ranges: {
dob: [
{ start: new Date('2020-01-01'), end: 'Now', includeStart: true },
{ start: undefined, end: 'Now', endOffset: { years: -20 } },
],
},
prevResults: {
action: 'Clear',
scope: 'All',
},
});
```
#### Search by Number Ranges
```typescript
tablor.searchByNumbersRanges({
ranges: {
cgpa: [
{ min: 3.7 },
],
},
prevResults: {
action: 'Clear',
scope: 'All',
},
});
```
#### Search by Exact Values
```typescript
tablor.searchByExactValues({
values: {
dob: [null, undefined],
},
prevResults: {
action: 'Clear',
scope: 'All',
},
});
```
#### Combine Search Queries
```typescript
tablor.searchByStringQuery({
query: 'Zeeshan',
includeFields: ['name'],
prevResults: {
action: 'Clear',
scope: 'All',
},
});
tablor.searchByDateTimesRanges({
ranges: {
dob: [
{ start: new Date('1995-01-01'), end: new Date('2005-01-01'), includeStart: true },
],
},
prevResults: {
action: 'Keep',
},
searchTarget: {
scope: 'Prev',
},
});
```
#### Revert Search Results of one Search
To replace searched items with those not searched, use the `revertResultsAtEnd` property.
```typescript
tablor.searchByStringQuery({
query: 'Zeeshan',
includeFields: ['name'],
prevResults: {
action: 'Clear',
scope: 'All',
},
revertResultsAtEnd: true,
})
// This operation will get those users who do not have 'Zeeshan' in their name.
```
#### Revert Search Results of All the Performed Searches
```typescript
tablor.searchByStringQuery({
query: 'Zeeshan',
includeFields: ['name'],
prevResults: {
action: 'Clear',
scope: 'All',
},
})
tablor.searchByDateTimesRanges({
ranges: {
dob: [
{ start: new Date('1995-01-01'), end: new Date('2005-01-01'), includeStart: true },
],
},
prevResults: {
action: 'Keep',
},
searchTarget: {
scope: 'Prev',
},
});
tablor.searchByVoid({
prevResults: {
action: 'Keep',
},
searchTarget: {
scope: 'Prev',
},
revertResultsAtEnd: true,
})
```
### 7. Select Items
#### Select an Item
```typescript
tablor.selectItem(item, true);
```
#### Deselect an Item
```typescript
tablor.selectItem(item, false);
```
#### Toggle an Item's Selection
```typescript
tablor.selectItem(item, 'toggle');
```
#### Get Selected Items
```typescript
tablor.getSelectedItems();
```
#### Get Selected Items Within the Current Page
```typescript
tablor.getSelectedPaginatedItems();
```
### 8. Event Handling
TablorCore provides events to handle user interactions and custom events.
#### Subscribe to Items Removed Event
```typescript
tablor.$itemsRemoved.subscribe(options =>
{
console.log('Items removed:', options.removedItems);
// Or API call to remove items from server.
})
```
#### Subscribe to Items Updated Event
```typescript
tablor.$itemsUpdated.subscribe(options =>
{
console.log('Items updated - after update:', options.updatedItems);
console.log('Items updated - before update:', options.prevUpdatedItems);
console.log('Items updated - update difference:', options.updatedItemsDifference);
})
```
#### Subscribe to Page Number Changed Event
```typescript
tablor.$pageNbChanged.subscribe(options =>
{
console.log('Page number changed - new page nb:', options.pageNb);
console.log('Page number changed - prev page nb:', options.prevPageNb);
})
```
There are many more events you can subscribe to.
But note that all of these events are also used in the `TablorCore` class,
so `avoid marking them as completed`.
### Additional Functionalities
Explore more powerful features that you can explore yourself.
π **Start Building with Tablor-Core Today!**
## π License
This project is licensed under the **MIT License**.
Copyright 2025 [TIPUzee](https://github.com/TIPUzee).