Click here to Skip to main content
14,022,571 members
Click here to Skip to main content
Add your own
alternative version

Stats

55.6K views
18 bookmarked
Posted 6 Nov 2016
Licenced CPOL

Table pagination with Search bar in Angular2

, 16 Jan 2017
Rate this:
Please Sign up or sign in to vote.
step by step you will learn how to create a table pagination and search bar using Angular2

Introduction

Through this article, you will learn using Angular2:

  • how you can create a table with pagination
  • how you can implement a search bar to filter the content of table.

Background

To better understand this article , it is preferable that you have a good knowledge’s on:

  • Data Binding
  • TypeScript
  • Angular2

Using the Code

A) Prerequisite

Before you start coding, I recommend you to download Angular2 template from Angular 2 website: Angular2 Quick Start.

When you run the cmd tree command you should find the below folders tree :

B) Build Application

To constitute, this example you should first create Typescript classes that build the pagination and search logic.

**) Angular2 typescript classes

This section will describe steps that I follow to build the core of application in Typescript:

Create Product.ts

This class contains a list of attributes that describes a product object. it will be used to define an item on the 'productList' array.

export class Product {
   constructor(
    public id : number,    
    public name : string,    
    public description : string
   ){

   }
}

Create Data.ts

This file contains a declaration and the initialization of a JSON array named ‘productList’ that will be used after to populate the Product List table in the HTML view.

productList’ is an array of Product, that’s why we do the import of ‘Person’ class.

import {Product} from './Product';
export var productList: Product[] = [
  {"id": 1, "name": "juice 1", "description": "description 1"},
  {"id": 2, "name": "juice 2", "description": "description 2"},
  {"id": 3, "name": "juice 3", "description": "description 3"},
  {"id": 4, "name": "juice 4", "description": "description 4"},
  {"id": 5, "name": "juice 5", "description": "description 5"},
  {"id": 6, "name": "juice 6", "description": "description 6"},
  {"id": 7, "name": "juice 7", "description": "description 7"},
  {"id": 8, "name": "juice 8", "description": "description 8"},
  {"id": 9, "name": "juice 9", "description": "description 9"},
  {"id": 10, "name": "orange 1", "description": "description 1"},
  {"id": 11, "name": "orange 2", "description": "description 2"},
  {"id": 12, "name": "orange 3", "description": "description 3"},
  {"id": 13, "name": "orange 4", "description": "description 4"},
  {"id": 14, "name": "orange 5", "description": "description 5"},
  {"id": 15, "name": "orange 6", "description": "description 6"},
  {"id": 16, "name": "orange 7", "description": "description 7"},
  {"id": 17, "name": "orange 8", "description": "description 8"},
  {"id": 18, "name": "orange 9", "description": "description 9"},
  {"id": 19, "name": "orange 10", "description": "description 10"},
  {"id": 20, "name": "orange 11", "description": "description 11"},
  {"id": 21, "name": "orange 12", "description": "description 12"},
  {"id": 22, "name": "orange 13", "description": "description 13"},
  {"id": 23, "name": "orange 14", "description": "description 14"},
  {"id": 24, "name": "orange 15", "description": "description 15"},
  {"id": 25, "name": "orange 16", "description": "description 16"},
  {"id": 26, "name": "orange 17", "description": "description 17"},
]

Create app.paginationComponent.ts

This the main class, it disposes of the HTML template with the required binding, also the implementation of the pagination and search logic.

First you need to import the needed *.ts classes to build the Pagination class.

Pagination class will contain attributes and functions that constitute entries of Product Table, pagination and search input. Also it will handle events received from user interface thanks to binding.

