Reputation: 2366
I have a page:
<app-new-grid [isTotals]="false"></app-new-grid>
<hr>
<app-new-grid [isTotals]="true"></app-new-grid>
Which renders fine (with differences by checking the isTotals variable), and is a primeng table.
<p-table #dt [value]="data" [columns]="cols" dataKey="name"
[autoLayout]="true" sortMode="single" (sortFunction)="customSort($event)" [customSort]="true" (onFilter)="onFilter($event)">
...
Each grid has it's own dataset and is displayed correctly. However when I try to filter the first table, it is using the variables that were setup for the second table. Is this because of the #dt in the table declaration? How do I solve this?
Component:
import { Component, OnInit, Input } from '@angular/core';
import { } from '@angular/cdk/scrolling';
import { MyData } from './MyData-Interface';
import rawJson from '../../../assets/json/myData.json';
import { SelectItem } from 'primeng/api/selectitem';
import { FilterUtils } from 'primeng/utils';
import { SortEvent } from 'primeng/api/sortevent';
import { PercentPipe } from '@angular/common'
@Component({
selector: 'app-new-grid',
templateUrl: 'new-grid.component.html',
styleUrls: ['new-grid.component.scss']
})
export class MyDataNewGridComponent implements OnInit {
@Input() isTotals: boolean;
myData: MyData[];
pp: PercentPipe;
cols: any[];
classSelect: any[] = [];
classes: SelectItem[];
products: SelectItem[];
soldRangeValues: number[];
soldRangeMin: number;
soldRangeMax: number;
rowGroupMetadata = {};
groupingVar = 'name';
constructor() { }
ngOnInit(): void {
console.log(this.isTotals);
this.pp = new PercentPipe('en-US');
this.myData = <MyData[]>rawJson.filter(
detail => !this.isTotals ? detail.sortOrder < 5000 : detail.sortOrder > 5000);
this.fillMyData();
this.cols = [
{ field: 'name', header: 'Product' },
{ field: 'description', header: 'Class' }
];
var productNames = this.myData
.map(item => item.name)
.filter((value, index, self) => self.indexOf(value) === index);
this.products = productNames.map(item => ({ label: item, value: item }));
this.initializeRangeValues();
this.declareFilters();
this.updateRowGroupMetaData(this.myData);
}
private fillMyData() {
//Group by defined variable
var grouped = this.myData.reduce((g: any, person: MyData) => {
g[person[this.groupingVar]] = g[person[this.groupingVar]] || [];
g[person[this.groupingVar]].push(person);
return g;
}, {});
this.myData = [];
for (let key of Object.keys(grouped)) {
let entry = grouped[key] as MyData[];
//Check if we already have a subtotal
var temp = entry.map(item => item['description']).filter(x => x.toUpperCase().includes("TOTAL"));
if (temp.length === 0) {
var subTotal = {} as MyData;
subTotal.name = entry[0].name;
entry.push(subTotal);
}
for (let x of entry) {
this.myData.push(x);
}
}
}
declareFilters() {
FilterUtils['soldRangeFilter'] = (value, filter): boolean => {
return value >= this.soldRangeValues[0] && value <= this.soldRangeValues[1];
}
}
initializeRangeValues() {
let sold = this.getMinMax('sold');
this.soldRangeMin = sold[0];
this.soldRangeMax = sold[1];
this.soldRangeValues = [this.soldRangeMin, this.soldRangeMax];
}
onFilter(event) {
this.updateRowGroupMetaData(event.filteredValue);
}
updateRowGroupMetaData(data) {
this.rowGroupMetadata = {};
if (data) {
for (let i = 0; i < data.length; i++) {
let rowData = data[i];
let name = rowData.name;
if (i == 0) {
this.rowGroupMetadata[name] = { index: 0, size: 1 };
}
else {
let previousRowData = data[i - 1];
let previousRowGroup = previousRowData.name;
if (name === previousRowGroup)
this.rowGroupMetadata[name].size++;
else
this.rowGroupMetadata[name] = { index: i, size: 1 };
};
}
}
}
arraySum = function (items, prop) {
return items.reduce(function (a, b) {
return a + b[prop];
}, 0);
};
customSort(event: SortEvent) {
let map = new Map<string, number>(event.data
.filter(x => x.description.includes('Subtotal'))
.map(x => [x[this.groupingVar], x[event.field]]));
this.myData = event.data.slice()
.sort((a, b) => (map.get(a.name) - map.get(b.name)) * event.order);
this.updateRowGroupMetaData(this.myData);
}
getMinMax(field: string) {
let fieldSelect = this.myData.map(item => item[field]).filter(item => Number.isFinite(item));
fieldSelect = fieldSelect.sort((n1, n2) => n1 - n2);
return [fieldSelect[0], fieldSelect[fieldSelect.length - 1]];
}
}
Update:
So I figured out the problem was with my use of FilterUtils. If I change the declaration of the filters to be unique per grid:
declareFilters() {
FilterUtils['soldRangeFilter' + isTotals] = (value, filter): boolean => {
return value >= this.soldRangeValues[0] && value <= this.soldRangeValues[1];
}
}
then it works. Is there a cleaner way to make sure each grid has it's own instance of FilterUtils?
Upvotes: 2
Views: 2391
Reputation: 2366
So I figured out the problem was with my use of FilterUtils. If I change the declaration of the filters to be unique per grid:
declareFilters() {
FilterUtils['soldRangeFilter' + isTotals] = (value, filter): boolean => {
return value >= this.soldRangeValues[0] && value <= this.soldRangeValues[1];
}
}
then it works. Later versions of primeng changed FilterUtils to a service.
Upvotes: 0