SurveyJS v2.4.1

Released: December 3, 2025

SurveyJS v2.4.1 adds asynchronous event support for survey completion and page navigation, configurable default question type for the "Add Question" button, and a new noneof operator for expressions.

Form Library: Async page navigation and data saving

This release adds support for asynchronous operations within the SurveyModel's onCurrentPageChanging and onCompleting event handlers. This is helpful when you need to run server-side validation, save intermediate data, or perform any other async workflow before allowing the survey to continue or complete.

To enable asynchronous behavior, return a Promise from the event handler. You can prevent the survey from completing or switching pages by setting options.allow to false, and use options.message to display an error or success notification.

The example below shows how to save the last active page number on a server and how to submit survey results asynchronously:

function postJson(url, data) {
  return fetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json; charset=utf-8" },
    body: JSON.stringify(data)
  });
}

// ...
// Omitted: `SurveyModel` creation
// ...

survey.onCurrentPageChanging.add(async (_, options) => {
  try {
    const response = await postJson(surveyServiceUrl + "/post/page-number/", {
      postId: surveyPostId,
      lastActivePageIndex: options.oldCurrentPage.visibleIndex
    });
    if (!response.ok) {
      options.allow = false;
      options.message = "Could not save the last page number";
    }
  } catch (e) {
    options.allow = false;
    options.message = e.message;
    console.error(e.message);
  }
});

survey.onCompleting.add(async (_, options) => {
  try {
    const response = await postJson(surveyServiceUrl + "/post/", {
      postId: surveyPostId,
      surveyResult: JSON.stringify(survey.data)
    });
    if (!response.ok) {
      options.allow = false;
      options.message = "Could not post the survey results";
    } else {
      // Optionally show a success message
      options.message = "Your data has been saved";
    }
  } catch (e) {
    options.allow = false;
    options.message = e.message;
    console.error(e.message);
  }
});

Survey Creator: Specify a default question type for the Add Question button

By default, the "Add Question" button on the design surface adds a new Single-Line Input question. This release introduces the defaultAddQuestionType property, which lets you specify a different default question type. For example, the code below configures Dropdown as the default:

import { SurveyCreatorModel } from "survey-creator-core";

const creatorOptions = {
  defaultAddQuestionType: "dropdown"
};

const creator = new SurveyCreatorModel(creatorOptions);

Open in Plunker

New "None Of" Operator for Expressions

SurveyJS v2.4.1 adds a new operator to the list of supported expression operators. The noneof operator compares a value with an array and returns true if the value is absent, or compares two arrays and returns true if the first array contains none of the values in the second.

// `true` because "apple" is not in the array
"expression": "noneof('apple', ['banana', 'orange', 'grape'])"

// `true` because none of the selected tags are blocked
"expression": "noneof(['tag1', 'tag2'], ['blocked1', 'blocked2'])"

New Blog Posts

Data Entry Software: Definition, Types, Features, Benefits, and the Best Tools in 2025

Bug Fixes and Minor Enhancements

Form Library

  • Serializer.generateSchema() doesn't allow strings for itemvalue arrays (#10655)
  • [PDF Generator] PDF document is not generated when the onChoicesLazyLoad event handler is not attached to a SurveyPDF instance (#10642)
  • [Survey Creator] File Upload: "Custom" option cannot be removed from "Accepted file categories" unless the custom file extensions are removed first (#10647)
  • Exception occurs in input-per-page mode when survey.data is set (#10653)
  • "Set Value" trigger fails when dependent on values set by another "Set Value" trigger (#10659)

Survey Creator

  • Property Grid: Copying a trigger expression accidentally starts drag action (#7286)
  • Property Grid: Clarify that validation expression defines when the value is valid, not invalid (#7277)
  • [Angular] Infinite loop exception occurs (#7293)

How to Update SurveyJS Libraries in Your Application

Angular
npm i survey-core@v2.4.1 survey-angular-ui@v2.4.1 --save
npm i survey-creator-core@v2.4.1 survey-creator-angular@v2.4.1 --save
npm i survey-analytics@v2.4.1 --save
npm i survey-pdf@v2.4.1 --save
React
npm i survey-core@v2.4.1 survey-react-ui@v2.4.1 --save
npm i survey-creator-core@v2.4.1 survey-creator-react@v2.4.1 --save
npm i survey-analytics@v2.4.1 --save
npm i survey-pdf@v2.4.1 --save
Vue.js
npm i survey-core@v2.4.1 survey-vue3-ui@v2.4.1 --save
npm i survey-creator-core@v2.4.1 survey-creator-vue@2.4.1 --save
npm i survey-analytics@2.4.1 --save
npm i survey-pdf@2.4.1 --save
HTML/CSS/JavaScript
<link href="https://unpkg.com/survey-core@2.4.1/survey-core.min.css" type="text/css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/survey-core@2.4.1/survey.core.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/survey-js-ui@2.4.1/survey-js-ui.min.js"></script>

<script src="https://unpkg.com/survey-core@2.4.1/themes/index.min.js"></script>
<script src="https://unpkg.com/survey-creator-core@2.4.1/themes/index.min.js"></script>

<link href="https://unpkg.com/survey-creator-core@2.4.1/survey-creator-core.min.css" type="text/css" rel="stylesheet">
<script src="https://unpkg.com/survey-creator-core@2.4.1/survey-creator-core.min.js"></script>
<script src="https://unpkg.com/survey-creator-js@2.4.1/survey-creator-js.min.js"></script>

<link href="https://unpkg.com/survey-analytics@2.4.1/survey.analytics.min.css" rel="stylesheet">
<script src="https://unpkg.com/survey-analytics@2.4.1/survey.analytics.min.js"></script>

<script src="https://unpkg.com/survey-pdf@2.4.1/survey.pdf.min.js"></script>
<script src="https://unpkg.com/survey-pdf@2.4.1/pdf-form-filler.min.js"></script>

Your cookie settings

We use cookies to make your browsing experience more convenient and personal. Some cookies are essential, while others help us analyse traffic. Your personal data and cookies may be used for ad personalization. By clicking “Accept All”, you consent to the use of all cookies as described in our Terms of Use and Privacy Statement. You can manage your preferences in “Cookie settings.”

Your renewal subscription expires soon.

Since the license is perpetual, you will still have permanent access to the product versions released within the first 12 month of the original purchase date.

If you wish to continue receiving technical support from our Help Desk specialists and maintain access to the latest product updates, make sure to renew your subscription by clicking the "Renew" button below.

Your renewal subscription has expired.

Since the license is perpetual, you will still have permanent access to the product versions released within the first 12 month of the original purchase date.

If you wish to continue receiving technical support from our Help Desk specialists and maintain access to the latest product updates, make sure to renew your subscription by clicking the "Renew" button below.