To implement the pagination and filter system, I used these:

  • filteredItems attribute: is an array of ‘Product’ used to stock the result of the search process executed by ‘FilterByName’ function.
  • pageSize attribute : indicate the number of entries per page,
  • pages : is a maximum of Page numbers that can be displayed in pagination bar (it’s the size of ‘pagesIndex’ array).
  • pageNumber attribute : is the maximum number of page can we deduce from the ‘ProductList’ in terms of ‘pageSize’ value,
  • currentIndex attribute : is the index of the current selected page,
  • items attribute : the content of selected page,
  • pagesIndex attribute : have the series of numbers shown in the pagination bar.
  • pageStart attribute : this the start index page in the pagination bar.
  • inputName attribute : is used to search a new list of Product which the value of the attribute name for each one contains the text in ‘inputName’ .
  • Constructor method : initialize the ‘filterditems’ from ‘ProductList’, and the pagination.
  • Init method : used to calculate the pagination values, and update the view screen.
  • FilterByName method : this function return a list of Products which the text in ‘inputName’ is a substring of the Product name. The result will be inserted in ‘filteredItems’ List.
  • refreshItems method : refresh the content of table depending mainly on values of the following attributes : ‘currentIndex’ , ‘pageSize’ , 'pages' and 'pageStart' .
  • prevPage method : this function will decrease the selected page index (‘currentIndex’) by one, and will refresh the display.
  • nextPage method : this function will increase the selected page index (‘currentIndex’) by one, and will refresh the display.
  • setPage method : invoked when user select a number from pagination. It will modify the ‘currentIndex’ value and refresh the view.
import { Component, NgModule } from '@angular/core';

import {Product} from './Product';
import {productList} from './data';
@Component({
 selector: 'my-pagination',
 template: ` 
   <div class="form-group">
         <label>Filter </label>
         <input  type="text"  id="inputName" [(ngModel)]="inputName"/>
         <input type="button" (click)="FilterByName()" value="Apply"/>
   </div>
   <div class='row'>
    <div class="panel panel-default">
    <!-- Default panel contents -->
    <div class='panel-heading'>Product List</div>
    <div class='panel-body'>
         <table class="table table-bordered table-condensed ">
            <thead>
               <th>Id</th>
               <th>Name</th>
               <th>Description</th>
            </thead>
            <tbody>
               <tr *ngFor="let item of items">
                  <td>{{item.id}}</td>
                  <td>{{item.name}}</td>
                  <td>{{item.description}}</td>
               </tr>
            </tbody>
         </table>
         <div class="btn-toolbar" role="toolbar" style="margin: 0;">
          <div class="btn-group">
               <label style="margin-top:10px">Page {{currentIndex}}/{{pageNumber}}</label>
            </div>
            <div class="btn-group pull-right">
               <ul class="pagination" >
                  <li [ngClass]="{'disabled': (currentIndex == 1 || pageNumber == 0)}" ><a  (click)="prevPage()" href="#">Prev</a></li>
                     <li *ngFor="let page of pagesIndex"  [ngClass]="{'active': (currentIndex == page)}">
                        <a (click)="setPage(page)" href="#" >{{page}}</a>
                     </li>
                  <li [ngClass]="{'disabled': (currentIndex == pageNumber || pageNumber == 0)}" ><a   (click)="nextPage()" href="#">Next</a></li>
               </ul>
            </div>
         </div>
      </div>
   </div>   
  `,
 styles: ['.pagination { margin: 0px !important; }']
})
export class Pagination {

   filteredItems : Product[];
   pages : number = 4;
  pageSize : number = 5;
   pageNumber : number = 0;
   currentIndex : number = 1;
   items: Product[];
   pagesIndex : Array<number>;
   pageStart : number = 1;
   inputName : string = '';

   constructor( ){
         this.filteredItems = productList;
       this.init();
   };
   init(){
         this.currentIndex = 1;
         this.pageStart = 1;
         this.pages = 4;

         this.pageNumber = parseInt(""+ (this.filteredItems.length / this.pageSize));
         if(this.filteredItems.length % this.pageSize != 0){
            this.pageNumber ++;
         }
    
         if(this.pageNumber  < this.pages){

               this.pages =  this.pageNumber;

         }

       

         this.refreshItems();

         console.log("this.pageNumber :  "+this.pageNumber);

   }



   FilterByName(){

      this.filteredItems = [];

      if(this.inputName != ""){

            productList.forEach(element => {
                if(element.name.toUpperCase().indexOf(this.inputName.toUpperCase())>=0){
                  this.filteredItems.push(element);
               }
            });
      }else{
         this.filteredItems = productList;
      }
      console.log(this.filteredItems);
      this.init();
   }
   fillArray(): any{
      var obj = new Array();
      for(var index = this.pageStart; index< this.pageStart + this.pages; index ++) {

                  obj.push(index);

      }

      return obj;

   }

