---
title: Breakable Loop
product: Form Library
description: Allow your respondents to duplicate a group of questions as many times as needed, for example, to add multiple addresses, contacts, family members, or other entries. Set a maximum number of groups to stop the repetition automatically. View the JavaScript demo to see the breakable loop feature in action.
framework: jQuery
source: https://surveyjs.io/form-library/examples/breakable-loop/jquery
index: https://surveyjs.io/form-library/examples/overview.md
---

# Breakable Loop (jQuery)

A breakable loop allows respondents to repeat the same set of questions in a loop to add multiple entries. Respondents can exit the loop when they want to, or the loop can end automatically when a certain condition is met. This may happen when a maximum number of entries is reached, a specific value is entered, or a validation rule is triggered. Once the loop ends, the respondent can proceed to the next question or submit the survey.

In SurveyJS Form Library, two question types can be used to create a breakable loop: [Dynamic Panel](/form-library/examples/duplicate-group-of-fields-in-form/) and [Dynamic Matrix](/form-library/examples/dynamic-matrix-add-new-rows/). Regardless of the question type you choose, the loop can be enabled only if your survey displays one input field per page. To enable this structure, set the [`questionsOnPageMode`](/form-library/documentation/api-reference/survey-data-model#questionsOnPageMode) property to `"inputPerPage"` at the survey level.

To implement a breakable loop based on a Dynamic Panel or Dynamic Matrix, follow the steps below:

1. Configure the repeated questions.            
Define the question configurations in the [`templateElements`](/form-library/documentation/api-reference/dynamic-panel-model#templateElements) array in a Dynamic Panel or [`columns`](/form-library/documentation/api-reference/dynamic-matrix-table-question-model#columns) array in a Dynamic Matrix.

1. Specify a title pattern.         
Each iteration step displays a title. To customize it, use the [`templateTitle`](/form-library/documentation/api-reference/dynamic-panel-model#templateTitle) property in a Dynamic Panel or [`singleInputTitleTemplate`](/form-library/documentation/api-reference/dynamic-matrix-table-question-model#singleInputTitleTemplate) property in a Dynamic Matrix. The title pattern supports text piping from other questions and loop levels.

1. *(Optional)* Define conditions for breaking the loop.        
Respondents can stop adding new entries when they want to, but you can specify conditions that end the loop automatically. For example, the [`maxPanelCount`](/form-library/documentation/api-reference/dynamic-panel-model#maxPanelCount) property in a Dynamic Panel and [`maxRowCount`](/form-library/documentation/api-reference/dynamic-matrix-table-question-model#maxRowCount) property in a Dynamic Matrix define the maximum number of repeating sections a user can add. This demo sets the `maxPanelCount` property to 5. If you need a more sophisticated logic for breaking the loop, use [triggers](/form-library/documentation/design-survey/conditional-logic#conditional-survey-logic-triggers).

For a Dynamic Panel code example, refer to the Code tab in this demo. A Dynamic Matrix code example is shown in the [Nested Loops](/form-library/examples/nested-loops/) demo.

## Files

### `public/index.html`

```html
<div id="surveyElement" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; min-height: 100%; height:100%"></div>
```

### `src/index.css`

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

### `src/index.js`

```js
import $ from "jquery";
import { Model } from "survey-core";
import "survey-js-ui";
import "survey-core/survey-core.min.css";
import "./index.css";
import { json } from "./json";

const survey = new Model(json);
survey.onComplete.add((sender, options) => {
    console.log(JSON.stringify(sender.data, null, 3));
});

$("#surveyElement").Survey({ model: survey });
```

### `src/json.js`

```js
export const json = {
  "questionsOnPageMode": "inputPerPage",
  "pages": [
    {
      "name": "page1",
      "elements": [
        {
          "type": "paneldynamic",
          "name": "vacation-info",
          "title": "Enter information about your vacations",
          "templateElements": [
            {
              "type": "dropdown",
              "name": "country",
              "title": "Select a country",
              "isRequired": true,
              "defaultDisplayValue": "[not selected]",
              "choicesByUrl": {
                "url": "https://surveyjs.io/api/CountriesExample",
                "valueName": "name"
              }
            },
            {
              "type": "text",
              "name": "start-date",
              "title": "Select a vacation start date",
              "isRequired": true,
              "inputType": "date"
            },
            {
              "type": "text",
              "name": "end-date",
              "title": "Select a vacation end date",
              "isRequired": true,
              "validators": [
                {
                  "type": "expression",
                  "text": "End date should be greater than start date",
                  "expression": "{panel.start-date} < {panel.end-date}"
                }
              ],
              "inputType": "date"
            },
            {
              "type": "expression",
              "name": "diffdays",
              "visible": false,
              "expression": "iif({panel.start-date} < {panel.end-date}, diffDays({panel.start-date}, {panel.end-date}), '[not set]')"
            }
          ],
          "templateTitle": "Vacation to {panel.country}, duration {panel.diffdays} days",
          "panelCount": 1,
          "maxPanelCount": 5,
          "confirmDelete": true,
          "addPanelText": "Add Vacation"
        }
      ]
    }
  ]
};
```

### `src/theme.js`

```js
export const themeJson = {};
```

### `package.json`

```json
{
  "dependencies": {
    "jquery": "latest",
    "survey-core": "latest",
    "survey-js-ui": "latest"
  }
}
```

## Other Frameworks

- [Angular](https://surveyjs.io/form-library/examples/breakable-loop/angular.md)
- [React](https://surveyjs.io/form-library/examples/breakable-loop/reactjs.md)
- [Vue 3](https://surveyjs.io/form-library/examples/breakable-loop/vue3js.md)
- [Vanilla JS](https://surveyjs.io/form-library/examples/breakable-loop/vanillajs.md)
