---
title: Override the Property Grid Component
product: Survey Creator
description: You can change the default behavior of Survey Creator UI and move some of the elements from the designer surface to the property grid. View a free demo for JavaScript.
framework: Angular
source: https://surveyjs.io/survey-creator/examples/override-property-grid/angular
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Override the Property Grid Component (Angular)

Survey Creator consists of individual UI components that you can override to extend their functionality or implement custom appearance. Overriding the Property Grid component is useful if you want to add UI elements around it, without customizing the Property Grid itself. For instance, this demo shows how to display custom buttons above the Property Grid.

The steps to override a SurveyJS component depend on the frontend framework you use. The following instructions outline the core stages:

1. Create a custom component.           
This component will extend the Property Grid functionality.

1. Make the original Property Grid component available within the custom component.           
In React, import `PropertyGridComponent` within the custom component.           
In Vue 3, register the original component using the `app.component()` method (see the `main.ts` file).          
In Angular and vanilla JS applications, the original component is available by default.     

1. Implement desired functionality in the custom component.                   
The component's markup should include the original Property Grid component.

1. Replace the original component with the custom component.            
Register the custom component under the name `"svc-property-grid"` within `ComponentFactory` (in Vue 3), `ReactElementFactory` (in React and vanilla JS), or `AngularComponentFactory` (in Angular).

Refer to the Code tab for details and code examples.

## 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/custom-property-grid.component.html`

```html
<div class="button-container">
    <button (click)="clearSurvey()" class="button sd-action sd-action--brand sd-action--tertiary-surface sd-action--large sd-action--border">
        <div class="sd-action__title">Clear Survey</div>
    </button>
    <button (click)="loadNps()" class="button sd-action sd-action--brand sd-action--tertiary-surface sd-action--large sd-action--border">
        <div class="sd-action__title">Load NPS Survey</div>
    </button>
</div>
<svc-property-grid [model]="model"></svc-property-grid>
```

### `src/app/components/custom-property-grid.component.scss`

```
:host {
    display: block;
    width: 100%;
}

.button-container {
  display: flex;
  box-sizing: border-box;
  width: calc(100% - var(--sjs2-spacing-x200));
  gap: var(--sjs2-spacing-x200);
  margin: var(--sjs2-spacing-x100);
}

.button {
  flex-basis: 50%;
}

.spg-container.spg-container_search {
  height: calc(100% - var(--sjs2-spacing-x900, calc(9 * var(--sjs2-spacing-x100, 8px))));
}
```

### `src/app/components/custom-property-grid.component.ts`

```ts
import { Component, Input } from "@angular/core";
import { AngularComponentFactory } from "survey-angular-ui";
import { PropertyGridViewModel } from "survey-creator-core";
import { NpsSurvey } from "./nps_survey";

@Component({
    selector: "svc-custom-property-grid",
    templateUrl: "./custom-property-grid.component.html",
    styleUrls: ["./custom-property-grid.component.scss"]
})
export class CustomPropertyGridComponent {
    @Input() model!: PropertyGridViewModel;
    setCreatorJson(val) {
        this.model["creator"].JSON = val;
    }
    clearSurvey() {
        this.setCreatorJson({});
    }
    loadNps() {
        this.setCreatorJson(NpsSurvey);
    }
}
AngularComponentFactory.Instance.registerComponent(
    "svc-property-grid",
    CustomPropertyGridComponent
);
```

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

```js
export const NpsSurvey = {
  "completedHtmlOnCondition": [
   {
    "expression": "{nps-score} <= 6 or {rebuy} = false",
    "html": "Thanks for your feedback! We highly value all ideas and suggestions from our customers, whether they're positive or critical. In the future, our team might reach out to you to learn more about how we can further improve our product so that it exceeds your expectations."
   },
   {
    "expression": "{nps-score} = 6 or {nps-score} = 7",
    "html": "Thanks for your feedback. Our goal is to create the best possible product, and your thoughts, ideas, and suggestions play a major role in helping us identify opportunities to improve."
   },
   {
    "expression": "{nps-score} >= 8",
    "html": "Thanks for your feedback. It's great to hear that you're a fan of our product. Your feedback helps us discover new opportunities to improve it and make sure you have the best possible experience."
   }
  ],
  "pages": [
    {
      "name": "page1",
      "elements": [
        {
          "type": "rating",
          "name": "nps-score",
          "title": "On a scale from 0 to 10, how likely are you to recommend us to a friend or colleague?",
          "rateMin": 0,
          "rateMax": 10,
          "minRateDescription": "Very unlikely",
          "maxRateDescription": "Very likely",
          "rateDescriptionLocation": "bottom"
        },
        {
          "type": "comment",
          "name": "disappointing-experience",
          "visibleIf": "{nps-score} <= 5",
          "title": "How did we disappoint you and what can we do to make things right?",
          "maxLength": 300
        },
        {
          "type": "comment",
          "name": "improvements-required",
          "visibleIf": "{nps-score} >= 6",
          "title": "What can we do to make your experience more satisfying?",
          "maxLength": 300
        },
        {
          "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,
          "choices": [
            { "value": "performance", "text": "Performance" },
            { "value": "stability", "text": "Stability" },
            { "value": "ui", "text": "User interface" },
            { "value": "complete-functionality", "text": "Complete functionality" },
            { "value": "learning-materials", "text": "Learning materials (documentation, demos, code examples)" },
            { "value": "support", "text": "Quality support" }
          ],
          "showOtherItem": true,
          "otherPlaceholder": "Please specify...",
          "otherText": "Other features",
          "colCount": 2,
          "maxSelectedChoices": 3
        }
      ]
    },
    {
      "name": "page2",
      "elements": [
        {
          "type": "boolean",
          "name": "rebuy",
          "title": "Would you buy our product again?"
        },
      ]
    },
    {
      "name": "page3",
      "elements": [
        {
          "type": "radiogroup",
          "name": "testimonial",
          "title": "Would you mind providing us a brief testimonial for the website?",
          "choices": [
            { "value": "yes", "text": "Sure!" },
            { "value": "no", "text": "No" }
          ]
        },
        {
          "type": "text",
          "name": "email",
          "visibleIf": "{testimonial} = 'yes'",
          "title": "What is your email address?",
          "validators": [{
            "type": "email"
          }],
          "placeholder": "Enter your email here"
        }
      ]
    }
  ],
  "showPrevButton": false,
  "widthMode": "static",
  "width": "1000px"
};
```

### `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 "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

@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();
        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 { CustomPropertyGridComponent } from "./components/custom-property-grid.component";

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