Kostas_Me_
Kostas_Me_

Reputation: 113

How to search all the data in Angular 8 with pagination used

Goodmorning to everyone!!

I'm building an app in Angular 8 which displays a table with some data from the database. It includes a search box and a pagination component. I'm using the packages "Ng2SearchPipeModule" and "JwPaginationComponent".

When I have pagination disabled, search function works fine. But when I have pagination enabled, only the few displayed entries are being searched and not all of them.

Is there a trick to bypass this problem?? Thank you in advance for your help!

app.component.html

<input type="text" name="search" [(ngModel)]="searchText" autocomplete="off" placeholder="Search...">

<table>
   <tr *ngFor="let entry of pageOfEntries | filter:searchText">
      <th>{{ entry.asset }}</th>
      <th>{{ entry.model }}</th>
      <th>{{ entry.serial }}</th>
      <th>{{ entry.ip }}</th>
      <th>{{ entry.notes }}</th>
   </tr>
</table>

<jw-pagination [items]="entries" (changePage)="onChangePage($event)"></jw-pagination>

app.component.ts

searchText: string = '';
entries: Entry[] = [];
pageOfEntries: Array<any>;

onChangePage(pageOfEntries: Array<any>) {
   // update current page of items
   this.pageOfEntries = pageOfEntries;
}

Upvotes: 0

Views: 7184

Answers (3)

Kostas_Me_
Kostas_Me_

Reputation: 113

After some tries, I came up with the following solution:

I'm going to use the same div two times. The first one implements pagination while the other does not.

When the user doesn't search for something and the search input field is empty (searchText == ''), the results are a lot, so pagination has to be implemented.

<div *ngIf="searchText == ''">
   <table>
      <tr *ngFor="let entry of pageOfEntries">
         <th>{{ entry.asset }}</th>
         <th>{{ entry.model }}</th>
         <th>{{ entry.serial }}</th>
         <th>{{ entry.ip }}</th>
         <th>{{ entry.notes }}</th>
      </tr>
   </table>
   <jw-pagination [items]="entries" (changePage)="onChangePage($event)"></jw-pagination>
</div>

On the other hand, if the user searches for something, I need all entries to be searched. In order to do that, it is necessary pagination be disabled.

<div *ngIf="searchText != ''">
   <table>
      <tr *ngFor="let entry of entries | filter: searchText">
         <th>{{ entry.asset }}</th>
         <th>{{ entry.model }}</th>
         <th>{{ entry.serial }}</th>
         <th>{{ entry.ip }}</th>
         <th>{{ entry.notes }}</th>
      </tr>
   </table>
</div>

The problem from the beginning was located at the *ngFor="let entry of entries | filter:searchText". The string searchText is the user's search input and the entries are all the data from the database. So the keyword saved in the "searchText" is being searched across all the "entries".

With Pagination, entries had to be replaced from the pageOfEntries, which were the 10 displayed entries. So the problem was that only these 10 entries were being searched.

Upvotes: 0

Sher Singh
Sher Singh

Reputation: 545

 onChangePage(pageOfItems: Array) {
        // update current page of items
        this.pageOfItems = pageOfItems;
    }
**After this you have to try below.**

import { EventEmitter, OnInit, OnChanges, Component, Input, Output } from @angular/core';
import {paginate} from 'jw-paginate';

@Component({
  moduleId: module.id,
  selector: 'jw-pagination',
  template: `

      First


      Previous


      {{page}}


      Next


      Last

`
})

export class JwPaginationComponent implements OnInit, OnChanges {
  @Input() items: Array;
  @Output() changePage = new EventEmitter(true);
  @Input() initialPage = 1;
  @Input() pageSize = 10;
  @Input() maxPages = 10;

  pager: any = {};

  ngOnInit() {
    //if items array is not empty
    if (this.items && this.items.length) {
      this.setGridPage(this.initialPage);
    }
  }

  ngOnChanges(changes: SimpleChanges) {
    // Reset page if the items array has been changed
    if (changes.items.currentValue !== changes.items.previousValue) {
      this.setGridPage(this.initialPage);
    }
  }

  private setGridPage(page: number) {
    // get data base on page number
    this.pager = paginate(this.items.length, page, this.pageSize, this.maxPages);
    var pageOfItems = this.items.slice(this.pager.startIndex, this.pager.endIndex + 1);
    this.changePage.emit(pageOfItems);
  }
}

Upvotes: 1

Antonio Rossi
Antonio Rossi

Reputation: 61

With this limited amount of info it's not easy to debug the issue. However, my way of thinking would be the following:

when the component load and entry is equal to the full list, you could store it on a different variable (let's call it totalEntry for now). When you do the search, instead of searching on entry, you can search on totalEntry and display that array instead.

Upvotes: 0

Related Questions