Create a pagination form with Angular-Part 1

Anil Amarakoon
5 min readOct 5, 2018

--

In Part 1, I will show you how to create a multi page Angular form quickly using the Angular material mat-paginator.

My requirement is to create paging on form quickly, and I wanted to use an Angular template to set up my form fields. In the next article I will create a component that can handle paging. In the core, what I’m doing is hiding form fields by page number. Going with four items per page, this component displays the first four fields and hides other form fields if the selected page is one. On page two, it hides the first four form fields and displays form fields five to eight.

  • The initial form without paging is below. It’s too long for a cell phone.
Form without paging
  • Form with paging
Paged form. Four items per page.
Last page. Enables submit button. Four fields per page
Five fields per change.
  • Form with paging. Change items per page

Let’s create an angular material project.

$ ng new try-paging

$ cd try-paging

ng add @angular/material

$ ng g component page-form

Let’s start with a template first. I have eleven fields. Let’s assume that we get the initial field values as json.

page-form.component

<mat-toolbar color="primary">
<span>Pagable form - Part 1</span>
</mat-toolbar><mat-card>
<!-- Title of an Card -->
<mat-card-title>
<mat-paginator #paginator
[length]="length"
[pageSize]="pageSize"
[pageSizeOptions]="pageSizeOptions"
(page)="pageEvent($event)"
[hidePageSize]="hidePageSize"
[showFirstLastButtons]="showFirstLastButtons"
class="mat-paginator-container">
</mat-paginator>
</mat-card-title><mat-card-content><form [formGroup]="myForm"><mat-form-field [hidden]="formData[0].display == true"> <input matInput #dataValue0
placeholder="Last Name"
formControlName="dataValue0" required>
</mat-form-field>
<p><mat-form-field [hidden]="formData[1].display == true"> <input matInput
placeholder="First Name"
formControlName="dataValue1" required>
</mat-form-field>
<p><mat-form-field [hidden]="formData[2].display == true"> <input matInput
placeholder="Address 1"
formControlName="dataValue2" >
</mat-form-field>
<p><mat-form-field [hidden]="formData[3].display == true"> <input matInput
placeholder="Address 2"
formControlName="dataValue3" >
</mat-form-field>
<p><mat-form-field [hidden]="formData[4].display == true">

<input matInput
placeholder="City"
formControlName="dataValue4" required>
</mat-form-field>
<p><mat-form-field [hidden]="formData[5].display == true">

<input matInput
placeholder="Province"
formControlName="dataValue5" >
</mat-form-field>
<p><mat-form-field [hidden]="formData[6].display == true"> <input matInput
placeholder="Postal code"
formControlName="dataValue6" >
</mat-form-field>
<p><mat-form-field [hidden]="formData[7].display == true"> <input matInput placeholder="Phone cell"
formControlName="dataValue7" required>
</mat-form-field>
<p><mat-form-field class="full-width" [hidden]="formData[8].display == true">
<input matInput placeholder="Phone home" formControlName="dataValue8" >
</mat-form-field>
<p><mat-form-field [hidden]="formData[9].display == true"> <input matInput
placeholder="Direction"
formControlName="dataValue9">
</mat-form-field>
<p><mat-form-field [hidden]="formData[10].display == true"> <input matInput
placeholder="Country"
formControlName="dataValue10" >
</mat-form-field>
</form>
<!--
use <div *ngIf="isLastPage" class="submit-style">
if you want to hide button
-->
<div class="submit-style">
<button mat-raised-button color="primary"
[disabled]="!isLastPage"
(click)="submitExecuted()" >
Submit
</button>
</div></mat-card-content>
</mat-card>

page-form.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { MatPaginator } from '@angular/material';
export interface FormData {
name: string;
page: number;
display: boolean;
}
@Component({
selector: 'app-page-form',
templateUrl: './page-form.component.html',
styleUrls: ['./page-form.component.css']
})
export class PageFormComponent implements OnInit {
//Form variables
myForm: FormGroup;
//Pagination variables
@ViewChild(MatPaginator) paginator: MatPaginator;
length: number;
//initial page size
pageSize: number = 4;
pageSizeOptions: number[] = [2, 3, 4, 5];
hidePageSize: boolean = false;
showFirstLastButtons: boolean = false;
//initial page index. starts from zero
pageIndex: number = 0;
//helpers
//formData holds field name, page number of field
//and display ( true/false)
formData: FormData[] = [];
isLastPage: boolean = false;formValues = {
dataValue0: 'field0',
dataValue1: 'field1',
dataValue2: 'field2',
dataValue3: 'field3',
dataValue4: 'field4',
dataValue5: 'field5',
dataValue6: 'field6',
dataValue7: 'field7',
dataValue8: 'field8',
dataValue9: 'field9',
dataValue10: 'field10'
};
constructor(private fb: FormBuilder) {
//create FormGroup
this.myForm = this.fb.group(this.formValues);
}/**
* populate FormData[] with each form field.
* set record length
* sets field to display / hide flag
*/
ngOnInit() {
let indexNo = 0;
let pageNo = 0;
let i = 0;
for (var prop in this.formValues) { this.formData.push(this.createFormData(prop, pageNo));
indexNo++;
i++;
//increment page number
if (indexNo >= this.pageSize) {
indexNo = 0;
pageNo++;
}
}
this.length = i;
this.setPageFormFieldPaging(this.pageIndex, this.pageSize);
}
/** create FormData object */
createFormData(prop: string, pageNumber: number):FormData {
const item: FormData = { name: prop, page: pageNumber,
display: true };
return item;
}
/* set Form field to display / hide value */
setPageFormFieldPaging(pageIndex: number, pageSize: number) {
let lowerBound: number = ((pageIndex + 1) * pageSize) -
pageSize;

let upperBound: number = ((pageIndex + 1) * pageSize) - 1;
this.formData.forEach((item, index) => {
item.display = true;
if (index >= lowerBound && index <= upperBound) {
item.display = false;
}
});
}
//** helper method to set page size options */
setPageSizeOptions(setPageSizeOptionsInput: string) {
this.pageSizeOptions =
setPageSizeOptionsInput.split(',').map(str => +str);
}
pageEvent($event) {this.pageSize = $event.pageSize;
this.pageIndex = $event.pageIndex;
this.setPageFormFieldPaging(this.pageIndex, this.pageSize);
this.isLastPage = !this.paginator.hasNextPage();
}
submitExecuted() {
console.log("submit executed " + this.isLastPage);
}
}

formData array holds reference to each field.

Following are the initial data for Angular material paginator.

You can change pageSize by selecting items/page drop down.

length: number;
pageSize: number = 4;
pageSizeOptions: number[] = [2, 3, 4, 5];
hidePageSize: boolean = false;
showFirstLastButtons: boolean = false;

Here is the link to Angular Material Paginator.

page-form.component.css

.mat-paginator-container {
flex: 0 0 auto;
diplay:inline;
float: left;
}
mat-form-field[hidden] {
display: none;
}
.mat-paginator-range-label {
display:none !important;
background: blue;
display: inline;
}
form {
padding: 40px;
}
.nonFooter{
min-height: 100%;
position:relative;
/* Firefox */
min-height: -moz-calc(100% - 100px);
/* WebKit */
min-height: -webkit-calc(100% - 100px);
/* Opera */
min-height: -o-calc(100% - 100px);
/* Standard */
min-height: calc(100% - 100px);
margin-left: 20px;
}

This post may help you to get paging in form going quickly.

--

--

Anil Amarakoon

Senior software developer — Full stack, lives in Winnipeg, Manitoba, Canada