0

I am new to Angular 2 and Typescript and am working on a pager component that has been added to a component containing a table. The pager works fine, but I have two of these pagers one on top of the table and another below. When the next button on the first pager is clicked, I need to have both pagers move forward or backward so they are in sync. I've seen suggestions for using a shared service, but I am not sure if that would work since they are the same component.

How can I either trigger the unclicked button to also think it has been clicked, or simply mirror the behavior of the one pager component onto the other pager component? Does Angular 2 have a way of doing this?

Parent HTML:

<table-pager [(resort)]="resort" [recordPerPage]="recordPerPage" [totalItems]="totalItems" (onSetPage)="setPage($event)"></table-pager>
      <table class="uReportStandard" id="udfTable">
        <thead class="highlight-row">
         <tr>
          <th role="columnheader">Remove / Edit</th>
          <th *ngFor="let column of columns" role="columnheader" (click)="setSort(column)">
            {{column.name}}&nbsp;
            <img *ngIf="column.sortOrder == 'ASC'" src="./images/sort_asc.png" alt="Ascending" title="Ascending" class="tableIcon" />
            <img *ngIf="column.sortOrder == 'DESC'" src="./images/sort_desc.png" alt="Descending" title="Descending" class="tableIcon" />
          </th> 
        </tr>
        </thead>
        <tbody>
        <tr *ngFor="let udf of userDefinedField">
            <td class="tableIcons">
                <img src="./images/remove.png" alt="Remove" 
                (click)="deleteRow(udf.ID, 'Are you sure you want to remove the field: ' + udf.NAME)" 
                title="Remove" class="tableIcon" />
                <img src="./images/edit.png" alt="Edit" title="Edit" class="tableIcon" (click)="edit(udf.ID, udf.NAME, udf.DESCRIPTION)" />
            </td>
            <td>{{udf.ID}}</td>
            <td>{{udf.NAME}}</td>
            <td>{{udf.DESCRIPTION}}</td>
        </tr>
        </tbody>
      </table>
      <table-pager [(resort)]="resort" [recordPerPage]="recordPerPage" [totalItems]="totalItems" (onSetPage)="setPage($event)"></table-pager>

Pager Component:

export class PagerComponent implements OnInit, OnChanges  {

  @Input() recordPerPage: number;
  @Input() totalItems: number;
  @Input() resort: boolean = false;

  @Output() onSetPage: EventEmitter<any> = new EventEmitter<any>();

  totalPages: number;
  startIndex: number;
  endIndex: number;   
  currentPage: number;

  constructor() { }

  ngOnInit() {}

  ngOnChanges(changes: any) {
    console.log('OnChange called');
    //get total pages count  
    let pagesCount =  this.totalItems / this.recordPerPage;
    //If there is a remainder then add one to the page  
    if((this.totalItems % this.recordPerPage) > 0){
          pagesCount = pagesCount + 1;
    }

    this.resort = false;
    this.totalPages =  pagesCount;
    this.setPage(1, null);
  }


  setPage(page: number, direction: string = null) {
    if(direction === 'previous') {
        if (this.startIndex <= 1) {
            console.log('On the starting page');
            return;
        }
    } else if (direction === 'next') {
        if (this.totalItems === this.endIndex) {
            console.log('On the last page');
            return;
        }
    } else if (page < 1) {
        console.log("Invalid page number.");
        //callback
        //this.onSetPage.emit(0);
        return;
    }

    this.currentPage = page;
    this.startIndex = 1 + (page-1)*this.recordPerPage;
    this.endIndex = this.startIndex + +this.recordPerPage - 1;
    if(this.endIndex > this.totalItems) {
        this.endIndex = this.totalItems;
    }
    let resortHolder = this.resort;

    //callback
    this.onSetPage.emit({page, resortHolder});  
  }

Pager HTML:

<div *ngIf="totalItems == 0">
    <p>No records found</p>
</div>
<div *ngIf="totalPages >= 2" class="pagination">
    <span [ngClass]="{disabled:currentPage == 1}" (click)="setPage(currentPage - 1, 'previous')">
          <img src="./images/previous.png" alt="Previous" title="Previous" class="tableIcon" />
        Previous
    </span>
    <span>{{startIndex}} - {{endIndex}} of {{totalItems}}
    </span>
    <span [ngClass]="{disabled:endIndex == totalItems}" (click)="setPage(currentPage + 1, 'next')">
        Next
        <img src="./images/next.png" alt="Next" title="next" class="tableIcon"/>
    </span>          
</div>
Micheal
  • 3
  • 2
  • One solution is as you mentioned to use a service. You could also use the @Input, for more information take a look at this [Documentation](https://angular.io/docs/ts/latest/cookbook/component-communication.html) – Ploppy Mar 27 '17 at 23:57

1 Answers1

0

If you don't want to use a shared service an alternative is you could have the two pager components communicate via @Output events e.g. 'next clicked', see this related question

<table-pager #firstPager (nextClicked)="secondPager.clickNext($event)"></table-pager>
// the table html ..
<table-pager #secondPager (nextClicked)="firstPage.clickNext($event)"></table-pager>

Another (simpler?) way would be to change the template of you pager component so that the pager component displays a 'top' and 'bottom' pager, and use content project to place the table between them:

Pager html template:

<!-- Top pager -->
<div *ngIf="totalPages >= 2" class="pagination">
    <span [ngClass]="{disabled:currentPage == 1}" (click)="setPage(currentPage - 1, 'previous')">
          <img src="./images/previous.png" alt="Previous" title="Previous" class="tableIcon" />
        Previous
    </span>
    <span>{{startIndex}} - {{endIndex}} of {{totalItems}}
    </span>
    <span [ngClass]="{disabled:endIndex == totalItems}" (click)="setPage(currentPage + 1, 'next')">
        Next
        <img src="./images/next.png" alt="Next" title="next" class="tableIcon"/>
    </span>          
</div>

<!-- Content projected here -->
<ng-content></ng-content> 

<!-- Below pager -->
<div *ngIf="totalPages >= 2" class="pagination">
    <span [ngClass]="{disabled:currentPage == 1}" (click)="setPage(currentPage - 1, 'previous')">
          <img src="./images/previous.png" alt="Previous" title="Previous" class="tableIcon" />
        Previous
    </span>
    <span>{{startIndex}} - {{endIndex}} of {{totalItems}}
    </span>
    <span [ngClass]="{disabled:endIndex == totalItems}" (click)="setPage(currentPage + 1, 'next')">
        Next
        <img src="./images/next.png" alt="Next" title="next" class="tableIcon"/>
    </span>          
</div>

And the parent template:

<table-pager [(resort)]="resort" [recordPerPage]="recordPerPage" [totalItems]="totalItems" (onSetPage)="setPage($event)">
    <table> .. your table definition ... </table>
</table-pager>
Community
  • 1
  • 1
Garth Mason
  • 7,611
  • 3
  • 30
  • 39