 refreshItems(){

               this.items = this.filteredItems.slice((this.currentIndex - 1)*this.pageSize, (this.currentIndex) * this.pageSize);

               this.pagesIndex =  this.fillArray();

   }

   prevPage(){

      if(this.currentIndex>1){
         this.currentIndex --;
      } 
      if(this.currentIndex < this.pageStart){

         this.pageStart = this.currentIndex;

      }

      this.refreshItems();

   }

   nextPage(){

      if(this.currentIndex < this.pageNumber){

            this.currentIndex ++;

      }

      if(this.currentIndex >= (this.pageStart + this.pages)){
         this.pageStart = this.currentIndex - this.pages + 1;
      }
 
      this.refreshItems();
   }
    setPage(index : number){
         this.currentIndex = index;
         this.refreshItems();
    }

 }

Update app.module.ts

You should update this file to import the Pagination component in order to be visible from index.html.

import { NgModule} from '@angular/core';
import { FormsModule }   from '@angular/forms';
import { BrowserModule} from '@angular/platform-browser';
import { Pagination}   from './app.paginationComponent';

@NgModule({
  imports:      [ BrowserModule,FormsModule ],
  declarations: [ Pagination],
  bootstrap:    [ Pagination]
})
export class AppModule { }

Create index.html

This a HTML page, in which we will include all required js files and css styles to run the pagination component.

<html>
  <head>
    <title>Angular QuickStart</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="./css/styles.css">
    <link rel="stylesheet" href="./css/bootstrap.css">
    <!-- 1. Load libraries -->
     <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/core-js/client/shim.min.js"></script>
    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <!-- 2. Configure SystemJS -->
    <script src="systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
       
    </script>
  </head>
  <!-- 3. Display the application -->
  <body>
    <div class="container">
      <div class=" row">
        <h3>Angular2 : Table Pagination with search bar</h3>
      </div>
       <br>
      <div class=" row">
        <div class="col col-lg-6">
          <my-pagination>Loading...</my-pagination>
        </div> 
      </div>
    </div>
  </body>
</html>

**) Run the demo :

To run the Angular2 application, you should write the following cmd command-line in the root folder of your application :

  • npm install : to install required modules (optionnal).
  • npm start : to start the build of application.

Finally, if the demo run successfully, you should get the following render :

If user select a page number from pagination bar, than the display will be as follow:

If user enter 'Orange' text into the search bar and click on 'Apply' button, the search process will give:

References

Points of Interest

I hope that you appreciated this post. Try to download the source code and i'm waiting for your questions and comments.

History

  • v1 06/11/2016 : Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

O.Nasri
Engineer
France France
Microsoft certified professional in C# ,HTML 5 & CSS3 and JavaScript, Asp.net, and Microsoft Azure.

You may also be interested in...

Comments and Discussions

 
QuestionWhat about live data? Pin
Member 165621430-Jul-17 15:52
memberMember 165621430-Jul-17 15:52 
AnswerRe: What about live data? Pin
O.Nasri6-Nov-17 8:55
professionalO.Nasri6-Nov-17 8:55 
QuestionNice Solution for startup but scroll position changes when pagination Pin
shrikantsavalkar18-Jul-17 1:45
membershrikantsavalkar18-Jul-17 1:45 
AnswerRe: Nice Solution for startup but scroll position changes when pagination Pin
shrikantsavalkar19-Jul-17 1:14
membershrikantsavalkar19-Jul-17 1:14 
Questionpagination issues Pin
Member 1285742417-Nov-16 20:56
memberMember 1285742417-Nov-16 20:56 
PraiseMy vote of 5 Pin
Member 128287828-Nov-16 7:21
memberMember 128287828-Nov-16 7:21 
GeneralMy vote of 1 Pin
Jean-Pierre Bachmann8-Nov-16 2:09
professionalJean-Pierre Bachmann8-Nov-16 2:09 
QuestionThoughts Pin
Nelek6-Nov-16 20:58
protectorNelek6-Nov-16 20:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03 | 2.8.190417.4 | Last Updated 16 Jan 2017
Article Copyright 2016 by O.Nasri
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid