---
title: Progress Indicators
product: Form Library
description: Learn how to add progress indicators to your survey or form to show users how far along they are in the form or survey completion process, or use the indicators as jump links for easier navigation to a specific section of a form. View a free demo for JavaScript to learn more.
framework: Angular
source: https://surveyjs.io/form-library/examples/configure-form-navigation-with-progress-indicators/angular
index: https://surveyjs.io/form-library/examples/overview.md
---

# Progress Indicators (Angular)

A progress indicator, or progress bar, is a graphical element that visualizes the status of a particular task or process. Progress indicators provide visual cues that help respondents understand how far along they have advanced in your survey. SurveyJS Form Library ships with a progress bar that can show different types of progress information or allow users to switch survey pages.

## Display and Position the Progress Bar

To display the progress bar, enable the [`showProgressBar`](/form-library/documentation/api-reference/survey-data-model#showProgressBar) property. Use the [`progressBarLocation`](/form-library/documentation/api-reference/survey-data-model#progressBarLocation) property to position the progress bar within your survey. This property accepts the following values:

- `"aboveHeader"` - Displays the progress bar above the survey header.
- `"belowHeader"` - Displays the progress bar below the survey header. In this mode, the progress bar stays on top when users scroll the survey.
- `"bottom"` - Displays the progress bar below survey content.
- `"topBottom"` - Displays the progress bar above and below survey content.
- `"auto"` (default) - Automatically selects between `"aboveHeader"` and `"belowHeader"`.

In this demo, you can use the **Progress bar location** drop-down menu to switch between the positions.

## Specify Progress Information Type

You can also specify the information the progress bar displays: the number of completed pages, answered questions, answered required questions, or correct answers. To do this, set the [`progressBarType`](/form-library/documentation/api-reference/survey-data-model#progressBarType) property to one of the following values:

- `"pages"` (default)       
Indicates the number of completed pages and serves as a navigation element that respondents can use to jump between pages. You can also enable the [`progressBarShowPageNumbers`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#progressBarShowPageNumbers) and [`progressBarShowNavigationText`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#progressBarShowNavigationText) properties if you want to display page numbers, titles, and descriptions in the progress bar. Use a page's [`navigationTitle`](/form-library/documentation/api-reference/page-model#navigationTitle) and [`navigationDescription`](/form-library/documentation/api-reference/page-model#navigationDescription) properties to specify its title and description.
- `"questions"`     
Indicates The number of answered questions.
- `"requiredQuestions"`         
Indicates the number of answered [required questions](https://surveyjs.io/form-library/documentation/api-reference/question#isRequired).
- `"correctQuestions"`          
Indicates the number of correct questions in a [quiz](https://surveyjs.io/form-library/documentation/design-survey/create-a-quiz).

This demo allows you to switch between the `"pages"` and `"questions"` progress bar types at runtime using the **Progress bar type** drop-down menu.

## Files

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

```ts
export const json = {
  "showProgressBar": true,
  "progressBarLocation": "auto",
  "progressBarType": "pages",
  "progressBarShowPageNumbers": true,
  "progressBarShowNavigationText": true,
  "title": "Customer Satisfaction Survey",
  "pages": [{
    "navigationTitle": "Overall satisfaction",
    "elements": [{
      "type": "matrix",
      "name": "qualities",
      "title": "Please indicate if you agree or disagree with the following statements",
      "columns": [{
        "value": 5,
        "text": "Strongly agree"
      }, {
        "value": 4,
        "text": "Agree"
      }, {
        "value": 3,
        "text": "Neutral"
      }, {
        "value": 2,
        "text": "Disagree"
      }, {
        "value": 1,
        "text": "Strongly disagree"
      }],
      "rows": [{
        "value": "affordable",
        "text": "Product is affordable"
      }, {
        "value": "does-what-it-claims",
        "text": "Product does what it claims"
      }, {
        "value": "better-than-others",
        "text": "Product is better than other products on the market"
      },{
        "value": "easy-to-use",
        "text": "Product is easy to use"
      }]
    }, {
      "type": "rating",
      "name": "satisfaction-score",
      "title": "How satisfied are you with our product?",
      "minRateDescription": "Not satisfied",
      "maxRateDescription": "Completely satisfied"
    }, {
      "type": "rating",
      "name": "recommend",
      "visibleIf": "{satisfaction-score} > 3",
      "title": "How likely are you to recommend our product to a friend or co-worker?",
      "minRateDescription": "Will not recommend",
      "maxRateDescription": "I will recommend"
    }, {
      "type": "comment",
      "name": "suggestions",
      "title": "What would make you more satisfied with our product?"
    }]
  }, {
    "navigationTitle": "Pricing",
    "elements": [{
      "type": "radiogroup",
      "name": "price-comparison",
      "title": "Compared to our competitors, do you feel our product is:",
      "choices": [
        "Less expensive",
        "Priced about the same",
        "More expensive",
        "Not sure"
      ]
    }, {
      "type": "radiogroup",
      "name": "current-price",
      "title": "Do you feel our current price is merited by our product?",
      "choices": [
        "correct|Yes, the price is about right",
        "low|No, the price is too low for your product",
        "high|No, the price is too high for your product"
      ]
    }, {
      "type": "multipletext",
      "name": "price-limits",
      "title": "What is the highest and lowest price you would pay for a product like ours?",
      "items": [{
        "name": "highest",
        "title": "Highest"
      }, {
        "name": "lowest",
        "title": "Lowest"
      }]
    }]
  }, {
    "navigationTitle": "Contacts",
    "elements": [{
      "type": "text",
      "name": "email",
      "title": "Please leave your email address if you would like us to contact you."
    }]
  }]
};
```

### `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 { themeJson } from "./theme";
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);
        survey.applyTheme(themeJson);
        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 = {
  "themeName": "default",
  "colorPalette": "light",
  "isPanelless": false,
  "backgroundImage": "",
  "backgroundOpacity": 1,
  "backgroundImageAttachment": "scroll",
  "backgroundImageFit": "cover",
  "cssVariables": {
    "--sjs2-color-bg-basic-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-utility-property-grid": "rgba(255, 255, 255, 1)",
    "--sjs2-color-utility-tabs": "rgba(255, 255, 255, 1)",
    "--sjs2-color-utility-toolbox": "rgba(255, 255, 255, 1)",
    "--sjs2-color-bg-basic-primary-dim": "rgba(248, 248, 248, 1)",
    "--sjs2-color-bg-neutral-tertiary-dim": "rgba(243, 243, 243, 1)",
    "--sjs2-color-utility-surface-survey-panelless": "rgba(243, 243, 243, 1)",
    "--sjs2-color-utility-surface-survey": "rgba(243, 243, 243, 1)",
    "--sjs2-color-bg-basic-secondary": "rgba(249, 249, 249, 1)",
    "--sjs2-color-bg-basic-secondary-dim": "rgba(243, 243, 243, 1)",
    "--sjs2-color-fg-basic-primary": "rgba(0, 0, 0, 0.91)",
    "--sjs2-color-fg-basic-secondary": "rgba(0, 0, 0, 0.45)",
    "--sjs2-color-project-brand-600": "rgba(25, 179, 148, 1)",
    "--sjs2-color-bg-brand-secondary": "rgba(25, 179, 148, 0.1)",
    "--sjs2-color-bg-brand-primary-dim": "rgba(20, 164, 139, 1)",
    "--sjs2-color-fg-brand-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-fg-brand-primary-disabled": "rgba(255, 255, 255, 0.25)",
    "--sjs2-base-unit-size": "8px",
    "--sjs2-base-unit-spacing": "8px",
    "--sjs2-base-unit-radius": "4px",
    "--sjs2-color-bg-accent-primary": "rgba(255, 152, 20, 1)",
    "--sjs2-color-bg-accent-secondary": "rgba(255, 152, 20, 0.1)",
    "--sjs2-color-bg-accent-secondary-dim": "rgba(255, 152, 20, 0.25)",
    "--sjs2-color-fg-accent-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-fg-accent-primary-disabled": "rgba(255, 255, 255, 0.25)",
    "--sjs2-border-effect-surface-default": "0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
    "--sjs2-border-effect-floating-default": "0px 2px 6px 0px rgba(0, 0, 0, 0.1),0px 8px 16px 0px rgba(0, 0, 0, 0.1)",
    "--sjs2-border-effect-component-formbox-default": "inset 0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
    "--sjs2-border-effect-component-check-true-default": "inset 0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
    "--sjs2-border-effect-component-check-false-default": "inset 0px 1px 2px 0px rgba(0, 0, 0, 0.15)",
    "--sjs2-color-border-basic-secondary": "rgba(0, 0, 0, 0.09)",
    "--sjs2-color-component-input-default-line": "rgba(0, 0, 0, 0.16)",
    "--sjs2-color-border-basic-secondary-overlay": "rgba(0, 0, 0, 0.16)",
    "--sjs2-color-bg-alert-primary": "rgba(229, 10, 62, 1)",
    "--sjs2-color-bg-alert-secondary": "rgba(229, 10, 62, 0.1)",
    "--sjs2-color-fg-alert-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-bg-positive-primary": "rgba(25, 179, 148, 1)",
    "--sjs2-color-bg-positive-secondary": "rgba(25, 179, 148, 0.1)",
    "--sjs2-color-fg-positive-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-bg-note-primary": "rgba(67, 127, 217, 1)",
    "--sjs2-color-bg-note-secondary": "rgba(67, 127, 217, 0.1)",
    "--sjs2-color-fg-note-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-bg-warning-primary": "rgba(255, 152, 20, 1)",
    "--sjs2-color-bg-warning-secondary": "rgba(255, 152, 20, 0.1)",
    "--sjs2-color-fg-warning-on-primary": "rgba(255, 255, 255, 1)",
    "--sjs2-color-component-header-default-bg": "transparent",
    "--sjs2-typography-font-weight-component-header-title": "700",
    "--sjs2-typography-font-size-component-header-description": "20px",
    "--sjs2-typography-font-weight-component-page-title": "700"
  },
  "header": {
    "height": 50,
    "titlePositionX": "center",
    "titlePositionY": "middle"
  },
  "headerView": "advanced"
};
```

### `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
<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/configure-form-navigation-with-progress-indicators/reactjs.md)
- [Vue 3](https://surveyjs.io/form-library/examples/configure-form-navigation-with-progress-indicators/vue3js.md)
- [jQuery](https://surveyjs.io/form-library/examples/configure-form-navigation-with-progress-indicators/jquery.md)
- [Vanilla JS](https://surveyjs.io/form-library/examples/configure-form-navigation-with-progress-indicators/vanillajs.md)
