---
title: Limit Question Instances and Panel Nesting
product: Survey Creator
description: Survey Creator allows you to have complete control over the types of questions users can add to a form and how many questions of each type a user can include within a single form. Survey elements that support nesting, such as Panels and Dynamic Panels, can be configured to either prevent users from adding certain question types or limit how many times they can be added. This JavaScript form builder demo illustrates how to restrict nesting options and control the use of specific question types.
framework: React
source: https://surveyjs.io/survey-creator/examples/limit-number-of-survey-elements/reactjs
index: https://surveyjs.io/survey-creator/examples/overview.md
---

# Limit Question Instances and Panel Nesting (React)

When dealing with complex forms, you may wish to restrict the number of elements authors can insert, nesting depth for panels, and acceptable form structures. This example illustrates how to enforce such design constraints in Survey Creator: for example, allow just one Signature question per survey and restrict nesting of panels and matrices.

## Limit a Question Type to a Single Instance

To restrict survey authors from adding more than one instance of a specific question type, handle the [`onAllowAddElement`](https://surveyjs.io/survey-creator/documentation/api-reference/survey-creator#onAllowAddElement) event.

The following code ensures that only one Signature field can be added:

```js
const SIGNATURE_QUESTION_TYPE = "signaturepad";

function hasSignatureQuestion(surveyModel) {
  const questions = surveyModel.getAllQuestions(true, true, true);
  return questions.some(q => q.getType() === SIGNATURE_QUESTION_TYPE);
}

creator.onAllowAddElement.add((_, options) => {
  if (options.name === SIGNATURE_QUESTION_TYPE) {
    // Allow adding only if no Signature question exists
    options.allow = !hasSignatureQuestion(creator.survey);
  }
});
```

## Restrict Nested Panels and Question Types

To maintain a clear and manageable survey structure, you can limit how deeply panels can nest and which element types can appear inside them. Use the following configuration options:

- [`maxPanelNestingLevel`](https://surveyjs.io/survey-creator/documentation/api-reference/survey-creator#maxPanelNestingLevel): `number`\
Sets the maximum depth for nested Panels and Dynamic Panels.

- [`forbiddenNestedElements`](https://surveyjs.io/survey-creator/documentation/api-reference/survey-creator#forbiddenNestedElements): `{ panel: string[]; paneldynamic: string[]; }`\
Specifies which element types cannot appear inside Panels and Dynamic Panels.

The example below applies these restrictions:

- Panels cannot contain Dynamic Panels.
- Dynamic Panels cannot contain Panels, other Dynamic Panels, Multi-Select Matrices, or Dynamic Matrices.
- Panels and Dynamic Panels are limited to two levels of nesting.

```js
const creatorOptions = {
  maxPanelNestingLevel: 2,
  forbiddenNestedElements: {
    panel: ["paneldynamic"],
    paneldynamic: ["panel", "paneldynamic", "matrixdropdown", "matrixdynamic"]
  }
}
const creator = new SurveyCreator.SurveyCreator(creatorOptions);

// In modular applications:
import { SurveyCreatorModel } from "survey-creator-core";
const creator = new SurveyCreatorModel(creatorOptions);
```

## Files

### `public/index.html`

```html
<!-- Uncomment the following lines to enable Ace Editor in the JSON Editor tab -->
<!-- 
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ace.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/ext-searchbox.js"></script>
<script src="https://unpkg.com/ace-builds/src-min-noconflict/theme-clouds_midnight.js"></script>
-->

<div id="surveyCreatorContainer" style="position: absolute; height: 100%; width: 100%"></div>
```

### `src/survey_json.js`

```js
export const surveyJSON = {
  "pages": [
    {
      "name": "page1",
      "elements": [
        {
          "type": "panel",
          "name": "panel",
          "title": "Panel",
          "description": "Allows up to two levels of nesting and cannot contain Dynamic Panels."
        },
        {
          "type": "paneldynamic",
          "name": "dynamic-panel",
          "title": "Dynamic Panel",
          "description": "Allows up to two levels of nesting and cannot contain Panels, other Dynamic Panels, Multi-Select Matrices, or Dynamic Matrices."
        },
        {
          "type": "signaturepad",
          "name": "signature",
          "title": "Signature",
          "description": "Only one Signature field per survey is allowed."
        }
      ]
    }
  ]
};
```

### `src/SurveyCreatorComponent.jsx`

```js
import React from "react";
import { SurveyCreator, SurveyCreatorComponent } from "survey-creator-react";
import "survey-core/survey.i18n";
import "survey-creator-core/survey-creator-core.i18n";
import { surveyJSON } from "./survey_json";
import "survey-core/survey-core.css";
import "survey-creator-core/survey-creator-core.css";
import "./index.css";

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

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

function SurveyCreatorRenderComponent() {
    const creator = new SurveyCreator({
        maxPanelNestingLevel: 2,
        forbiddenNestedElements: {
            panel: ["paneldynamic"],
            paneldynamic: ["panel", "paneldynamic", "matrixdropdown", "matrixdynamic"]
        }
    });
    const SIGNATURE_QUESTION_TYPE = "signaturepad";
    
    function hasSignatureQuestion(surveyModel) {
        const questions = surveyModel.getAllQuestions(true, true, true);
        return questions.some(q => q.getType() === SIGNATURE_QUESTION_TYPE);
    }
    
    creator.onAllowAddElement.add((_, options) => {
        if (options.name === SIGNATURE_QUESTION_TYPE) {
            // Allow adding only if no other Signature question exists
            options.allow = !hasSignatureQuestion(creator.survey);
        }
    });
    
    creator.JSON = surveyJSON;
    return (<SurveyCreatorComponent creator={creator} />);
}

export default SurveyCreatorRenderComponent;
```

### `src/index.css`

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

### `src/index.js`

```js
import React from "react";
import { createRoot } from "react-dom/client";
import SurveyCreatorRenderComponent from "./SurveyCreatorComponent";

const root = createRoot(document.getElementById("surveyCreatorContainer"));
root.render(<SurveyCreatorRenderComponent />);
```

### `package.json`

```json
{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "survey-core": "latest",
    "survey-react-ui": "latest",
    "survey-creator-core": "latest",
    "survey-creator-react": "latest"
  },
  "devDependencies": {
    "react-scripts": "latest"
  }
}
```

## Other Frameworks

- [Angular](https://surveyjs.io/survey-creator/examples/limit-number-of-survey-elements/angular.md)
- [Vue 3](https://surveyjs.io/survey-creator/examples/limit-number-of-survey-elements/vue3js.md)
- [jQuery](https://surveyjs.io/survey-creator/examples/limit-number-of-survey-elements/jquery.md)
- [Vanilla JS](https://surveyjs.io/survey-creator/examples/limit-number-of-survey-elements/vanillajs.md)
