---
title: Paging in Dynamic Panel
product: Form Library
description: Learn how to enable paging in a SurveyJS Dynamic Panel to simplify navigation through long lists of entries. This demo for JavaScript shows how to set the maximum number of entries per page, track the current page, and get the total page count.
framework: Angular
source: https://surveyjs.io/form-library/examples/paging-in-dynamic-panel/angular
index: https://surveyjs.io/form-library/examples/overview.md
---

# Paging in Dynamic Panel (Angular)

Paging divides [Dynamic Panel](https://surveyjs.io/form-library/documentation/api-reference/dynamic-panel-model) entries into smaller groups so that respondents can work with long lists without scrolling through every panel. This demo displays 30 orders in a Dynamic Panel question. You can expand an order to edit its details.

> Paging is available in SurveyJS Form Library v3.2.2 and later.

## Enable Paging

You can enable paging by setting the question's [`pageSize`](/form-library/documentation/api-reference/dynamic-panel-model#pageSize) property to the number of panels per data page. The default value, `0`, disables paging. The effective page size is limited by the global [`settings.maxPageSize`](/form-library/documentation/api-reference/settings#maxPageSize) property. If you need to remove this limit, set the property to `0`.

In addition, you can use [`pageIndex`](/form-library/documentation/api-reference/dynamic-panel-model#pageIndex) to read or change the current data page index and [`pageCount`](/form-library/documentation/api-reference/dynamic-panel-model#pageCount) to access the total number of data pages.

This example displays five panels per page. You can switch between data pages using the navigation controls below the panels.

## See Also

[Demo: Paging in Matrices](/form-library/examples/paging-in-matrices/ (linkStyle))

## Files

### `src/app/components/json.ts`

```ts
export const json = {
  "showNavigationButtons": false,
  "pages": [
    {
      "name": "ordersPage",
      "elements": [
        {
          "type": "paneldynamic",
          "name": "orders",
          "title": "Orders (Dynamic Panel)",
          "description": "You can expand an order to edit its details and use the navigation controls below the panels to switch between data pages.",
          "pageSize": 5,
          "panelsState": "collapsed",
          "templateTitle": "Order #{panel.id}: {panel.customer}",
          "templateDescription": "{panel.product} × {panel.quantity}",
          "addPanelText": "Add order",
          "removePanelText": "Remove order",
          "templateElements": [
            {
              "type": "text",
              "name": "id",
              "title": "Order ID",
              "inputType": "number",
              "readOnly": true
            },
            {
              "type": "text",
              "name": "customer",
              "title": "Customer",
              "isRequired": true,
              "startWithNewLine": false
            },
            {
              "type": "dropdown",
              "name": "product",
              "title": "Product",
              "choices": [
                "Laptop",
                "Monitor",
                "Keyboard",
                "Mouse",
                "Headset",
                "Docking station",
                "Webcam",
                "Desk lamp",
                "Office chair",
                "USB-C cable"
              ]
            },
            {
              "type": "text",
              "name": "quantity",
              "title": "Quantity",
              "inputType": "number",
              "min": 1,
              "startWithNewLine": false
            },
            {
              "type": "text",
              "name": "price",
              "title": "Price",
              "inputType": "number",
              "min": 0
            },
            {
              "type": "expression",
              "name": "total",
              "title": "Total",
              "expression": "{panel.quantity} * {panel.price}",
              "displayStyle": "currency",
              "startWithNewLine": false
            },
            {
              "type": "dropdown",
              "name": "status",
              "title": "Status",
              "choices": [
                { "value": "new", "text": "New" },
                { "value": "processing", "text": "Processing" },
                { "value": "shipped", "text": "Shipped" },
                { "value": "delivered", "text": "Delivered" },
                { "value": "cancelled", "text": "Cancelled" }
              ]
            },
            {
              "type": "text",
              "name": "orderDate",
              "title": "Order date",
              "inputType": "date",
              "startWithNewLine": false
            }
          ]
        }
      ]
    }
  ]
}
;
```

### `src/app/components/survey.component.css`

```css
/* You can add your custom CSS here. */
```

### `src/app/components/survey.component.html`

```html
<survey [model]="model" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; height:100%"></survey>
```

### `src/app/components/survey.component.ts`

```ts
import { Component, OnInit } from "@angular/core";
import { Model } from "survey-core";
import { json } from "./json";
import "./survey.component.css";
import "survey-core/survey-core.min.css";

@Component({
    // tslint:disable-next-line:component-selector
    selector: "component-survey",
    templateUrl: "./survey.component.html",
    styleUrls: ["./survey.component.css"]
})
export class SurveyComponent implements OnInit {
    model: Model;
    ngOnInit() {
        const survey = new Model(json);
        const orders = [
          { id: 1001, customer: "Bob Brown", product: "Mouse", quantity: 4, price: 39, status: "shipped", orderDate: "2026-06-04" },
          { id: 1002, customer: "Grace Smith", product: "Laptop", quantity: 1, price: 1290, status: "delivered", orderDate: "2026-05-13" },
          { id: 1003, customer: "Quinn Smith", product: "USB-C cable", quantity: 2, price: 15, status: "shipped", orderDate: "2026-01-21" },
          { id: 1004, customer: "Elena Tanaka", product: "Monitor", quantity: 1, price: 340, status: "shipped", orderDate: "2026-06-02" },
          { id: 1005, customer: "Bob Rossi", product: "Monitor", quantity: 5, price: 340, status: "shipped", orderDate: "2026-06-16" },
          { id: 1006, customer: "Liam Garcia", product: "Laptop", quantity: 5, price: 1290, status: "shipped", orderDate: "2026-09-29" },
          { id: 1007, customer: "Sven Chen", product: "USB-C cable", quantity: 5, price: 15, status: "shipped", orderDate: "2026-09-03" },
          { id: 1008, customer: "Rosa Larsen", product: "Desk lamp", quantity: 2, price: 45, status: "delivered", orderDate: "2026-07-31" },
          { id: 1009, customer: "Noah Novak", product: "Mouse", quantity: 3, price: 39, status: "delivered", orderDate: "2026-01-09" },
          { id: 1010, customer: "Olga Petrova", product: "Webcam", quantity: 2, price: 89, status: "processing", orderDate: "2026-01-28" },
          { id: 1011, customer: "Ines Tanaka", product: "Laptop", quantity: 2, price: 1290, status: "new", orderDate: "2026-03-21" },
          { id: 1012, customer: "Tara Silva", product: "Docking station", quantity: 3, price: 219, status: "cancelled", orderDate: "2026-07-23" },
          { id: 1013, customer: "Liam Kowalski", product: "Monitor", quantity: 1, price: 340, status: "cancelled", orderDate: "2026-06-21" },
          { id: 1014, customer: "Pablo Ivanova", product: "Keyboard", quantity: 4, price: 79, status: "cancelled", orderDate: "2026-09-07" },
          { id: 1015, customer: "Noah Haddad", product: "Docking station", quantity: 1, price: 219, status: "shipped", orderDate: "2026-04-11" },
          { id: 1016, customer: "Ann Silva", product: "Monitor", quantity: 2, price: 340, status: "new", orderDate: "2026-05-02" },
          { id: 1017, customer: "Grace Müller", product: "Office chair", quantity: 2, price: 410, status: "delivered", orderDate: "2026-06-25" },
          { id: 1018, customer: "Elena Silva", product: "Webcam", quantity: 2, price: 89, status: "processing", orderDate: "2026-06-18" },
          { id: 1019, customer: "Dmitri Okafor", product: "Office chair", quantity: 3, price: 410, status: "new", orderDate: "2026-09-10" },
          { id: 1020, customer: "Mei Brown", product: "USB-C cable", quantity: 3, price: 15, status: "processing", orderDate: "2026-03-25" },
          { id: 1021, customer: "Sofia Martin", product: "Headset", quantity: 2, price: 119, status: "new", orderDate: "2026-09-11" },
          { id: 1022, customer: "Lucas Chen", product: "Laptop", quantity: 1, price: 1290, status: "processing", orderDate: "2026-09-12" },
          { id: 1023, customer: "Amira Hassan", product: "Desk lamp", quantity: 4, price: 45, status: "shipped", orderDate: "2026-09-14" },
          { id: 1024, customer: "Oscar Silva", product: "Keyboard", quantity: 3, price: 79, status: "delivered", orderDate: "2026-09-15" },
          { id: 1025, customer: "Hana Novak", product: "Monitor", quantity: 2, price: 340, status: "new", orderDate: "2026-09-16" },
          { id: 1026, customer: "Leo Rossi", product: "Webcam", quantity: 1, price: 89, status: "processing", orderDate: "2026-09-18" },
          { id: 1027, customer: "Maya Garcia", product: "Office chair", quantity: 3, price: 410, status: "shipped", orderDate: "2026-09-21" },
          { id: 1028, customer: "Ivan Larsen", product: "Docking station", quantity: 2, price: 219, status: "delivered", orderDate: "2026-09-23" },
          { id: 1029, customer: "Nina Tanaka", product: "Mouse", quantity: 5, price: 39, status: "cancelled", orderDate: "2026-09-24" },
          { id: 1030, customer: "Adam Kowalski", product: "USB-C cable", quantity: 4, price: 15, status: "processing", orderDate: "2026-09-28" }
        ];
        
        let nextOrderId = Math.max(...orders.map(order => order.id)) + 1;
        survey.onDynamicPanelAdded.add((_, options) => {
          if (options.question.name === "orders") {
            options.panel.getQuestionByName("id").value = nextOrderId++;
          }
        });
        
        survey.data = { orders: orders };
        
        survey.onComplete.add((sender, options) => {
            console.log(JSON.stringify(sender.data, null, 3));
        });
        this.model = survey;
    }
}
```

### `src/app/components/theme.ts`

```ts
export const themeJson = {};
```

### `src/app/app.component.css`

```css

```

### `src/app/app.component.html`

```html
<component-survey></component-survey>
```

### `src/app/app.component.ts`

```ts
import { Component } from "@angular/core";

@Component({
    selector: "app-root",
    templateUrl: "./app.component.html",
    styleUrls: ["./app.component.css"]
})
export class AppComponent {
    title = "CodeSandbox";
}
```

### `src/app/app.module.ts`

```ts
import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";

import { AppComponent } from "./app.component";
import { SurveyModule } from "survey-angular-ui";
import { SurveyComponent } from "./components/survey.component";

@NgModule({
    declarations: [AppComponent, SurveyComponent],
    imports: [BrowserModule, SurveyModule],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }
```

### `src/environments/environment.prod.ts`

```ts
export const environment = {
    production: true
};
```

### `src/environments/environment.ts`

```ts
// The file contents for the current environment will overwrite these during build.
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
// The list of which env maps to which file can be found in `.angular-cli.json`.

export const environment = {
    production: false
};
```

### `src/index.html`

```html
<link href="https://fonts.googleapis.com/css?family=Open%20Sans:400,600&display=swap" rel="stylesheet">
<app-root></app-root>
```

### `src/main.ts`

```ts
import { enableProdMode } from "@angular/core";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";

import { AppModule } from "./app/app.module";
import { environment } from "./environments/environment";

if (environment.production) {
    enableProdMode();
}

platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .catch(err => console.log(err));
```

### `src/polyfills.ts`

```ts
/**
 * This file includes polyfills needed by Angular and is loaded before the app.
 * You can add your own extra polyfills to this file.
 *
 * This file is divided into 2 sections:
 *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
 *   2. Application imports. Files imported after ZoneJS that should be loaded before your main
 *      file.
 *
 * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
 * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
 * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
 *
 * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
 */

/***************************************************************************************************
 * BROWSER POLYFILLS
 */

/** IE9, IE10 and IE11 requires all of the following polyfills. **/
// import 'core-js/es6/symbol';
// import 'core-js/es6/object';
// import 'core-js/es6/function';
// import 'core-js/es6/parse-int';
// import 'core-js/es6/parse-float';
// import 'core-js/es6/number';
// import 'core-js/es6/math';
// import 'core-js/es6/string';
// import 'core-js/es6/date';
// import 'core-js/es6/array';
// import 'core-js/es6/regexp';
// import 'core-js/es6/map';
// import 'core-js/es6/weak-map';
// import 'core-js/es6/set';

/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js';  // Run `npm install classlist.js`.

/** IE10 and IE11 requires the following for the Reflect API. */
// import 'core-js/es6/reflect';

/** Evergreen browsers require these. **/
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import "core-js/proposals/reflect-metadata";

/**
 * Required to support Web Animations `@angular/platform-browser/animations`.
 * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
 **/
// import 'web-animations-js';  // Run `npm install web-animations-js`.

/***************************************************************************************************
 * Zone JS is required by default for Angular itself.
 */
import "zone.js/dist/zone"; // Included with Angular CLI.

/***************************************************************************************************
 * APPLICATION IMPORTS
 */
```

### `src/styles.css`

```css
/* You can add your custom CSS here. */
```

### `src/typings.d.ts`

```ts
/* SystemJS module definition */
declare var module: NodeModule;
interface NodeModule {
    id: string;
}
```

### `.angular-cli.json`

```json
{
  "apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": [ "assets", "favicon.ico" ],
      "index": "index.html",
      "main": "main.ts",
      "polyfills": "polyfills.ts",
      "prefix": "app",
      "styles": [ "styles.css" ],
      "scripts": [ ],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ]
}
```

### `_tsconfig.json`

```json
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "allowSyntheticDefaultImports": true,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "resolveJsonModule": true,
    "target": "es2015",
    "module": "es2020",
    "lib": [
      "es2018",
      "dom"
    ]
  }
}
```

### `package.json`

```json
{
  "name": "surveyjs-angular",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --prod",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "14.1.1",
    "@angular/cdk": "14.1.1",
    "@angular/common": "14.1.1",
    "@angular/compiler": "14.1.1",
    "@angular/core": "14.1.1",
    "@angular/forms": "14.1.1",
    "@angular/platform-browser": "14.1.1",
    "@angular/platform-browser-dynamic": "14.1.1",
    "@angular/router": "14.1.1",
    "core-js": "3.6.4",
    "rxjs": "6.5.4",
    "survey-core": "latest",
    "survey-angular-ui": "latest",
    "tslib": "1.13.0",
    "zone.js": "0.11.7"
  },
  "devDependencies": {
    "@angular/cli": "1.6.6",
    "@angular/compiler-cli": "^5.2.0",
    "@angular/language-service": "^5.2.0",
    "@types/core-js": "0.9.46",
    "@types/jasmine": "~2.8.3",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "^4.0.1",
    "jasmine-core": "~2.8.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~2.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~4.1.0",
    "tslint": "~5.9.1",
    "typescript": "3.9.7"
  },
  "keywords": [ "angular", "surveyjs" ],
  "description": "SurveyJS-Angular example project"
}
```

## Other Frameworks

- [React](https://surveyjs.io/form-library/examples/paging-in-dynamic-panel/reactjs.md)
- [Vue 3](https://surveyjs.io/form-library/examples/paging-in-dynamic-panel/vue3js.md)
- [jQuery](https://surveyjs.io/form-library/examples/paging-in-dynamic-panel/jquery.md)
- [Vanilla JS](https://surveyjs.io/form-library/examples/paging-in-dynamic-panel/vanillajs.md)
