mercredi 12 août 2020

Angular filter doesn't filter every column only one at a time

INTRO

I'm trying to implement that my Angular column filter doesn't show my previously filtered results once I filter one column. More that it keeps on filtering results as I select more items in my column filters.

Let's say I select a name from my Name column and it filters fine (which it does), but as soon as I select a different column filter (let's say Project) it adds everyone else that's previously been filtered out and filters what I need (filters the Projects), same for Project Activity, and it just adds more and more items that are filtered but keeps the old filtered mess.

I just have no idea how to implement a mechanism that blocks the filter from adding wrong items to my filtered columns.

CODE

There are 5 columns in my HTML:

<mat-table #table [dataSource]="dataSource" matSort matSortActive="work_date" matSortDirection="asc">
            <ng-container matColumnDef="create_by">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
                <mat-cell *matCellDef="let log">  </mat-cell>
            </ng-container>

            <ng-container matColumnDef="project_id">
                <mat-header-cell ng-repeat="data in filtered = (list | filter: search)" *matHeaderCellDef
                    mat-sort-header>
                    Project ID </mat-header-cell>
                <mat-cell *matCellDef="let log">  </mat-cell>
            </ng-container>

            <ng-container matColumnDef="project_activity_id">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Project Activity ID </mat-header-cell>
                <mat-cell *matCellDef="let log">  </mat-cell>
            </ng-container>

            <ng-container matColumnDef="work_date">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Work date </mat-header-cell>
                <mat-cell *matCellDef="let log">  </mat-cell>
            </ng-container>

            <ng-container matColumnDef="hours">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Hours </mat-header-cell>
                <mat-cell *matCellDef="let log">  </mat-cell>
            </ng-container>

            <ng-container matColumnDef="minutes">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Minutes </mat-header-cell>
                <mat-cell *matCellDef="let log">  </mat-cell>
            </ng-container>

            <ng-container matColumnDef="notes">
                <mat-header-cell *matHeaderCellDef mat-sort-header> Additional notes </mat-header-cell>
                <mat-cell *matCellDef="let log">  </mat-cell>
            </ng-container>

            <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
            <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
        </mat-table>

And this would be my filter in the component, createFilter is the main focus where all the logic for filtering columns and main filter logic occurs.

filterChange(filter, event) {
    //let filterValues = {}

    if (this.hasFilter) {
      // second filter
      console.log("second filter");
      this.filterValues[filter.columnProp] = event.target.value.trim().toLowerCase().toString();
      console.log(this.filterValues);

      this.dataSource.filter = JSON.stringify(this.filterValues);
      console.log(this.dataSource.filter);

    } else {
      console.log("first filter");
      this.filterValues[filter.columnProp] = event.target.value.trim().toLowerCase().toString();
      console.log(this.filterValues);

      this.dataSource.filter = JSON.stringify(this.filterValues);
      console.log(this.dataSource.filter);
      this.hasFilter = true;
    }
  }

createFilter() {
    if (this.hasFilter) {
      // second filter - multi-layer filter

    } else {

      let filterFunction = function (data: any, filter: string): boolean {
        let searchTerms = JSON.parse(filter);
        let isFilterSet = false;
        for (const col in searchTerms) {
          console.log(searchTerms);
          console.log(col);
          if (searchTerms[col].toString() !== ' ') {
            isFilterSet = true;
          } else {
            delete searchTerms[col];
          }
        }

        console.log(searchTerms);

        let nameSearch = () => {
          let found = false;
          if (isFilterSet) {
            for (const col in searchTerms) {
              console.log(searchTerms[col]);

              if (searchTerms[col] == data[col].toString().toLowerCase() && isFilterSet) {
                found = true;
                console.log(this.nameSearch + " nameSearch");
                console.log(this.filterFunction + " filterFunction");
              } else {
                if (filterFunction == undefined) {
                  return found == true;
                }
              }
            }
            return found
          } else {
            return true;
          }
        }
        return nameSearch()
      }
      return filterFunction
    }
  }

My data source is my database and it connects absolutely fine with it, as well as filters one column at a time.

Aucun commentaire:

Enregistrer un commentaire