---
title: Customize the Tab Bar
product: Survey Creator
description: With SurveyJS you can easily modify the tab bar to make it more convenient for your end users. For example, you can hide or show the existing tabs, remove them, or add new ones. View a free demo for JavaScript.
framework: Angular
source: https://surveyjs.io/survey-creator/examples/modify-tab-bar/angular
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Customize the Tab Bar (Angular)

SurveyJS offers the flexibility to add, remove, and modify tabs in its Form Builder UI to implement additional functionality as needed. In this example, we demonstrate how to manage built-in tabs and create a custom "Survey Templates" tab that enables survey authors to quickly load boilerplate surveys into Survey Creator for further customization.

## Manage Built-In Survey Creator Tabs

Survey Creator includes six built-in tabs. To specify the visibility of each tab, use a dedicated configuration property:

- [`showDesignerTab`](https://surveyjs.io/survey-creator/documentation/api-reference/icreatoroptions#showDesignerTab)
- [`showPreviewTab`](https://surveyjs.io/survey-creator/documentation/api-reference/icreatoroptions#showPreviewTab)
- [`showJSONEditorTab`](https://surveyjs.io/survey-creator/documentation/api-reference/icreatoroptions#showJSONEditorTab)
- [`showLogicTab`](https://surveyjs.io/survey-creator/documentation/api-reference/icreatoroptions#showLogicTab)
- [`showTranslationTab`](https://surveyjs.io/survey-creator/documentation/api-reference/icreatoroptions#showTranslationTab)
- [`showThemeTab`](https://surveyjs.io/survey-creator/documentation/api-reference/icreatoroptions#showThemeTab)

By default, the Designer, Preview, Logic, and JSON Editor tabs are visible, while the Translations and Themes tabs are hidden. In this demo, the Translations tab is made visible by setting the `showTranslationTab` property to `true`.

## Add a Custom Survey Creator Tab

If you want to add a custom tab to Survey Creator, follow the instructions below:

1. Implement a custom component that renders tab markup.        
In this demo, the component renders buttons that load different JSON schemas into Survey Creator.

1. Register your component under a custom name in the component collection.      
    In HTML/CSS/JavaScript projects, register the component in `ReactElementFactory` as shown in the `index.js` file.           
    In React, register the component in `ReactElementFactory` as shown in the `SurveyCreatorComponent.jsx` file.          
    In Angular, register the component in `AngularComponentFactory` as shown in the `survey-templates-tab.component.ts` file.          
    In Vue.js, use [techniques native to this framework](https://vuejs.org/guide/components/registration).

2. Configure a tab plugin.      
A tab plugin is an object that allows you to handle user interactions with a tab. The tab plugin object must specify the `activate` and `deactivate` functions. They are executed when users switch to or from the tab and allow you to handle and cancel the switch if necessary. In this demo, `activate` is empty, and `deactivate` always returns `true`, which means that they do not interfere with user interactions in any way.

1. Register a custom tab.        
Call the [`addTab(tabOptions)`](https://surveyjs.io/survey-creator/documentation/api-reference/survey-creator#addTab) method on a `SurveyCreatorModel` instance to register a custom tab.

## Files

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

```css
/* You can define custom CSS rules here */
```

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

```html
<div style="position: fixed; top: 0; bottom: 0; right: 0; left: 0;">
    <survey-creator [model]="model"></survey-creator>
</div>
```

### `src/app/components/survey-templates-tab.component.html`

```html
<div style="padding: 7px;">
    <div *ngFor="let template of surveyTemplates">
        <div style="padding: 7px;">
            <button
                (click)="loadSurvey(template)"
                class="sd-action sd-action--brand sd-action--primary sd-action--large sd-action--border">
                <span class="sd-action__title">
                    Load {{template.name}}
                </span>
            </button>
        </div>
    </div>
</div>
```

### `src/app/components/survey-templates-tab.component.ts`

```ts
import { Component, Input } from "@angular/core";
import { SurveyCreatorModel } from "survey-creator-core";
import { AngularComponentFactory, BaseAngular } from "survey-angular-ui";
import { npsJson, jobApplicationJson } from "./survey_json";

interface ISurveyTemplate {
    name: string;
    json: any;
}

const surveyTemplates: Array<ISurveyTemplate> = [{
    name: "NPS Survey",
    json: npsJson
}, {
    name: "Job Application Form",
    json: jobApplicationJson
}, {
    name: "Empty Survey",
    json: {}
}];

@Component({
    // tslint:disable-next-line:component-selector
    selector: "svc-tab-survey-templates",
    templateUrl: "./survey-templates-tab.component.html"
})
export class SurveyTemplatesTabComponent extends BaseAngular<SurveyCreatorModel> {
    @Input() model!: SurveyCreatorModel;
    public surveyTemplates: Array<ISurveyTemplate> = surveyTemplates;
    public loadSurvey(template: ISurveyTemplate) {
        this.model.JSON = template.json;
        this.model.switchTab("designer");
    }
    protected getModel(): any {
        return null;
    }
}
AngularComponentFactory.Instance.registerComponent(
    "svc-tab-survey-templates",
    SurveyTemplatesTabComponent
);
```

### `src/app/components/survey_json.js`

```js
export const npsJson = {
  "title": "NPS Survey Question",
  "logo": "https://surveyjs.io/Content/Images/examples/logo.png",
  "logoHeight": "60px",
  "logoFit": "cover",
  "pages": [
    {
      "name": "page1",
      "elements": [
        {
          "type": "rating",
          "name": "nps_score",
          "title": "On a scale of zero to ten, how likely are you to recommend our product to a friend or colleague?",
          "isRequired": true,
          "rateMin": 0,
          "rateMax": 10,
          "minRateDescription": "(Most unlikely)",
          "maxRateDescription": "(Most likely)"
        },
        {
          "type": "checkbox",
          "name": "promoter_features",
          "visibleIf": "{nps_score} >= 9",
          "title": "Which of the following features do you value the most?",
          "description": "Please select no more than three features.",
          "isRequired": true,
          "validators": [
            {
              "type": "answercount",
              "text": "Please select no more than three features.",
              "maxCount": 3
            }
          ],
          "showOtherItem": true,
          "choices": [
            "Performance",
            "Stability",
            "User interface",
            "Complete functionality",
            "Learning materials (documentation, demos, code examples)",
            "Quality support"
          ],
          "otherText": "Other features:",
          "colCount": 2
        },
        {
          "type": "comment",
          "name": "passive_experience",
          "visibleIf": "{nps_score} >= 7  and {nps_score} <= 8",
          "title": "What can we do to make your experience more satisfying?"
        },
        {
          "type": "comment",
          "name": "disappointing_experience",
          "visibleIf": "{nps_score} <= 6",
          "title": "Please let us know why you had such a disappointing experience with our product"
        }
      ]
    }
  ],
  "completedHtml": "<h3>Thank you for your feedback</h3>",
  "completedHtmlOnCondition": [
    {
      "expression": "{nps_score} >= 9",
      "html": "<h3>Thank you for your feedback</h3> <h4>We are glad that you love our product. Your ideas and suggestions will help us make it even better.</h4>"
    },
    {
      "expression": "{nps_score} >= 6  and {nps_score} <= 8",
      "html": "<h3>Thank you for your feedback</h3> <h4>We are glad that you shared your ideas with us. They will help us make our product better.</h4>"
    }
  ]
};
export const jobApplicationJson = {
  "title": "Job Application Form",
  "description": "Thank you for your interest in working with us. Please fill out the form and send your application. We will get back to you within a week.",
  "logo": "https://surveyjs.io/Content/Images/examples/logo.png",
  "questionErrorLocation": "bottom",
  "logoHeight": "60px",
  "logoFit": "cover",
  "elements": [
    {
      "type": "panel",
      "name": "personal-info",
      "title": "Personal Information",
      "elements": [
        {
          "type": "text",
          "name": "first-name",
          "title": "First name",
          "isRequired": true
        },
        {
          "type": "text",
          "name": "last-name",
          "startWithNewLine": false,
          "title": "Last name",
          "isRequired": true
        },
        {
          "type": "text",
          "name": "birthdate",
          "title": "Date of birth",
          "inputType": "date",
          "isRequired": true
        }
      ]
    },
    {
      "type": "panel",
      "name": "location",
      "title": "Your Location",
      "elements": [
        {
          "type": "dropdown",
          "name": "country",
          "title": "Country",
          "choicesByUrl": {
            "url": "https://surveyjs.io/api/CountriesExample"
          }
        },
        {
          "type": "text",
          "name": "city",
          "title": "City/Town"
        },
        {
          "type": "text",
          "name": "zip",
          "startWithNewLine": false,
          "title": "Zip code",
          "inputType": "number",
          "validators": [
            {
              "type": "numeric"
            }
          ]
        },
        {
          "type": "text",
          "name": "address",
          "title": "Street address"
        }
      ]
    },
    {
      "type": "text",
      "name": "email",
      "title": "Email",
      "inputType": "email",
      "placeholder": "mail@example.com"
    },
    {
      "type": "text",
      "name": "salary",
      "title": "Expected salary (in US dollars)",
      "inputType": "number",
      "validators": [
        {
          "type": "numeric"
        }
      ]
    },
    {
      "type": "dropdown",
      "name": "position",
      "title": "What position are you applying for?",
      "choices": [
        {
          "value": "frontend",
          "text": "Frontend Developer"
        },
        {
          "value": "backend",
          "text": "Backend Developer"
        },
        {
          "value": "fullstack",
          "text": "Full-Stack Developer"
        },
        {
          "value": "intern",
          "text": "Intern"
        }
      ]
    },
    {
      "type": "text",
      "name": "start-date",
      "title": "Date available to start work",
      "isRequired": true,
      "inputType": "date"
    },
    {
      "type": "file",
      "name": "resume",
      "title": "Upload your resume",
      "acceptedTypes": "application/pdf"
    }
  ],
  "completeText": "Send",
  "widthMode": "static",
  "width": "800px"
};
```

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

```ts
import { Component, OnInit } from "@angular/core";
import { SurveyCreatorModel } from "survey-creator-core";
import "survey-core/survey.i18n";
import "survey-creator-core/survey-creator-core.i18n";
import { ICreatorPlugin } from "survey-creator-core";
import "survey-core/survey-core.css";
import "survey-creator-core/survey-creator-core.css";

import SurveyTheme from "survey-core/themes";
import { registerCreatorTheme } from "survey-creator-core";

registerCreatorTheme(SurveyTheme); // Add predefined Survey Creator UI themes

class SurveyTemplatesTabPlugin implements ICreatorPlugin {
    constructor(private creator: SurveyCreatorModel) {
        this.model = creator;

        // Add the `svc-tab-survey-templates` plugin as the first tab
        creator.addTab({
            name: "survey-templates",
            plugin: this,
            title: "Survey Templates",
            componentName: "svc-tab-survey-templates",
            index: 0
        });
    }
    public model: SurveyCreatorModel;

    // Do nothing when the tab is activated or deactivated
    public activate(): void { }
    public deactivate(): boolean {
        return true;
    }
}
@Component({
    // tslint:disable-next-line:component-selector
    selector: "component-survey-creator",
    templateUrl: "./creator.component.html",
    styleUrls: ["./creator.component.css"]
})
export class SurveyCreatorComponent implements OnInit {
    model: SurveyCreatorModel;
    ngOnInit() {
        const creator = new SurveyCreatorModel({ showTranslationTab: true });
        new SurveyTemplatesTabPlugin(creator);
        creator.activeTab = "survey-templates";
        this.model = creator;
    }
}
```

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

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

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

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

@Component({
    selector: "app-root",
    templateUrl: "./app.component.html"
})
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 { SurveyCreatorModule } from "survey-creator-angular";
import { SurveyCreatorComponent } from "./components/creator.component";
import { SurveyTemplatesTabComponent } from "./components/survey-templates-tab.component";

@NgModule({
    declarations: [AppComponent, SurveyCreatorComponent, SurveyTemplatesTabComponent],
    imports: [BrowserModule, SurveyCreatorModule],
    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 global styles to this file and import other style files */
```

### `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-angular-ui": "latest",
    "survey-creator-core": "latest",
    "survey-core": "latest",
    "survey-creator-angular": "latest",
    "tslib": "1.13.0",
    "zone.js": "0.11.7"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~13.0.0",
    "@angular/cli": "~13.0.0",
    "@types/jasmine": "3.6.3",
    "@types/jasminewd2": "2.0.8",
    "@types/node": "14.14.28",
    "codelyzer": "6.0.1",
    "jasmine-core": "3.6.0",
    "jasmine-spec-reporter": "6.0.0",
    "karma": "6.1.1",
    "karma-chrome-launcher": "3.1.0",
    "karma-coverage-istanbul-reporter": "3.0.3",
    "karma-jasmine": "4.0.1",
    "karma-jasmine-html-reporter": "1.5.4",
    "protractor": "7.0.0",
    "ts-node": "9.1.1",
    "tslint": "~6.1.3",
    "typescript": "4.1.5"
  },
  "keywords": [ "angular", "surveyjs" ],
  "description": "SurveyJS-Angular example project"
}
```

## Other Frameworks

- [React](https://surveyjs.io/survey-creator/examples/modify-tab-bar/reactjs.md)
- [Vue 3](https://surveyjs.io/survey-creator/examples/modify-tab-bar/vue3js.md)
- [jQuery](https://surveyjs.io/survey-creator/examples/modify-tab-bar/jquery.md)
- [Vanilla JS](https://surveyjs.io/survey-creator/examples/modify-tab-bar/vanillajs.md)
