ngx-column-filter-popup 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +135 -55
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -297,7 +297,8 @@ export class YourModule {}
|
|
|
297
297
|
columnName="name"
|
|
298
298
|
columnKey="name"
|
|
299
299
|
fieldType="text"
|
|
300
|
-
(filterApplied)="
|
|
300
|
+
(filterApplied)="onFilterApplied('name', $event)"
|
|
301
|
+
(filterCleared)="onFilterCleared('name')">
|
|
301
302
|
</lib-column-filter>
|
|
302
303
|
```
|
|
303
304
|
|
|
@@ -309,7 +310,8 @@ export class YourModule {}
|
|
|
309
310
|
columnKey="balance"
|
|
310
311
|
fieldType="currency"
|
|
311
312
|
currencySymbol="$"
|
|
312
|
-
(filterApplied)="
|
|
313
|
+
(filterApplied)="onFilterApplied('balance', $event)"
|
|
314
|
+
(filterCleared)="onFilterCleared('balance')">
|
|
313
315
|
</lib-column-filter>
|
|
314
316
|
```
|
|
315
317
|
|
|
@@ -320,7 +322,8 @@ export class YourModule {}
|
|
|
320
322
|
columnName="age"
|
|
321
323
|
columnKey="age"
|
|
322
324
|
fieldType="age"
|
|
323
|
-
(filterApplied)="
|
|
325
|
+
(filterApplied)="onFilterApplied('age', $event)"
|
|
326
|
+
(filterCleared)="onFilterCleared('age')">
|
|
324
327
|
</lib-column-filter>
|
|
325
328
|
```
|
|
326
329
|
|
|
@@ -331,7 +334,8 @@ export class YourModule {}
|
|
|
331
334
|
columnName="date"
|
|
332
335
|
columnKey="date"
|
|
333
336
|
fieldType="date"
|
|
334
|
-
(filterApplied)="
|
|
337
|
+
(filterApplied)="onFilterApplied('date', $event)"
|
|
338
|
+
(filterCleared)="onFilterCleared('date')">
|
|
335
339
|
</lib-column-filter>
|
|
336
340
|
```
|
|
337
341
|
|
|
@@ -343,10 +347,13 @@ export class YourModule {}
|
|
|
343
347
|
columnKey="status"
|
|
344
348
|
fieldType="status"
|
|
345
349
|
[statusOptions]="['qualified', 'unqualified', 'negotiation', 'new']"
|
|
346
|
-
(filterApplied)="
|
|
350
|
+
(filterApplied)="onFilterApplied('status', $event)"
|
|
351
|
+
(filterCleared)="onFilterCleared('status')">
|
|
347
352
|
</lib-column-filter>
|
|
348
353
|
```
|
|
349
354
|
|
|
355
|
+
> 💡 **Note**: All examples use generic handlers `onFilterApplied(columnKey, $event)` and `onFilterCleared(columnKey)` - no need for separate functions per filter!
|
|
356
|
+
|
|
350
357
|
## API Reference
|
|
351
358
|
|
|
352
359
|
### ColumnFilterComponent
|
|
@@ -584,8 +591,11 @@ export class ExampleComponent {
|
|
|
584
591
|
|
|
585
592
|
## Complete Example
|
|
586
593
|
|
|
594
|
+
**✅ Modern Implementation using Generic Handlers (Recommended):**
|
|
595
|
+
|
|
587
596
|
```typescript
|
|
588
|
-
import { Component } from '@angular/core';
|
|
597
|
+
import { Component, ViewChildren, QueryList } from '@angular/core';
|
|
598
|
+
import { CommonModule } from '@angular/common';
|
|
589
599
|
import { ColumnFilterComponent } from 'ngx-column-filter-popup';
|
|
590
600
|
import { FilterConfig, applyColumnFilter } from 'ngx-column-filter-popup';
|
|
591
601
|
|
|
@@ -602,8 +612,9 @@ interface User {
|
|
|
602
612
|
|
|
603
613
|
@Component({
|
|
604
614
|
selector: 'app-user-list',
|
|
605
|
-
imports: [ColumnFilterComponent],
|
|
615
|
+
imports: [CommonModule, ColumnFilterComponent],
|
|
606
616
|
template: `
|
|
617
|
+
<button (click)="clearAllFilters()">Clear All Filters</button>
|
|
607
618
|
<table>
|
|
608
619
|
<thead>
|
|
609
620
|
<tr>
|
|
@@ -612,8 +623,29 @@ interface User {
|
|
|
612
623
|
<lib-column-filter
|
|
613
624
|
columnName="first name"
|
|
614
625
|
columnKey="firstName"
|
|
615
|
-
|
|
616
|
-
|
|
626
|
+
[allowMultipleRules]="false"
|
|
627
|
+
[backendMode]="isBackendMode('firstName')"
|
|
628
|
+
(filterApplied)="onFilterApplied('firstName', $event)"
|
|
629
|
+
(filterCleared)="onFilterCleared('firstName')">
|
|
630
|
+
</lib-column-filter>
|
|
631
|
+
</th>
|
|
632
|
+
<th>
|
|
633
|
+
Last Name
|
|
634
|
+
<lib-column-filter
|
|
635
|
+
columnName="last name"
|
|
636
|
+
columnKey="lastName"
|
|
637
|
+
(filterApplied)="onFilterApplied('lastName', $event)"
|
|
638
|
+
(filterCleared)="onFilterCleared('lastName')">
|
|
639
|
+
</lib-column-filter>
|
|
640
|
+
</th>
|
|
641
|
+
<th>
|
|
642
|
+
Email
|
|
643
|
+
<lib-column-filter
|
|
644
|
+
columnName="email"
|
|
645
|
+
columnKey="email"
|
|
646
|
+
[backendMode]="isBackendMode('email')"
|
|
647
|
+
(filterApplied)="onFilterApplied('email', $event)"
|
|
648
|
+
(filterCleared)="onFilterCleared('email')">
|
|
617
649
|
</lib-column-filter>
|
|
618
650
|
</th>
|
|
619
651
|
<th>
|
|
@@ -622,7 +654,8 @@ interface User {
|
|
|
622
654
|
columnName="age"
|
|
623
655
|
columnKey="age"
|
|
624
656
|
fieldType="age"
|
|
625
|
-
(filterApplied)="
|
|
657
|
+
(filterApplied)="onFilterApplied('age', $event)"
|
|
658
|
+
(filterCleared)="onFilterCleared('age')">
|
|
626
659
|
</lib-column-filter>
|
|
627
660
|
</th>
|
|
628
661
|
<th>
|
|
@@ -632,7 +665,8 @@ interface User {
|
|
|
632
665
|
columnKey="balance"
|
|
633
666
|
fieldType="currency"
|
|
634
667
|
currencySymbol="$"
|
|
635
|
-
(filterApplied)="
|
|
668
|
+
(filterApplied)="onFilterApplied('balance', $event)"
|
|
669
|
+
(filterCleared)="onFilterCleared('balance')">
|
|
636
670
|
</lib-column-filter>
|
|
637
671
|
</th>
|
|
638
672
|
<th>
|
|
@@ -641,7 +675,8 @@ interface User {
|
|
|
641
675
|
columnName="join date"
|
|
642
676
|
columnKey="joinDate"
|
|
643
677
|
fieldType="date"
|
|
644
|
-
(filterApplied)="
|
|
678
|
+
(filterApplied)="onFilterApplied('joinDate', $event)"
|
|
679
|
+
(filterCleared)="onFilterCleared('joinDate')">
|
|
645
680
|
</lib-column-filter>
|
|
646
681
|
</th>
|
|
647
682
|
<th>
|
|
@@ -651,7 +686,8 @@ interface User {
|
|
|
651
686
|
columnKey="status"
|
|
652
687
|
fieldType="status"
|
|
653
688
|
[statusOptions]="statusOptions"
|
|
654
|
-
(filterApplied)="
|
|
689
|
+
(filterApplied)="onFilterApplied('status', $event)"
|
|
690
|
+
(filterCleared)="onFilterCleared('status')">
|
|
655
691
|
</lib-column-filter>
|
|
656
692
|
</th>
|
|
657
693
|
</tr>
|
|
@@ -659,6 +695,8 @@ interface User {
|
|
|
659
695
|
<tbody>
|
|
660
696
|
<tr *ngFor="let user of filteredUsers">
|
|
661
697
|
<td>{{ user.firstName }}</td>
|
|
698
|
+
<td>{{ user.lastName }}</td>
|
|
699
|
+
<td>{{ user.email }}</td>
|
|
662
700
|
<td>{{ user.age }}</td>
|
|
663
701
|
<td>${{ user.balance }}</td>
|
|
664
702
|
<td>{{ user.joinDate }}</td>
|
|
@@ -675,67 +713,109 @@ export class UserListComponent {
|
|
|
675
713
|
|
|
676
714
|
filteredUsers: User[] = [...this.users];
|
|
677
715
|
statusOptions = ['active', 'inactive', 'on-leave'];
|
|
678
|
-
|
|
679
|
-
firstNameFilter: FilterConfig | null = null;
|
|
680
|
-
ageFilter: FilterConfig | null = null;
|
|
681
|
-
balanceFilter: FilterConfig | null = null;
|
|
682
|
-
dateFilter: FilterConfig | null = null;
|
|
683
|
-
statusFilter: FilterConfig | null = null;
|
|
684
|
-
|
|
685
|
-
onFirstNameFilter(filterConfig: FilterConfig) {
|
|
686
|
-
this.firstNameFilter = filterConfig;
|
|
687
|
-
this.applyAllFilters();
|
|
688
|
-
}
|
|
689
716
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
this.applyAllFilters();
|
|
693
|
-
}
|
|
717
|
+
// ✅ Unified filter storage - single source of truth
|
|
718
|
+
filters = new Map<string, FilterConfig | null>();
|
|
694
719
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
this.applyAllFilters();
|
|
698
|
-
}
|
|
720
|
+
// ✅ Configuration: Which columns use backend mode
|
|
721
|
+
readonly backendModeColumns = new Set<string>(['firstName', 'email']);
|
|
699
722
|
|
|
700
|
-
|
|
701
|
-
|
|
723
|
+
@ViewChildren(ColumnFilterComponent) filterComponents!: QueryList<ColumnFilterComponent>;
|
|
724
|
+
|
|
725
|
+
// ✅ Generic filter handler - works for ALL columns (no separate functions needed!)
|
|
726
|
+
onFilterApplied(columnKey: string, filterConfig: FilterConfig): void {
|
|
727
|
+
this.filters.set(columnKey, filterConfig);
|
|
728
|
+
|
|
729
|
+
if (this.isBackendMode(columnKey)) {
|
|
730
|
+
this.sendAllBackendFiltersToBackend();
|
|
731
|
+
}
|
|
732
|
+
|
|
702
733
|
this.applyAllFilters();
|
|
703
734
|
}
|
|
704
735
|
|
|
705
|
-
|
|
706
|
-
|
|
736
|
+
// ✅ Generic filter clear handler - works for ALL columns
|
|
737
|
+
onFilterCleared(columnKey: string): void {
|
|
738
|
+
this.filters.set(columnKey, null);
|
|
739
|
+
|
|
740
|
+
if (this.isBackendMode(columnKey)) {
|
|
741
|
+
this.sendAllBackendFiltersToBackend();
|
|
742
|
+
}
|
|
743
|
+
|
|
707
744
|
this.applyAllFilters();
|
|
708
745
|
}
|
|
709
746
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
this.
|
|
747
|
+
// ✅ Check if column uses backend mode
|
|
748
|
+
isBackendMode(columnKey: string): boolean {
|
|
749
|
+
return this.backendModeColumns.has(columnKey);
|
|
713
750
|
}
|
|
714
751
|
|
|
715
|
-
|
|
752
|
+
// ✅ Apply all filters - automatically skips backend mode columns
|
|
753
|
+
private applyAllFilters(): void {
|
|
716
754
|
let result = [...this.users];
|
|
717
755
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
}
|
|
724
|
-
if (this.balanceFilter) {
|
|
725
|
-
result = applyColumnFilter(result, 'balance', this.balanceFilter);
|
|
726
|
-
}
|
|
727
|
-
if (this.dateFilter) {
|
|
728
|
-
result = applyColumnFilter(result, 'joinDate', this.dateFilter);
|
|
729
|
-
}
|
|
730
|
-
if (this.statusFilter) {
|
|
731
|
-
result = applyColumnFilter(result, 'status', this.statusFilter);
|
|
732
|
-
}
|
|
756
|
+
this.filters.forEach((filterConfig, columnKey) => {
|
|
757
|
+
// Skip backend mode columns (handled by backend)
|
|
758
|
+
if (filterConfig && !this.isBackendMode(columnKey)) {
|
|
759
|
+
result = applyColumnFilter(result, columnKey, filterConfig);
|
|
760
|
+
}
|
|
761
|
+
});
|
|
733
762
|
|
|
734
763
|
this.filteredUsers = result;
|
|
735
764
|
}
|
|
765
|
+
|
|
766
|
+
// ✅ Clear all filters programmatically
|
|
767
|
+
clearAllFilters(): void {
|
|
768
|
+
this.filters.clear();
|
|
769
|
+
this.sendAllBackendFiltersToBackend();
|
|
770
|
+
this.filteredUsers = [...this.users];
|
|
771
|
+
|
|
772
|
+
// Clear UI state in all filter components (icons/inputs)
|
|
773
|
+
if (this.filterComponents) {
|
|
774
|
+
this.filterComponents.forEach((filter: ColumnFilterComponent) => {
|
|
775
|
+
filter.clearFilter();
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// ✅ Send all backend filters to API
|
|
781
|
+
private sendAllBackendFiltersToBackend(): void {
|
|
782
|
+
const activeFilters: Array<{
|
|
783
|
+
field: string;
|
|
784
|
+
matchType: string;
|
|
785
|
+
value: string;
|
|
786
|
+
fieldType: string;
|
|
787
|
+
}> = [];
|
|
788
|
+
|
|
789
|
+
this.backendModeColumns.forEach(columnKey => {
|
|
790
|
+
const filterConfig = this.filters.get(columnKey);
|
|
791
|
+
if (filterConfig && filterConfig.rules.length > 0) {
|
|
792
|
+
filterConfig.rules.forEach(rule => {
|
|
793
|
+
if (rule.value && rule.value.trim() !== '') {
|
|
794
|
+
activeFilters.push({
|
|
795
|
+
field: columnKey,
|
|
796
|
+
matchType: rule.matchType,
|
|
797
|
+
value: rule.value.trim(),
|
|
798
|
+
fieldType: filterConfig.fieldType || 'text'
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
const payload = { activeFilters, count: activeFilters.length };
|
|
806
|
+
// Send to your backend API
|
|
807
|
+
console.log('Backend payload:', payload);
|
|
808
|
+
}
|
|
736
809
|
}
|
|
737
810
|
```
|
|
738
811
|
|
|
812
|
+
**✨ Key Benefits of This Approach:**
|
|
813
|
+
- ✅ **No separate functions per filter** - One `onFilterApplied()` handles all columns
|
|
814
|
+
- ✅ **Easy to add new filters** - Just add HTML, no new functions needed
|
|
815
|
+
- ✅ **Clean and maintainable** - Map-based storage, generic handlers
|
|
816
|
+
- ✅ **Backend mode support** - Configurable per column
|
|
817
|
+
- ✅ **Single source of truth** - All filters in one Map
|
|
818
|
+
|
|
739
819
|
## 📖 Documentation
|
|
740
820
|
|
|
741
821
|
### For Beginners:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ngx-column-filter-popup",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "A powerful, reusable Angular column filter component with support for multiple field types, advanced filtering rules, and customizable match modes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|