---
title: Add Custom Properties to the Property Grid
product: Survey Creator
description: Increase functional capabilities of your survey forms by adding custom properties to the property grid of a survey builder. View a free demo example for JavaScript to learn more.
framework: Angular
source: https://surveyjs.io/survey-creator/examples/add-properties-to-property-grid/angular
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Add Custom Properties to the Property Grid (Angular)

Survey elements include a number of built-in properties that cover most use cases. However, you can add custom properties to the survey elements if you want to extend their functionality. Custom properties can be serialized and included in the survey JSON schema. Both built-in and custom properties are set in the Property Grid of Survey Creator. 

To add a custom property, call the `addProperty(questionType, propertySettings)` method on the `Survey.Serializer` object. This method accepts the following arguments:

- `questionType`        
A string value that specifies the question type to which the property should be added. You can use a specific type (see the [getType](https://surveyjs.io/Documentation/Library?id=Question#getType) description) or one of the base types. In the latter case, the new property is added to all question types derived from the base type. Refer to the API of a specific question type for information on its inheritance chain.

- `propertySettings`      
Settings that configure the property's appearance and behavior. For information about these settings, refer to the following help section: [Survey Element Property Settings](https://surveyjs.io/survey-creator/documentation/property-grid#survey-element-property-settings).

This demo shows how to add custom properties to the survey, page, and all questions.

## 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/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 { Serializer, SvgRegistry } from "survey-core";
import { getLocaleStrings } 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

// Add a property to the Survey class
Serializer.addProperty("survey", {
    name: "customSurveyProperty",
    category: "customCategory",
    visibleIndex: 0
});
// Add a property to the Page class
Serializer.addProperty("page", {
    name: "customPageProperty",
    category: "customCategory",
    visibleIndex: 0
});
// Add a property to the base Question class and to all questions as a result
Serializer.addProperty("question", {
    name: "customNumericProperty",
    type: "number",
    category: "customCategory",
    default: 1,
    visibleIndex: 0,
    onSetValue: (survey, value) => {
        // ...
        // You can perform required checks here
        // ...
        // Set the `value`
        survey.setPropertyValue("customNumericProperty", value);
        // You can perform required actions after the `value` is set
        // ...
    }
});

// Specify a title for the custom category in the Property Grid
const translations = getLocaleStrings("en");
translations.pe.tabs.customCategory = "Custom Settings";

// Register an icon for the custom category in the Property Grid
const customIcon = `<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M19.5275 7.5275L9.5275 17.5275C9.3775 17.6775 9.1875 17.7475 8.9975 17.7475C8.8075 17.7475 8.6175 17.6775 8.4675 17.5275L4.4675 13.5275C4.1775 13.2375 4.1775 12.7575 4.4675 12.4675C4.7575 12.1775 5.2375 12.1775 5.5275 12.4675L8.9975 15.9375L18.4675 6.4675C18.7575 6.1775 19.2375 6.1775 19.5275 6.4675C19.8175 6.7575 19.8175 7.2375 19.5275 7.5275Z" />
</svg>`;
SvgRegistry.registerIcon("icon-custom", customIcon);

@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();
        creator.onSurveyInstanceCreated.add((_, options) => {
            // Assign the icon to the custom category 
            if (options.area === "property-grid") {
                const choicesCategory = options.survey.getPageByName("customCategory");
                if (choicesCategory) {
                    choicesCategory.iconName = "icon-custom";
                }
            }
        });
        creator.JSON = {
          "pages": [{
            "name": "page1",
            "elements": [{
              "type": "text",
              "name": "question1"
            }]
          }]
        };
        creator.showSidebar = true;
        creator.activatePropertyGridCategory("customCategory");
        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";

@NgModule({
    declarations: [AppComponent, SurveyCreatorComponent],
    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/add-properties-to-property-grid/reactjs.md)
- [Vue 3](https://surveyjs.io/survey-creator/examples/add-properties-to-property-grid/vue3js.md)
- [jQuery](https://surveyjs.io/survey-creator/examples/add-properties-to-property-grid/jquery.md)
- [Vanilla JS](https://surveyjs.io/survey-creator/examples/add-properties-to-property-grid/vanillajs.md)
