1
votes

I am trying to create search functionality using an Angular material data table. I am using the default function for filtering the datatable which is in the Angular documentation.

What I am trying to do is, initially the table will not show any data, only after entering keywords in the search box, will the matched result be displayed.

My problem is that my table is first giving results correctly but upon second attempt to search it keeps flickering. I have taken my data from a json file. Should I use a Promise for it? Or is it because I can't use the default filter function like this to achieve this search functionality?

HTML:

    <div class="clear overflow-hidden">
      <div class="input-holder">
        <mat-form-field>
          <input matInput id="searchInput" placeholder="">
          <div class="green-box"><img alt="search" (click)="searchTable();" src="../../../assets/images/search-icon.png"></div>
        </mat-form-field>
    </div>
    </div>
    <div class="mat-elevation-z8">
      <mat-table #table [dataSource]="dataSource" matSort matSortActive="accountId" matSortDirection="asc">

        <!-- Id Column -->
        <ng-container matColumnDef="accountId">
          <mat-header-cell *matHeaderCellDef mat-sort-header>AccountId</mat-header-cell>
          <mat-cell *matCellDef="let record">{{record.accountId}}</mat-cell>
        </ng-container>

        <!-- Name Column -->
        <ng-container matColumnDef="name">
          <mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
          <mat-cell *matCellDef="let record">{{record.name}}</mat-cell>
        </ng-container>

        <ng-container matColumnDef="records">
          <mat-header-cell *matHeaderCellDef mat-sort-header>Number</mat-header-cell>
          <mat-cell *matCellDef="let record">{{record.records[0].accountNumber}}</mat-cell>
        </ng-container>

        <ng-container matColumnDef="price">
          <mat-header-cell *matHeaderCellDef mat-sort-header>Price</mat-header-cell>
          <mat-cell *matCellDef="let record">{{record.price}}</mat-cell>
        </ng-container>

        <!-- -->

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

      <!-- <mat-paginator #paginator
        [length]="dataSource.data.length"
        [pageIndex]="0"
        [pageSize]="50"
        [pageSizeOptions]="[25, 50, 100, 250]">
      </mat-paginator> -->
    </div>

Component:

    import { Component, OnInit, ViewChild } from '@angular/core';
    import { RecordsService } from '../../services/records.service';
    import { Observable } from 'Rxjs';
    import { MatSort, MatSortable, MatTableDataSource, MatSelectModule } from '@angular/material';
    import { Company } from '../../models/interfaces/company';

    @Component({
      selector: 'data-table',
      templateUrl: './data-table.component.html',
      styleUrls: ['./data-table.component.scss']
    })
    export class DataTableComponent implements OnInit {
      @ViewChild(MatSort) sort: MatSort;
      records: Array<any>;
      dataSource;

      displayedColumns = ['accountId', 'name', 'records', 'price'];

      applyFilter(filterValue: string) {
        filterValue = filterValue.trim();
        filterValue = filterValue.toLowerCase();
        this.dataSource.filter = filterValue;
      }

      constructor(private recService: RecordsService) {}
      ngOnInit() {
        this.loadTable();
      }

      loadTable() {
        this.recService.getResults().subscribe( results => {
          this.dataSource = new MatTableDataSource(results);
          this.dataSource.sort = this.sort;
        });
      }

      searchTable() {
        const query = (document.getElementById('searchInput') as HTMLInputElement).value;
          this.applyFilter(query);
      }
    }
1
I'm leaving this morning for mountain biking and don't have time to check your code but I have various kinds of searches with Mat Table here: stackblitz.com/edit/angular-material-table-with-multi-queriesPreston

1 Answers

0
votes

The first time you are searching from all data set of array but the second time you are searching from set of your first search.

So that is why it first time worked but broke on the second time.


So whenever you want to search make sure your table contains all the data you want.

-- Or simply you can implement it this way.

searchTable() {
      this.recService.getResults().subscribe( results => {
      this.dataSource = new MatTableDataSource(results);
      this.dataSource.sort = this.sort;
      const query = (document.getElementById('searchInput') as HTMLInputElement).value;
      this.applyFilter(query);
    });

  }

I hope this helps.

But I recommend you to implement a method in your service so that you can search the data with a keyword.