<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: SurveyJS</title>
    <description>The latest articles on Forem by SurveyJS (@surveyjs).</description>
    <link>https://forem.com/surveyjs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F863112%2Fc86654ef-e30a-4859-aa34-d4d15bc4dcdc.png</url>
      <title>Forem: SurveyJS</title>
      <link>https://forem.com/surveyjs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/surveyjs"/>
    <language>en</language>
    <item>
      <title>How to Add a Form Wizard to Your Website (React, Angular, Vue, plain JS)</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Thu, 12 Mar 2026 21:13:31 +0000</pubDate>
      <link>https://forem.com/surveyjs/how-to-add-a-form-wizard-to-your-website-react-angular-vue-plain-js-198d</link>
      <guid>https://forem.com/surveyjs/how-to-add-a-form-wizard-to-your-website-react-angular-vue-plain-js-198d</guid>
      <description>&lt;p&gt;The quickest way to add a form wizard to a web application is to use a JavaScript form library that already supports multi-step flows. Instead of building page navigation, validation, and conditional logic from scratch, you define the form as JSON and let the rendering library handle the runtime behavior.&lt;/p&gt;

&lt;p&gt;SurveyJS is a good fit for this. It lets you model forms as JSON schemas, configure validation and logic declaratively, and render the same form in React, Angular, Vue, or plain JavaScript. Survey Creator allows you to generate that schema visually, and Form Library renders it in your application.&lt;/p&gt;

&lt;p&gt;This article shows how to create a multi-step form wizard with SurveyJS and embed it in different JavaScript stacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Form Wizard
&lt;/h2&gt;

&lt;p&gt;A form wizard is a form navigation pattern that splits a long or complex form into a sequence of smaller steps. Instead of showing every input at once, the UI presents one section, question, or field at a time and guides the user through the flow with navigation controls and progress indicators. This approach improves usability for long forms such as the sample background check consent form shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0hgfbbfhhibgjtl1u1lu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0hgfbbfhhibgjtl1u1lu.png" alt="Multi-step form wizard" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use SurveyJS for Multi-Step Forms
&lt;/h2&gt;

&lt;p&gt;SurveyJS separates form design from rendering.&lt;/p&gt;

&lt;p&gt;You define the form structure, validation rules, navigation, and logic in JSON. Then the Form Library renders that schema in the framework of your choice. &lt;a href="https://surveyjs.io/form-library/documentation/overview" rel="noopener noreferrer"&gt;SurveyJS Form Library&lt;/a&gt; is framework-specific at the UI layer, while &lt;code&gt;survey-core&lt;/code&gt; contains the shared model and runtime logic, so you can reuse the same form definition across React, Angular, Vue, and plain JavaScript.&lt;/p&gt;

&lt;p&gt;To learn more about SurveyJS architecture, please refer to the &lt;a href="https://surveyjs.io/documentation/surveyjs-architecture" rel="noopener noreferrer"&gt;SurveyJS Architecture&lt;/a&gt; guide.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://surveyjs.io/survey-creator/documentation/overview" rel="noopener noreferrer"&gt;Survey Creator&lt;/a&gt; is the visual form builder used to generate and edit form schemas. It supports drag-and-drop form design, a JSON editor, validation rules, and conditional logic configuration. The generated JSON can then be rendered by SurveyJS Form Library.&lt;/p&gt;

&lt;p&gt;In practice, that gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;visual form authoring&lt;/li&gt;
&lt;li&gt;JSON-based configuration&lt;/li&gt;
&lt;li&gt;built-in validation&lt;/li&gt;
&lt;li&gt;conditional logic&lt;/li&gt;
&lt;li&gt;reusable rendering across frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SurveyJS Rendering Packages
&lt;/h2&gt;

&lt;p&gt;SurveyJS ships framework-specific rendering packages on top of &lt;code&gt;survey-core&lt;/code&gt;. Using these packages, you can embed multi-step forms into any&lt;br&gt;
website. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;NPM Package&lt;/th&gt;
&lt;th&gt;Get Started guide&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;React&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/survey-react-ui" rel="noopener noreferrer"&gt;&lt;code&gt;survey-react-ui&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://surveyjs.io/form-library/documentation/get-started-react" rel="noopener noreferrer"&gt;React Get Started Guide&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Angular&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/survey-angular-ui" rel="noopener noreferrer"&gt;&lt;code&gt;survey-angular-ui&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://surveyjs.io/form-library/documentation/get-started-angular" rel="noopener noreferrer"&gt;Angular Get Started Guide&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vue.js&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/survey-vue3-ui" rel="noopener noreferrer"&gt;&lt;code&gt;survey-vue3-ui&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://surveyjs.io/form-library/documentation/get-started-vue" rel="noopener noreferrer"&gt;Vue Get Started Guide&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plain JavaScript&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/survey-js-ui" rel="noopener noreferrer"&gt;&lt;code&gt;survey-js-ui&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://surveyjs.io/form-library/documentation/get-started-html-css-javascript" rel="noopener noreferrer"&gt;Plain JavaScript Get Started Guide&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All of them render the same JSON schema, which means the form definition stays the same even if the frontend stack changes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Define the Wizard as JSON
&lt;/h2&gt;

&lt;p&gt;In SurveyJS, a form is described as a JSON schema. At the top level, you define survey metadata and runtime options. Inside pages, you define the questions shown in each step.&lt;/p&gt;

&lt;p&gt;Here is a simplified example of a background check consent form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;surveyJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Background check consent form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pages&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;personal-details&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Personal Details&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;elements&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;surname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Surname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;maxLength&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;surname-at-birth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;startWithNewLine&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Surname at birth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;maxLength&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Date of Birth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;validators&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;expression&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You must be at least 18 y.o. to submit the form.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;expression&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;age({dob}) &amp;gt;= 18&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inputType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;date&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;radiogroup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gender&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;maxWidth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;50%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Gender&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;commentText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Other (describe)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;choices&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;female&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Female&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;male&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Male&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;other&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Other&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;otherText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Other (please specify)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;otherErrorText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Response required: please specify your               gender.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;colCount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;showProgressBar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;progressBarLocation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;belowheader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;progressBarType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;questions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;completeText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submit Form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;questionsOnPageMode&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;questionPerPage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#questionsOnPageMode" rel="noopener noreferrer"&gt;&lt;code&gt;questionsOnPageMode&lt;/code&gt;&lt;/a&gt; is a survey-level setting that controls how the runtime treats steps. It works as the switch that determines whether navigation happens by page, by question, or by input.&lt;/p&gt;

&lt;p&gt;The property accepts the following values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;singlePage&lt;/code&gt; – Combines all survey pages into a single page.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;questionPerPage&lt;/code&gt; – Displays each question on a separate page.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;inputPerPage&lt;/code&gt; – Displays each input field on a separate page. Complex questions—such as Single-Select Matrix, Multi-Select Matrix, Dynamic Matrix, Dynamic Panel, and Multiple Textboxes—are split so that each input field appears on its own page.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;standard&lt;/code&gt; (default) – Retains the original single- or multi-page structure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;questionsOnPageMode: "questionPerPage"&lt;/code&gt; turns the form into a question-by-question wizard, regardless of how many elements are on a page. If you want each declared page to behave as a wizard step, use the default page structure instead of question-per-page mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Wizard Behavior in Survey Creator
&lt;/h2&gt;

&lt;p&gt;You can define the JSON manually, but it is faster to configure the form visually in Survey Creator.&lt;/p&gt;

&lt;p&gt;Survey Creator produces a JSON configuration that Form Library can render later, and the survey-level settings include layout and navigation configuration. To configure a multi-step form in the builder UI:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;At the top of the Property Grid, select &lt;strong&gt;Survey&lt;/strong&gt; to switch to the survey-level settings.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Navigation&lt;/strong&gt;, locate the &lt;strong&gt;Survey layout&lt;/strong&gt; setting.&lt;/li&gt;
&lt;li&gt;Select the option that suits your use case.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1jbut8iniwfvo49ysle.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1jbut8iniwfvo49ysle.png" alt="Form wizard layout options" width="800" height="421"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Render the Form Wizard
&lt;/h2&gt;

&lt;p&gt;Once the JSON schema is ready, pass it to a &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/survey-data-model" rel="noopener noreferrer"&gt;&lt;code&gt;Model&lt;/code&gt;&lt;/a&gt; from &lt;code&gt;survey-core&lt;/code&gt; and render it with the package for your framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  React
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;survey-core/survey-core.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;survey-core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Survey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;survey-react-ui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;surveyJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;SurveyWizard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;survey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;surveyJson&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Survey&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;survey&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Angular
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;survey-core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;survey [model]="survey"&amp;gt;&amp;lt;/survey&amp;gt;`&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;survey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;surveyJson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in your Angular module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BrowserModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@angular/platform-browser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SurveyModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;survey-angular-ui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./app.component&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;declarations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppComponent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;BrowserModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SurveyModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppComponent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Vue
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;survey-core/survey-core.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;survey-core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SurveyComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;survey-vue3-ui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;survey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;surveyJson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SurveyComponent&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;survey&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Plain JavaScript
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;SurveyJS Form Wizard&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt;
    &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;
    &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/survey-core/survey-core.min.css"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/survey-core/survey.core.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/survey-js-ui/survey-js-ui.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"surveyContainer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;surveyJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;survey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Survey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;surveyJson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DOMContentLoaded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;survey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;surveyContainer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;A form wizard is not just a UI convenience. It is a runtime model for managing long-form input: sequence, validation, conditional branching, and completion. SurveyJS is useful here because those concerns live in the schema instead of being hand-coded into each frontend implementation.&lt;/p&gt;

&lt;p&gt;That design has two practical benefits. First, the form definition becomes portable across frameworks. Second, the logic is easier to review, version, and maintain because it is expressed declaratively in JSON rather than spread across multiple components and event handlers.&lt;/p&gt;

&lt;p&gt;If your goal is to ship a multi-step form quickly without losing control over validation and logic, that is a solid architecture.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>json</category>
      <category>opensource</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Thu, 15 Jan 2026 23:01:42 +0000</pubDate>
      <link>https://forem.com/surveyjs/-5a7l</link>
      <guid>https://forem.com/surveyjs/-5a7l</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/surveyjs" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F863112%2Fc86654ef-e30a-4859-aa34-d4d15bc4dcdc.png" alt="surveyjs"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/surveyjs/react-json-schema-forms-in-practice-why-they-break-down-and-how-surveyjs-fixes-the-architecture-17ik" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;React JSON Schema Forms in Practice — Why They Break Down and How SurveyJS Fixes the Architecture&lt;/h2&gt;
      &lt;h3&gt;SurveyJS ・ Jan 15&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#frontend&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#json&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>react</category>
      <category>json</category>
    </item>
    <item>
      <title>React JSON Schema Forms in Practice — Why They Break Down and How SurveyJS Fixes the Architecture</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Thu, 15 Jan 2026 22:57:09 +0000</pubDate>
      <link>https://forem.com/surveyjs/react-json-schema-forms-in-practice-why-they-break-down-and-how-surveyjs-fixes-the-architecture-17ik</link>
      <guid>https://forem.com/surveyjs/react-json-schema-forms-in-practice-why-they-break-down-and-how-surveyjs-fixes-the-architecture-17ik</guid>
      <description>&lt;p&gt;React JSON schema forms promise something very attractive to product teams: define your form once as JSON, render it anywhere, and let the schema handle validation, defaults, and conditional logic.&lt;/p&gt;

&lt;p&gt;Libraries like &lt;code&gt;@rjsf/core&lt;/code&gt; (&lt;a href="https://github.com/rjsf-team/react-jsonschema-form" rel="noopener noreferrer"&gt;react-jsonschema-form&lt;/a&gt;) and &lt;a href="https://github.com/vazco/uniforms" rel="noopener noreferrer"&gt;Uniforms&lt;/a&gt; deliver on that promise for small to medium forms. But once forms become &lt;strong&gt;dynamic, state-dependent, or large&lt;/strong&gt;, teams start hitting the same architectural limits again and again.&lt;/p&gt;

&lt;p&gt;This article explains &lt;em&gt;why&lt;/em&gt; those problems occur and how &lt;a href="https://github.com/surveyjs" rel="noopener noreferrer"&gt;SurveyJS Form Library&lt;/a&gt; approaches the problem differently and separates business logic from rendering by introducsing &lt;code&gt;survey-core&lt;/code&gt;, a platform-independent survey model for SurveyJS Form Library and &lt;code&gt;survey-react-ui&lt;/code&gt;, a React-specific UI rendering package.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Architectural Difference
&lt;/h2&gt;

&lt;p&gt;Before diving into specific issues, it's important to understand the root cause.&lt;/p&gt;

&lt;h3&gt;
  
  
  React JSON Schema Forms
&lt;/h3&gt;

&lt;p&gt;React JSON Schema libraries treat the schema as both structure and behavior. They rely on schema mutation (&lt;code&gt;dependencies&lt;/code&gt;, &lt;code&gt;oneOf&lt;/code&gt;, dynamically regenerated schemas) and depend heavily on React re-renders to apply logic. Most of the problems below stem directly from that distinction.&lt;/p&gt;

&lt;h3&gt;
  
  
  SurveyJS
&lt;/h3&gt;

&lt;p&gt;SurveyJS takes a different approach: JSON is treated as a &lt;strong&gt;declarative model&lt;/strong&gt;, business logic is encapsulated in the form engine (&lt;code&gt;survey-core&lt;/code&gt;), and &lt;strong&gt;React is used only for rendering&lt;/strong&gt;, not orchestration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conditional Logic: When Schema Mutation Meets React State
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem in react-jsonschema-form
&lt;/h3&gt;

&lt;p&gt;In RJSF, conditional fields are typically implemented using &lt;code&gt;dependencies&lt;/code&gt;, &lt;code&gt;oneOf&lt;/code&gt;, or dynamically regenerated schemas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;hasCar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;hasCar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;oneOf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;hasCar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;const&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;carModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;hasCar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;const&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;em&gt;works&lt;/em&gt;, but only as long as the schema never changes shape unexpectedly. In React JSON Schema forms, the schema is not just a description of fields - it is the form itself. Using &lt;code&gt;dependencies&lt;/code&gt;, &lt;code&gt;oneOf&lt;/code&gt;, or &lt;code&gt;anyOf&lt;/code&gt; dynamically switches schema branches at runtime. From React's perspective, fields are added or removed, the internal form tree changes shape, and previously mounted inputs may unmount and remount.&lt;/p&gt;

&lt;p&gt;This is manageable when the schema is static, conditionals are simple, and no external data influences the schema. But real product forms often need feature flags, backend-driven configuration, role-based visibility, and progressive disclosure. &lt;/p&gt;

&lt;p&gt;As soon as the schema is modified dynamically (for example, regenerated in a &lt;code&gt;useEffect&lt;/code&gt;), React sees it as a new form definition, not a continuation of the previous one. That's when input state, defaults, and validation can reset in surprising ways.&lt;/p&gt;

&lt;p&gt;React JSON Schema form libraries also rely on React's render cycle to coordinate behavior. A field change updates &lt;code&gt;formData&lt;/code&gt;, triggering a re-render, which may cause a different schema branch to be selected and then validated. This chain only works when updates happen in perfect order. React may batch updates or re-render components opportunistically, which can lead to flickering fields, disappearing validation messages, or inputs losing focus. None of this is a React bug—it is a consequence of encoding business logic into the render cycle.&lt;/p&gt;

&lt;p&gt;Real-world forms often rebuild schemas in &lt;code&gt;useEffect&lt;/code&gt; to handle multiple fields, derived values, or async data. This leads to lost state, broken validation, and brittle logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  How SurveyJS Handles Conditional Logic
&lt;/h3&gt;

&lt;p&gt;SurveyJS does &lt;strong&gt;not mutate schemas&lt;/strong&gt; to express behavior.&lt;/p&gt;

&lt;p&gt;Instead, conditions are &lt;strong&gt;runtime expressions&lt;/strong&gt; evaluated by &lt;code&gt;survey-core&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;carModel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;visibleIf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{hasCar} = true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key idea is that the &lt;strong&gt;schema stays static&lt;/strong&gt;: the form's structure is defined once and treated as a durable contract rather than something that changes in response to user interaction. Fields are never removed or recreated; they always exist in the model, giving the engine a stable reference point. Visibility is evaluated at runtime by the engine, making field appearance deterministic and independent of React render timing.&lt;/p&gt;

&lt;p&gt;React is never asked to rebuild the form. It simply renders what the engine reports as visible or active. State changes trigger rule evaluation, not structural mutation, eliminating the need for schema regeneration, deep equality checks, or defensive memoization. This separation allows SurveyJS to handle complex conditional logic, large schemas, and frequent state changes without becoming fragile.&lt;/p&gt;

&lt;p&gt;Conditional logic in SurveyJS is therefore predictable, composable, and scalable across even very large forms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validation: Why Errors Disappear in Schema-Based React Forms
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem in RJSF (and Uniforms)
&lt;/h3&gt;

&lt;p&gt;Validation in React JSON Schema forms is typically delegated to Ajv and mapped back into React state. Teams often encounter issues such as disappearing errors after schema updates, async validation racing with renders, and complex cross-field validation requiring custom plumbing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;
  &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;onError&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The underlying problem isn't Ajv—it's that validation is &lt;strong&gt;tied to React render cycles&lt;/strong&gt;. Any schema or state change risks resetting the error tree.&lt;/p&gt;

&lt;h3&gt;
  
  
  How SurveyJS Handles Validation
&lt;/h3&gt;

&lt;p&gt;SurveyJS treats validation as a first-class engine concern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;isRequired&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;validators&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validation runs independently of React, errors are persisted in the survey model, and cross-field or async validation are built-in. Moving validation out of React removes the need to sequence &lt;code&gt;setState&lt;/code&gt; calls, debounce validation manually, or reconcile async results with rendering. Complex rules stay readable because they are declared close to the fields they affect, rather than scattered across component logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Schema Updates on State Change: The Hidden Cost of "Dynamic Schemas"
&lt;/h2&gt;

&lt;p&gt;In RJSF, changing the schema usually means &lt;strong&gt;replacing the schema object&lt;/strong&gt;, often in a &lt;code&gt;useEffect&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSchema&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseSchema&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;advanced&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;advancedSchema&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern causes full form reinitialization, loss of user input, validation resets, and performance degradation. Teams often add memoization, deep merges, or schema diffing to compensate, which adds complexity.&lt;/p&gt;

&lt;p&gt;SurveyJS avoids schema updates entirely. Instead, the schema is static and behavior changes—such as conditional visibility, required fields, or validation—are handled through runtime expressions. React simply renders what the engine reports as active. This separation ensures predictable behavior, maintains user input, preserves validation state, and improves performance for large forms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance with Large Schemas: When React Becomes the Bottleneck
&lt;/h2&gt;

&lt;p&gt;Large JSON schemas in React forms often hit serious performance limits: initial renders are slow, deep comparisons on re-renders are expensive, and single-field updates can trigger unnecessary renders elsewhere. Uniforms and RJSF perform well for small forms but struggle at scale.&lt;/p&gt;

&lt;p&gt;SurveyJS was designed for &lt;strong&gt;large forms&lt;/strong&gt; from the ground up. It uses incremental rendering, dependency-based updates, and lazy loading of pages and questions. React only renders currently visible questions, and only affected fields re-evaluate, which dramatically reduces unnecessary re-renders and improves performance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Survey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;survey-react-ui&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;surveyJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;SurveyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;survey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;surveyJson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Survey&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;survey&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Behind the scenes, the engine handles visibility conditions, dynamic rules, and validation in real time, without diffing the entire schema. You can explore a real-world demo here: &lt;a href="https://surveyjs.io/form-library/examples/lazy-loading/reactjs" rel="noopener noreferrer"&gt;Content-Heavy JSON Forms&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  SurveyJS Architecture: Why This Works
&lt;/h2&gt;

&lt;p&gt;SurveyJS clearly separates business logic from rendering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;survey-core&lt;/code&gt; — a platform-independent survey model for SurveyJS Form Library &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;survey-react-ui&lt;/code&gt; — a React-specific form renderer
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;survey-creator-core&lt;/code&gt; — a platform-independent data model for &lt;a href="https://surveyjs.io/survey-creator/documentation/overview" rel="noopener noreferrer"&gt;SurveyJS Survey Creator&lt;/a&gt;, a drag-and-drop form builder&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;survey-creator-react&lt;/code&gt; — a React-specific Survey Creator UI renderer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;React itself is never responsible for evaluating conditions, managing validation state, or coordinating schema changes. You can read more here: &lt;a href="https://surveyjs.io/documentation/surveyjs-architecture" rel="noopener noreferrer"&gt;SurveyJS Architecture&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When Product Teams Choose SurveyJS
&lt;/h2&gt;

&lt;p&gt;SurveyJS is a better fit when forms are long-lived, conditional logic is central, performance matters at scale, non-trivial validation is required, or schema mutation becomes a maintenance burden. React JSON Schema forms are still valuable, but SurveyJS is designed for &lt;strong&gt;what they struggle with most&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Most issues attributed to "React JSON Schema form" aren't implementation bugs—they're architectural limits.&lt;/p&gt;

&lt;p&gt;SurveyJS solves these problems by moving form intelligence out of React, letting product engineers focus on features instead of fighting render cycles.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>react</category>
      <category>json</category>
    </item>
    <item>
      <title>An open-source library to create dynamic JSON schema forms in your React application</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Tue, 13 Jan 2026 21:53:00 +0000</pubDate>
      <link>https://forem.com/surveyjs/an-open-source-library-to-create-dynamic-json-schema-forms-in-your-react-application-3flg</link>
      <guid>https://forem.com/surveyjs/an-open-source-library-to-create-dynamic-json-schema-forms-in-your-react-application-3flg</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/_surveyjs" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__org__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F9626%2F06b7ed19-dc54-4d69-b7f0-27a51713d7cf.png" alt="_SurveyJS" width="800" height="800"&gt;
      &lt;div class="ltag__link__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F863112%2Fc86654ef-e30a-4859-aa34-d4d15bc4dcdc.png" alt="" width="800" height="800"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/_surveyjs/custom-form-builder-for-react-applications-2a12" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Custom Form Builder for React Applications&lt;/h2&gt;
      &lt;h3&gt;SurveyJS for _SurveyJS ・ Jan 13&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#frontend&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tooling&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>react</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Custom Form Builder for React Applications</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Tue, 13 Jan 2026 21:33:10 +0000</pubDate>
      <link>https://forem.com/_surveyjs/custom-form-builder-for-react-applications-2a12</link>
      <guid>https://forem.com/_surveyjs/custom-form-builder-for-react-applications-2a12</guid>
      <description>&lt;p&gt;Building forms in React often starts simple but quickly becomes complex as requirements grow. Validation rules, conditional logic, dynamic fields, and enterprise constraints can turn handcrafted forms into hard-to-maintain code. SurveyJS provides a custom form builder for React applications that solves these challenges by enabling dynamic, schema-driven forms while keeping developers fully in control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built for Developers Who Need Dynamic Forms in React
&lt;/h2&gt;

&lt;p&gt;SurveyJS is designed for developers building applications where forms are not static. Instead of hardcoding inputs and rules, forms are defined as JSON and rendered dynamically at runtime.&lt;/p&gt;

&lt;p&gt;SurveyJS is a good fit for teams that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build dynamic forms that change frequently&lt;/li&gt;
&lt;li&gt;Need a custom form builder embedded into their own React applications&lt;/li&gt;
&lt;li&gt;Want a developer-first solution without SaaS lock-in or hosted data storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because SurveyJS is delivered as JavaScript libraries, &lt;a href="https://surveyjs.io/survey-creator/documentation/get-started-react" rel="noopener noreferrer"&gt;it integrates directly into your codebase&lt;/a&gt; and development workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Dynamic Forms from JSON Schemas
&lt;/h2&gt;

&lt;p&gt;SurveyJS uses a JSON schema to describe the structure and behavior of a form. This schema defines questions, layouts, validation rules, and logic in a clear, structured format.&lt;/p&gt;

&lt;p&gt;With SurveyJS, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create reusable schemas shared across applications&lt;/li&gt;
&lt;li&gt;Store schemas in your own database (&lt;a href="https://surveyjs.io/documentation/backend-integration" rel="noopener noreferrer"&gt;Learn more about Backend integration&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Generate forms at runtime using &lt;a href="https://surveyjs.io/form-library/documentation/overview" rel="noopener noreferrer"&gt;SurveyJS form rendering component&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Update forms without redeploying your React app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the schema is platform-agnostic, the same form definition can be reused with different front-end frameworks while preserving consistent behavior. SurveyJS offers dedicated npm packages for Angular, React, Vue, and VanillaJS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designed for Modern React Applications
&lt;/h2&gt;

&lt;p&gt;SurveyJS provides dedicated React components that integrate cleanly into modern React applications. Forms are rendered as part of your component tree and work naturally with existing layouts and routing.&lt;/p&gt;

&lt;p&gt;Key integration benefits include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compatibility with React hooks and modern state patterns&lt;/li&gt;
&lt;li&gt;Smooth behaviour in single-page applications (SPAs)&lt;/li&gt;
&lt;li&gt;A framework-agnostic core that separates form logic from the UI layer (&lt;a href="https://surveyjs.io/documentation/surveyjs-architecture" rel="noopener noreferrer"&gt;Learn more about SurveyJS architecture&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This architecture allows SurveyJS forms to remain portable and maintainable over time.&lt;/p&gt;

&lt;p&gt;Advanced Logic and Validation Without Hardcoding&lt;/p&gt;

&lt;p&gt;One of SurveyJS’s strengths is its ability to handle complex form logic declaratively. Instead of writing conditional logic in React components, rules are defined directly in the schema like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;json

[
  ...,
{
    "name": "textlengthvalidator",
    "type": "comment",
    "title": "Text Length Validator",
    "description": "Enter text no shorter than 10 and no longer than 280 symbols",
    "isRequired": true,
    "validators": [{
      "type": "text",
      "minLength": 10,
      "maxLength": 280
    }]
  },
...
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SurveyJS offers a GUI for configuring form logic and supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conditional logic for dynamic visibility &lt;/li&gt;
&lt;li&gt;&lt;a href="https://surveyjs.io/form-library/examples/javascript-form-validation/reactjs" rel="noopener noreferrer"&gt;Built-in validation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://surveyjs.io/form-library/documentation/data-validation#implement-custom-client-side-validation" rel="noopener noreferrer"&gt;Support for custom client-side validation rules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://surveyjs.io/form-library/documentation/design-survey/conditional-logic#calculated-values" rel="noopener noreferrer"&gt;Calculated fields and expressions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cross-field dependencies using expression syntax&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By centralizing logic in the schema, SurveyJS reduces code complexity and improves consistency across forms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fully Customizable and White-Label
&lt;/h2&gt;

&lt;p&gt;SurveyJS is designed to be fully integrated and customized. It offers &lt;em&gt;white-label usage and does not impose SurveyJS branding&lt;/em&gt; or fixed UI constraints, making it suitable for white-label products.&lt;/p&gt;

&lt;p&gt;Customization options allow developers to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create &lt;a href="https://surveyjs.io/form-library/documentation/customize-question-types/question-customization-options" rel="noopener noreferrer"&gt;custom fields and question types&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Extend functionality with custom widgets (&lt;a href="https://surveyjs.io/survey-creator/examples/form-builder-with-integrated-rich-text-editor/reactjs" rel="noopener noreferrer"&gt;This example shows how to integrate a 3rd-rarty rich content editor&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Localize the form builder UI to any language&lt;/li&gt;
&lt;li&gt;Integrate forms into existing design systems and apply &lt;a href="https://surveyjs.io/survey-creator/examples/add-custom-theme/reactjs" rel="noopener noreferrer"&gt;full UI theming using custom CSS&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This flexibility makes SurveyJS suitable for both internal tools and customer-facing applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  You Stay in Control of Your Data
&lt;/h2&gt;

&lt;p&gt;SurveyJS is a self-hosted solution. It does not collect, store, or process user data on your behalf.&lt;/p&gt;

&lt;p&gt;With SurveyJS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All form data stays in your application&lt;/li&gt;
&lt;li&gt;You control backend integration and data flow&lt;/li&gt;
&lt;li&gt;There is no built-in or external data storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach is especially important for organizations with strict security, privacy, or compliance needs.&lt;/p&gt;

&lt;p&gt;The team offer &lt;a href="https://surveyjs.io/backend-integration/examples" rel="noopener noreferrer"&gt;several examples to help you integrate SurveyJS components with your backend system&lt;/a&gt;. Examples are available for PHP, ASP.NET, and Node.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  How SurveyJS Compares to Other React Form Builders
&lt;/h2&gt;

&lt;p&gt;Many React form solutions focus on managing form state and validation at the component level. While effective for simple use cases, these tools often require significant custom code for dynamic or schema-driven forms.&lt;/p&gt;

&lt;p&gt;Compared to typical alternatives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SurveyJS provides a schema-based form builder, not just a form library&lt;/li&gt;
&lt;li&gt;Business logic lives in configuration rather than React code&lt;/li&gt;
&lt;li&gt;It scales better for complex and evolving requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For teams looking for an open-source, dynamic, and scalable form solution SurveyJS offers a balance: a developer-friendly open-source architecture with enterprise-ready capabilities, making it a strong enterprise form builder for React applications.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>react</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Top Customizable Survey Software You Shouldn't Miss</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Wed, 25 Sep 2024 12:55:13 +0000</pubDate>
      <link>https://forem.com/_surveyjs/top-customizable-survey-software-you-shouldnt-miss-1k4c</link>
      <guid>https://forem.com/_surveyjs/top-customizable-survey-software-you-shouldnt-miss-1k4c</guid>
      <description>&lt;p&gt;When it comes to managing surveys, having full control over your data is crucial. Relying on third-party platforms often means facing limitations in customization, data storage, or integration. DIY survey software allows you to create, manage, and analyze your surveys without compromise. These tools give you the flexibility to design forms that suit your exact needs while ensuring your data remains secure. Here’s a rundown of six web-based customizable survey tools, each with its own strengths in form creation, survey filling, data analysis, pricing, and accessibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. SurveyJS
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frec8dfcob15ewvf7tdp1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frec8dfcob15ewvf7tdp1.png" alt="SurveyJS - customizable survey software" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;SurveyJS is an open-source, &lt;a href="https://surveyjs.io/" rel="noopener noreferrer"&gt;highly customizable survey software&lt;/a&gt; with a focus on flexibility and ease of integration into modern web applications. SurveyJS &lt;strong&gt;client JavaScript libraries&lt;/strong&gt; &lt;a href="https://surveyjs.io/form-library/documentation/overview#get-started" rel="noopener noreferrer"&gt;support every common front-end framework&lt;/a&gt; that you could imagine, and even the ones you couldn't. It's even more flexible when it comes to the backend - you can &lt;a href="https://surveyjs.io/documentation/backend-integration" rel="noopener noreferrer"&gt;integrate with any backend system of your choice&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Creation
&lt;/h3&gt;

&lt;p&gt;The form management platform offers a visual form builder, allowing non-tech users to build forms quickly. Its drag-and-drop interface simplifies form setup, and it supports custom themes and layouts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Filling
&lt;/h3&gt;

&lt;p&gt;With responsive designs and mobile optimization, forms are easy to fill out on any device. SurveyJS also supports complex conditions, allowing for dynamic changes based on user input.&lt;/p&gt;

&lt;h3&gt;
  
  
  Survey Data Analysis
&lt;/h3&gt;

&lt;p&gt;SurveyJS offers a &lt;a href="https://surveyjs.io/dashboard/documentation/overview" rel="noopener noreferrer"&gt;Dashboard library&lt;/a&gt; that enables users to analyze survey results using various customizable charts and tables. It provides real-time feedback, so responses can be analyzed instantly. You have complete control over your data, allowing you to sync it with platforms like Google Sheets or your company’s business insights tools. &lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing
&lt;/h3&gt;

&lt;p&gt;SurveyJS offers a flexible pricing model &lt;a href="https://github.com/surveyjs" rel="noopener noreferrer"&gt;by publishing its libraries on GitHub&lt;/a&gt; for free trial use. The survey rendering library is MIT licensed, allowing free use even for commercial purposes. However, for products like Survey Creator, a 'Basic' license costs around $499. For the Survey Creator, Dashboard and PDF Generator, you'll need a 'Pro' license at $899. Commercial licenses are perpetual, but access to updates requires an annual renewal. It’s ideal for both small businesses and large enterprises as it imposes no usage limitations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility
&lt;/h3&gt;

&lt;p&gt;This survey tool prioritizes accessibility, &lt;a href="https://surveyjs.io/accessibility-statement" rel="noopener noreferrer"&gt;adhering to WCAG guidelines&lt;/a&gt; to ensure that forms are usable by everyone, including those with disabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. LimeSurvey
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ln4buc37b9xafbp8yuw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ln4buc37b9xafbp8yuw.png" alt="LimeSurvey — Free Online Survey Tool" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;LimeSurvey offers an all-in-one solution for the entire form lifecycle, from building and publishing to collecting and analyzing results. It’s a great option for those who want to get started quickly without managing backend infrastructure. However, it does involve sending user data to a third-party platform, meaning less control over backend technology and potential difficulties integrating with existing authentication systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Creation
&lt;/h3&gt;

&lt;p&gt;Though slightly less intuitive than some of the others, LimeSurvey offers a rich set of question types. However, its user interface can feel outdated and more suited to advanced users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Filling
&lt;/h3&gt;

&lt;p&gt;LimeSurvey offers a simple form-filling UI with responsive validation after publishing, but customization options are limited unless you self-host. Self-hosting allows you to apply custom CSS, but it requires significant development work and affects all forms. It's a great choice for users seeking a ready-made solution but less ideal for those who need extensive design flexibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Survey Data Analysis
&lt;/h3&gt;

&lt;p&gt;LimeSurvey excels in data analysis, with strong export options and built-in reporting features. The reporting is detailed, making it a solid choice for data-heavy projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing
&lt;/h3&gt;

&lt;p&gt;LimeSurvey offers a free, open-source 'community' edition for self-hosting, which can be complex to set up. For easier use, their cloud hosting service starts at 23€ per month (billed annually) for 10,000 responses annually, with higher plans reaching 58€ per month (billed annually) for 100,000 responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility
&lt;/h3&gt;

&lt;p&gt;It is compliant with major accessibility standards, but some users find that its default templates may require additional customization to be fully accessible.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Formium (by Formik)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4oee5k25gzyrw4sgiv4c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4oee5k25gzyrw4sgiv4c.png" alt="Formium - Headless Form Builder For Developers" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Formium originated from the React library Formik, designed to simplify form creation in React by providing components that streamline initial values and validation processes. Building on Formik's success, Formium introduced an online form builder platform comprising an online form interface, SDKs for integrating forms into React applications, and a robust submission and storage system that connects with Zapier for automation. However, &lt;strong&gt;Formium appears largely unmaintained&lt;/strong&gt;, with no updates to its SDK in three years and unanswered issues on GitHub, raising concerns about its future viability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Creation
&lt;/h3&gt;

&lt;p&gt;Formium features a user-friendly logic editor that allows users to set rules for form interactions, similar to SurveyJS, by specifying criteria for fields and defining actions, primarily limited to showing or hiding questions. However, its functionality is quite basic, lacking advanced features such as copying answers between questions or making fields conditionally required, and it does not offer tools for multilingual support, necessitating additional manual effort for translations; while the form editor is intuitive, users may feel frustrated by the absence of more comprehensive features that are yet to be implemented.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Filling
&lt;/h3&gt;

&lt;p&gt;Formium offers two options for form display: a built-in form viewer on their online platform that is clean and user-friendly, and a React SDK that allows for simple rendering of forms with customizable components, providing significant flexibility for developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Survey Data Analysis
&lt;/h3&gt;

&lt;p&gt;Formium allows users to send form submission results for storage and processing, but its dashboard lacks data visualization tools, requiring users to manually download CSV files to create graphs. While it offers 'workflows' for connecting to third-party services like Slack, email, or webhooks upon submission, any complex workflows must be managed through Zapier, which is a separate paid service not included natively in SurveyJS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing
&lt;/h3&gt;

&lt;p&gt;Formium has a pricing model based on form submissions, which can be a drawback for larger surveys or those with high respondent counts. The lowest tier starting at $20 per month for 25 forms and 1,000 monthly submissions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility
&lt;/h3&gt;

&lt;p&gt;The platform allows developers to create accessible forms, though out-of-the-box accessibility depends on the developer's implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Form.io
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0ys28cre19ji63gsu2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0ys28cre19ji63gsu2g.png" alt="Form.io - Data Governance Platform" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Form.io offers a comprehensive suite of tools for building, publishing, and managing forms, providing both front-end and back-end solutions to meet various user needs. Their products are delivered as Docker containers for easy deployment in your own environment, while also offering a hosted SaaS solution that, although lacking some features of the self-hosted option, allows users to quickly get started with form management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Creation
&lt;/h3&gt;

&lt;p&gt;Its form builder is feature-rich and allows for the creation of highly complex forms. The drag-and-drop interface is intuitive, but the learning curve can be steep due to the variety of options.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Filling
&lt;/h3&gt;

&lt;p&gt;Forms built with Form.io are responsive and efficient, though customization often requires a developer’s input for fine-tuning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Survey Data Analysis
&lt;/h3&gt;

&lt;p&gt;Form.io's basic product lacks comprehensive reporting functionality, allowing only data exports as spreadsheets without native graphing capabilities; users can purchase a separate reporting module for $600 per month, which still offers limited reporting options. However, Form.io provides a robust developer interface for integrating form results with third-party services, including pre-built integrations like a SQL connector to sync data with custom SQL databases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing
&lt;/h3&gt;

&lt;p&gt;Form.io's pricing model is primarily based on deployment rather than usage, starting at $600 per month for one enterprise-level project and API server management, with an additional $300 per month for enhanced security compliance features. Their hosted SaaS version costs $300 per month, offering unlimited forms but capping submissions at 1 million per month and 1,000 monthly PDF downloads, after which they encourage users to consider self-hosted options; both self-hosted and cloud versions can be trialed for 30 days, though accessing the self-hosted trial requires scheduling a sales call.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility
&lt;/h3&gt;

&lt;p&gt;Form.io offers an accessibility compliance module aimed at helping users create accessible forms, but charging extra for this feature is considered unfair since accessible design should be standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. FormEngine
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa01klhyxcun6p40x9oqq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa01klhyxcun6p40x9oqq.png" alt="Optimajet Drag and Drop Form Builder" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;FormEngine, developed by Optimajet as the successor to their original FormBuilder, provides a set of tools for building and deploying forms within React applications, featuring a Form Builder and a Form Viewer component. This front-end-only solution allows developers to integrate forms seamlessly into their existing applications while giving them the flexibility to manage data storage according to their preferences.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Creation
&lt;/h3&gt;

&lt;p&gt;FormEngine requires integration into a React application, limiting its use to that framework. While it offers a customizable drag-and-drop interface for building forms, the complexity of implementing rules and actions - such as showing or hiding fields based on responses - makes it less accessible for non-technical users; these features rely on programming references rather than a user-friendly interface, which could be a barrier for those unfamiliar with coding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Filling
&lt;/h3&gt;

&lt;p&gt;The forms are fast-loading and optimized for mobile, ensuring a positive user experience across all devices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Survey Data Analysis
&lt;/h3&gt;

&lt;p&gt;FormEngine lacks built-in solutions for accessing and visualizing form submission results, leaving users to manage and process their data independently; although Optimajet offers a separate product called WorkflowEngine for data processing, it does not integrate natively with FormEngine and incurs additional costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing
&lt;/h3&gt;

&lt;p&gt;FormEngine offers two payment options: a perpetual license starting at approximately $899, which includes six months of updates and two months of support, allowing users to maintain the same version indefinitely; or a subscription model at around $1,499 per year, providing access across all subdomains and continuous updates as long as the subscription is active, with additional pricing options available for further inquiries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility
&lt;/h3&gt;

&lt;p&gt;FormEngine prioritises accessibility by ensuring their entire UI is keyboard accessible and incorporating &lt;code&gt;aria&lt;/code&gt; labels throughout the application. This ensures that screen reader users can navigate and interact with the platform fully.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Tripetto
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2c0xv6qpqpexvlk2d0a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2c0xv6qpqpexvlk2d0a.png" alt="Tripetto - Give life to forms and surveys" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Tripetto is a visual survey tool that stands out for its unique flowchart-based form builder. It’s designed for building conversational-style forms and surveys.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Creation
&lt;/h3&gt;

&lt;p&gt;Tripetto’s flowchart interface allows users to create forms that feel more dynamic and interactive. It is especially useful for creating surveys with a conversational feel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Form Filling
&lt;/h3&gt;

&lt;p&gt;Tripetto allows users to customize form colors, fonts, and choose from various ‘form faces’ that dramatically alter the form's appearance and functionality. While the ‘autoscroll’ face resembles Typeform and can feel gimmicky, the ‘chat’ face offers an engaging design but lacks practicality. The ‘classic’ face is the most user-friendly, providing a responsive experience with quick error feedback. Overall, Tripetto's form designs showcase a strong attention to detail and aesthetic appeal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Survey Data Analysis
&lt;/h3&gt;

&lt;p&gt;Tripetto does not offer any built-in solutions for accessing or visualizing form results after submission. Users must independently manage and analyze the submitted data without support from the platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing
&lt;/h3&gt;

&lt;p&gt;Tripetto offers several pricing options for its SDK. The cost for accessing the form runner is €900 per year, but this only covers one ‘form face’; additional licenses are required for each extra form face. If you also want to use the builder on your own webpages, the cheapest builder license is €699 per year, which includes standard question types and allows for five users. To enable custom question types, a more expensive builder license costing €3.900 per year is necessary. The most economical combination of the builder and runner licenses totals €1,599 per year.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility
&lt;/h3&gt;

&lt;p&gt;Tripetto lacks information on its accessibility practices, and unfortunately, the platform fails to meet basic accessibility standards. The editor is not effectively navigable via keyboard, and screen readers struggle due to missing or incorrect ARIA tags. While the forms are somewhat keyboard accessible, they deviate significantly from standard keyboard controls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Each of these tools brings something unique to the table. SurveyJS survey software excels in customization and seamless backend integration, while Form.io is ideal for users requiring comprehensive data management. LimeSurvey is perfect for research-heavy projects, thanks to its robust data analysis capabilities. Tripetto shines with its conversational style, but falls short in accessibility. Ultimately, assessing your priorities - be it customization, ease of use, data management, or cost - will guide you to the survey solution that best fits your needs.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Create a Poll and Visualize Collected Responses in Real Time</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Sat, 22 Apr 2023 16:19:51 +0000</pubDate>
      <link>https://forem.com/_surveyjs/how-to-create-a-poll-and-visualize-collected-responses-in-real-time-4bi3</link>
      <guid>https://forem.com/_surveyjs/how-to-create-a-poll-and-visualize-collected-responses-in-real-time-4bi3</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftjcwnpetlvtpnrmzxtd3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftjcwnpetlvtpnrmzxtd3.png" alt="Image by pch.vector on Freepik" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.freepik.com/free-vector/internet-electronic-voting_6974903.htm#query=polls&amp;amp;position=0&amp;amp;from_view=keyword&amp;amp;track=sph" rel="noopener noreferrer"&gt;Image by pch.vector&lt;/a&gt; on Freepik&lt;/p&gt;

&lt;p&gt;In this blog post, we will guide you through all the steps to build a poll with SurveyJS Form Library and then visualize the results that are being submitted in real time with SurveyJS Dashboard. Plus — a sample React demo inside.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Power of Conducting Polls
&lt;/h2&gt;

&lt;p&gt;Running a poll is an effective way to measure public opinion on a particular issue or topic. By asking a representative sample of the population a set of questions on their views, pollsters can gather an accurate and actionable snapshot of what people think. Polls can also help identify trends in public opinion over time. By conducting regular polls on a particular issue or topic, pollsters can track how people's views are changing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://surveyjs.io/stay-updated/blog/create-poll-and-visualize-results-with-chart-that-updates-in-real-time" rel="noopener noreferrer"&gt;Read the full post&lt;/a&gt; on SurveyJS blog. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Client-Side vs Server-Side Form Input Validation</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Tue, 18 Apr 2023 16:11:58 +0000</pubDate>
      <link>https://forem.com/_surveyjs/client-side-vs-server-side-form-input-validation-27lp</link>
      <guid>https://forem.com/_surveyjs/client-side-vs-server-side-form-input-validation-27lp</guid>
      <description>&lt;p&gt;Tired of dealing with invalid data submitted by users in your web forms? Then it's time for you to introduce input validation into your form creation workflow. In this article, we will explore pros and cons of client- and server-side validation features that SurveyJS has to offer, so that you can decide which one to use in your project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://surveyjs.io/stay-updated/blog/client-server-data-validation" rel="noopener noreferrer"&gt;Read the full article&lt;/a&gt; on SurveyJS blog. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>opensource</category>
      <category>react</category>
    </item>
    <item>
      <title>No-code Editor for Domain Models</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Mon, 03 Apr 2023 18:32:01 +0000</pubDate>
      <link>https://forem.com/_surveyjs/no-code-editor-for-domain-models-kgp</link>
      <guid>https://forem.com/_surveyjs/no-code-editor-for-domain-models-kgp</guid>
      <description>&lt;p&gt;&lt;a href="https://surveyjs.io/documentation/no-code-editor-for-domain-models" rel="noopener noreferrer"&gt;This article&lt;/a&gt; describes how SurveyJS can help streamline the form creation process in your team. The proposed solution allows you to generate client-side form code based on server-side domain models, and vice versa. Content creators who do not possess coding skills can edit the forms in a visual designer and deliver them to the end users without the need to involve the development team.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Form Input Validation: Ensure Valid, Meaningful, and Reliable Responses in Questionnaires and Online Forms</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Thu, 23 Mar 2023 08:44:16 +0000</pubDate>
      <link>https://forem.com/_surveyjs/form-input-validation-ensure-valid-meaningful-and-reliable-responses-in-questionnaires-and-online-forms-h74</link>
      <guid>https://forem.com/_surveyjs/form-input-validation-ensure-valid-meaningful-and-reliable-responses-in-questionnaires-and-online-forms-h74</guid>
      <description>&lt;p&gt;Learn how to design an effective questionnaire and configure form field validation to improve the quality of your survey results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjji0928f0i2589t8li2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjji0928f0i2589t8li2f.png" alt="SurveyJS: Form Input Validation" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A thoughtfully designed questionnaire can improve its completion rate and deliver a positive user experience. If your survey is clear and well structured, and questions are concise, survey takers will be willing to provide relevant and actionable data that you can use to derive valuable insights.&lt;/p&gt;

&lt;p&gt;But how do you accomplish this? How do you organize an online questionnaire that doesn't overwhelm respondents and instead makes their experience enjoyable?&lt;/p&gt;

&lt;h4&gt;
  
  
  Proper Completion Time
&lt;/h4&gt;

&lt;p&gt;Designing a questionnaire requires careful consideration of various factors. One of them is &lt;strong&gt;completion time&lt;/strong&gt;, especially when it comes to online surveys. To maximize participation rates, limit the survey to no more than 10 minutes, or even shorter for mobile device users - around 7 minutes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Suitable Question Types
&lt;/h4&gt;

&lt;p&gt;Another critical aspect is selecting appropriate question types to ensure that the data collected will be suitable for further analysis and visual representation. Please refer to the &lt;a href="https://medium.com/@surveyjs/how-to-create-an-effective-survey-poll-or-quiz-and-increase-its-completion-rate-cce30282659f" rel="noopener noreferrer"&gt;How to Create an Effective Survey, Poll, or Quiz, and Increase its Completion Rate&lt;/a&gt; article to find out more on this topic.&lt;/p&gt;

&lt;h4&gt;
  
  
  Relevant Responses
&lt;/h4&gt;

&lt;p&gt;Data validity is another key factor to consider when designing a questionnaire. To ensure reliable data, identify the types of data you &lt;strong&gt;want&lt;/strong&gt; and &lt;strong&gt;do not want&lt;/strong&gt; to receive. This approach can help avoid uncertainties by clarifying the data expected from respondents. &lt;/p&gt;

&lt;p&gt;Different fields require different types of validation: validation for mandatory fields, numeric range validation for age or weight values, and file type validation for uploads in a specific file format, such as PDF, JPEG, or MP4.&lt;/p&gt;

&lt;p&gt;Using &lt;a href="https://surveyjs.io/" rel="noopener noreferrer"&gt;SurveyJS&lt;/a&gt;, you can apply these and other data validation settings to your survey questions, ensuring that respondents provide accurate and reliable data. In the following sections, we will review some possible data validation options available with SurveyJS, which can help improve the quality of your survey data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Form Input Validation with SurveyJS
&lt;/h2&gt;

&lt;p&gt;SurveyJS is an open-source JavaScript library for building complex forms and surveys in &lt;a href="https://surveyjs.io/form-library/documentation/overview" rel="noopener noreferrer"&gt;React, Angular, Vue.js, Knockout, and jQuery&lt;/a&gt;. SurveyJS offers a variety of input validation options that can help ensure that respondents provide valid answers. &lt;/p&gt;

&lt;h3&gt;
  
  
  Mandatory Questions
&lt;/h3&gt;

&lt;p&gt;Set the &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/question#isRequired" rel="noopener noreferrer"&gt;isRequired&lt;/a&gt; property value to &lt;code&gt;true&lt;/code&gt; to ensure that a user doesn't leave a question unanswered before submitting a survey.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "text",
  "name": "last-name",
  "title": "Last name",
  "isRequired": true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3a35n5rcq3bg1lpfkbu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3a35n5rcq3bg1lpfkbu5.png" alt="SurveyJS: Required Questions" width="800" height="312"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://surveyjs.io/form-library/examples/covid-19-screening-form-template/reactjs" rel="noopener noreferrer"&gt;Demo: COVID-19 Screening Form&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you use &lt;a href="https://surveyjs.io/form-library/examples/single-selection-matrix-table-question/reactjs" rel="noopener noreferrer"&gt;Single-Choice Matrix&lt;/a&gt; and you want to ensure that a user addresses all question in the rows, enable the &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/matrix-table-question-model#isAllRowRequired" rel="noopener noreferrer"&gt;isAllRowRequired&lt;/a&gt; option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ppxb8myyv2li5tdqbji.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ppxb8myyv2li5tdqbji.png" alt="SurveyJS: Required Matrix Rows" width="800" height="378"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://surveyjs.io/form-library/examples/single-selection-matrix-table-question/reactjs" rel="noopener noreferrer"&gt;Demo: Single-Selection Matrix&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Restrict the Number of Choices to Select
&lt;/h3&gt;

&lt;p&gt;If you want to limit the number of choice options a respondent can select in Multiple-Selection &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/checkbox-question-model" rel="noopener noreferrer"&gt;Checkbox&lt;/a&gt; and &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/dropdown-tag-box-model#maxSelectedChoices" rel="noopener noreferrer"&gt;TagBox&lt;/a&gt; questions, you can use the &lt;code&gt;maxSelectedChoices&lt;/code&gt; property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "checkbox",
  "name": "product-aspects",
  "title": "Key Features",
  "description": "These are some important aspects of the product. Select three features you find most important.",
  "choices": [
    "Technical support",
    "Price",
    "Delivery option",
    "Quality",
    "Ease of use",
    "Product warranties"
  ],
  "maxSelectedChoices": 3
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once a user selects the maximum number of items allowed, further selection is disabled for that question.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7na6qir7v40f720iulim.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7na6qir7v40f720iulim.png" alt="SurveyJS: Limit Selected Choices" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Numeric Ranges
&lt;/h3&gt;

&lt;p&gt;You can use the &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; properties to set numeric ranges for questions that require a numerical input type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "number",
  "type": "text",
  "title": "Enter a number from 0 to 100",
  "inputType": "number",
  "min": 0,
  "max": 100,
  "defaultValue": 0,
  "isRequired": true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lzhzz9hn84za9r18oam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lzhzz9hn84za9r18oam.png" alt="SurveyJS: Numeric Range Validation" width="800" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://surveyjs.io/form-library/examples/numeric-entry-question/reactjs" rel="noopener noreferrer"&gt;Demo: Numeric Entry&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Text Length
&lt;/h3&gt;

&lt;p&gt;By setting the minimum or maximum length values for text entry fields, you can control the number of characters users can enter. &lt;/p&gt;

&lt;p&gt;The minimum text length value can help ensure that users provide enough data and prevent them from submitting invalid and eventually useless responses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "comment",
  "name": "service_improvements",
  "title": "How can we improve our service?",
  "validators": [
    {
      "type": "text",
      "text": "Please provide more information",
      "minLength": 10
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr52ncduz5qszxt0zm0lq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr52ncduz5qszxt0zm0lq.png" alt="SurveyJS: Minimum Text Length Validation" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Setting the maximum text length value, on the other hand, can help prevent users from submitting redundant details in their answers. This will keep survey responses concise and focused on relevant information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "comment",
  "name": "service_improvements",
  "title": "How can we improve our service?",
  "maxLength": 100
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc3372lou75isgkc0vm6n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc3372lou75isgkc0vm6n.png" alt="SurveyJS: Maximum Text Length Validation" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Maximum File Size
&lt;/h3&gt;

&lt;p&gt;You can limit the size of files that can be uploaded as responses to questions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "file",
  "title": "Please upload your files",
  "name": "files",
  "storeDataAsText": false,
  "allowMultiple": true,
  "maxSize": 102400
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsg837bq3ce8xbx307ts.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftsg837bq3ce8xbx307ts.png" alt="SurveyJS: Upload File Size" width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://surveyjs.io/form-library/examples/file-upload/reactjs#content-code" rel="noopener noreferrer"&gt;Demo: File question - Upload Files to a Server&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Accepted File Types
&lt;/h3&gt;

&lt;p&gt;When configuring a File question type, use the &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/file-model#acceptedTypes" rel="noopener noreferrer"&gt;acceptedTypes&lt;/a&gt; property to restrict the file types that can be uploaded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regular Expressions
&lt;/h3&gt;

&lt;p&gt;You can use regular expressions to implement more sophisticated logic and validate such input values as email addresses, phone numbers, or passwords.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "user-password",
  "type": "text",
  "title": "Password",
  "inputType": "password",
  "description": "Enter a password that contains at least one upper-case, one lower-case letter, a digit, and a special character",
  "isRequired": true,
  "validators": [
    {
      "type": "regex",
      "regex": /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s)(?=.*[!-@#$*])/,
      "text": "Your password must contain at least one upper-case, one lower-case letter, a digit, and a special character"
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0isbdcxo5tyfysk40ql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0isbdcxo5tyfysk40ql.png" alt="SurveyJS: RegEx Text Validation" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://surveyjs.io/form-library/examples/javascript-form-validation/reactjs" rel="noopener noreferrer"&gt;Demo: Form Validation&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Validation Functions
&lt;/h3&gt;

&lt;p&gt;Validation functions can be useful in verifying more detailed responses. For instance, when it comes to email address, you may want to validate not only that the entered value conforms to the email format but also that it belongs to the domain of a specific company.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://surveyjs.io/form-library/examples/add-custom-input-validation/reactjs" rel="noopener noreferrer"&gt;Demo: Custom Form Validation Using an Event&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Server-Side Validation
&lt;/h3&gt;

&lt;p&gt;Use server-side validation in addition to client-side validation to prevent malicious submissions or errors. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://surveyjs.io/form-library/examples/javascript-server-side-form-validation/reactjs" rel="noopener noreferrer"&gt;Demo: Server-Side Form Validation Using an Event&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Consider the following recommendations to ensure that respondents provide accurate data while taking your survey.&lt;/p&gt;

&lt;h4&gt;
  
  
  Validate All Fields
&lt;/h4&gt;

&lt;p&gt;Ensure that all fields have validation on, including optional fields. This helps prevent incomplete submissions and errors and ensures that most of the information provided is valid.&lt;/p&gt;

&lt;h4&gt;
  
  
  Provide Help Text
&lt;/h4&gt;

&lt;p&gt;SurveyJS highlights a field with an error and displays an error message next to this field.&lt;/p&gt;

&lt;p&gt;In addition, you can customize error messages and provide clear instructions on fixing the error. Use plain language and avoid technical jargon.&lt;/p&gt;

&lt;h4&gt;
  
  
  Use Real-Time Validation
&lt;/h4&gt;

&lt;p&gt;Real-time validation helps users correct errors as they type rather than waiting until the form is submitted. Set the &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#checkErrorsMode" rel="noopener noreferrer"&gt;checkErrorsMode&lt;/a&gt; property to &lt;code&gt;onValueChanged&lt;/code&gt; to validate user responses as soon as users provide answers.&lt;/p&gt;

&lt;p&gt;Lastly, always test your survey with a small group of people (ideally - from the intended target group). This ensures that the survey is clear and easy to understand and can help detect and correct errors or ambiguities in questions and choice options before it reaches the main target audience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Designing effective surveys requires both skill and creativity. SurveyJS offers a wide selection of tools to help you create more engaging and insightful surveys and online forms.&lt;/p&gt;

</description>
      <category>inputvalidation</category>
      <category>validation</category>
      <category>surveying</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to create a Web Development Client Questionnaire with a TOC and add it to your JS application using SurveyJS.</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Thu, 16 Mar 2023 13:50:59 +0000</pubDate>
      <link>https://forem.com/_surveyjs/how-to-create-a-web-development-client-questionnaire-with-a-toc-navigation-and-add-it-to-your-js-application-using-surveyjs-58fl</link>
      <guid>https://forem.com/_surveyjs/how-to-create-a-web-development-client-questionnaire-with-a-toc-navigation-and-add-it-to-your-js-application-using-surveyjs-58fl</guid>
      <description>&lt;p&gt;A step-by-step guide on how to automate data collection from your clients with an on-page website intake form.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7phdv9dvvl3z0me6cw0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7phdv9dvvl3z0me6cw0.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s a web development client questionnaire?
&lt;/h2&gt;

&lt;p&gt;A web development, or a web design, client questionnaire is a website intake form that consists of a set of questions that a web developer asks their client to get a better understanding as to what their expectations are towards a website they are ordering, e.g. their goals, preferences, the timeline etc. A website intake form typically covers such topics as a client’s target audience, branding, design preferences, functionality requirements, content strategy, and budget. By gathering this information, a web developer can create a website mockup that addresses the client’s needs and ensures that the final product meets their expectations. A well-developed questionnaire can also help both sides save time, establish clear communication and prevent misunderstandings throughout the development process.&lt;/p&gt;

&lt;p&gt;Initially, client intake forms were in paper format. Nowadays, when the world is moving to digitalization and automation of any paper routine, it’s hard to imagine a web developer going to a client with a pen and a printed out paper form.&lt;/p&gt;

&lt;p&gt;In this article we are going to create a web design client questionnaire using &lt;a href="https://surveyjs.io/create-free-survey" rel="noopener noreferrer"&gt;a free full scale demo of the Survey Creator library&lt;/a&gt;. This demo tool will automatically generate a &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/survey-data-model" rel="noopener noreferrer"&gt;survey model&lt;/a&gt; for us that defines the contents and layout of a form in JSON format. You can then add this form to your website using &lt;a href="https://surveyjs.io/form-library" rel="noopener noreferrer"&gt;SurveyJS Form Library&lt;/a&gt; and have it rendered by any JavaScript framework you use. Once a form is incorporated into a page, you will be able to invite your customers to fill it out online right on your website, and then use the received results as a starting point in further more detailed discussion during a meeting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why choose SurveyJS Form Library to make a web form and collect responses?
&lt;/h2&gt;

&lt;p&gt;SurveyJS is a fast, versatile, free, and open-source (MIT license) &lt;a href="https://surveyjs.io/form-library" rel="noopener noreferrer"&gt;JavaScript client-side library&lt;/a&gt; for &lt;a href="https://surveyjs.io/form-library/documentation/get-started-react" rel="noopener noreferrer"&gt;React&lt;/a&gt;, &lt;a href="https://surveyjs.io/form-library/documentation/get-started-angular" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;, &lt;a href="https://surveyjs.io/form-library/documentation/get-started-vue" rel="noopener noreferrer"&gt;Vue.js&lt;/a&gt;, &lt;a href="https://surveyjs.io/form-library/documentation/get-started-knockout" rel="noopener noreferrer"&gt;Knockout&lt;/a&gt;, and &lt;a href="https://surveyjs.io/form-library/documentation/get-started-jquery" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt; that can be used to build forms and surveys of any complexity. It has a data-driven approach — fully dynamic surveys defined as JSON schemas, with templating for UI elements. SurveyJS renders a form on a page of your website, collects responses from users and sends the survey data to your database. Since all survey data is in industry-standard JSON format, the frontend and the backend are separated, so you can use &lt;a href="https://surveyjs.io/documentation/backend-integration" rel="noopener noreferrer"&gt;any server + database combination&lt;/a&gt; with it.&lt;/p&gt;

&lt;p&gt;SurveyJS allows for great customization and flexibility. You have total control over the look and feel of your forms — you can select from a variety of built-in themes and personalize them with custom CSS code. It also supports &lt;a href="https://surveyjs.io/form-library/examples/survey-localization/reactjs" rel="noopener noreferrer"&gt;automatic survey localization&lt;/a&gt; and the integration of third-party JavaScript components, such as &lt;a href="https://surveyjs.io/form-library/examples/custom-widget-bootstrapdatepicker/reactjs" rel="noopener noreferrer"&gt;bootstrap-datepicker&lt;/a&gt; or &lt;a href="https://surveyjs.io/form-library/examples/control-data-entry-formats-with-input-masks/reactjs" rel="noopener noreferrer"&gt;Inputmask&lt;/a&gt;, and many others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why self-host survey data instead of using online survey platforms?
&lt;/h2&gt;

&lt;p&gt;Self-hosting survey data — both survey contents and their results — has several benefits over using third-party survey platforms. One of the main benefits is increased control of the data flow between server and client without any third-party involved. Only you decide where and how the data is stored, who has access to it, and how it is transferred. This is especially important when it comes to handling sensitive or confidential commercial information, as it can help ensure the privacy and security of the data. With SurveyJS, you have full ownership of the survey data and can finally avoid using third-party black box SaaS platforms.&lt;/p&gt;

&lt;p&gt;Another important advantage is cost savings. Online survey platforms often charge a monthly fee for their services, which can add up over time. By self-hosting your survey data, you can avoid these fees at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions to ask in a Website Intake Form and best question types to choose
&lt;/h2&gt;

&lt;p&gt;Most of the questions in a website intake form are open-ended questions, meaning that they don’t have predefined choice options. Among the most popular open-ended question types that SurveyJS ships with is a &lt;a href="https://surveyjs.io/form-library/examples/text-entry-question/reactjs" rel="noopener noreferrer"&gt;Text Entry field&lt;/a&gt;. It’s suitable for short (hopefully concise) answers. You can use it to, for example ask a client the following questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the purpose of the website?&lt;/li&gt;
&lt;li&gt;Who is the target audience for the website?&lt;/li&gt;
&lt;li&gt;What is the budget for the website project?&lt;/li&gt;
&lt;li&gt;Who will be responsible for maintaining and updating the website?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To query a client about the project due date, you can either integrate a third-party date picker library, like &lt;a href="https://jqueryui.com/datepicker/" rel="noopener noreferrer"&gt;jQuery datepicker&lt;/a&gt; or &lt;a href="https://github.com/uxsolutions/bootstrap-datepicker/" rel="noopener noreferrer"&gt;Bootstrap datepicker&lt;/a&gt;, or simply change an input type to “date” to enable the built-in calendar as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffhrhobjz41nw8ruvf94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffhrhobjz41nw8ruvf94.png" alt="Image description" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another popular question type is &lt;a href="https://surveyjs.io/form-library/examples/add-open-ended-question-to-a-form/reactjs#content-code" rel="noopener noreferrer"&gt;Text Area or a Comment filed&lt;/a&gt;. This type of question provides more space for the respondent to write a longer or more detailed answer and would be suitable for such questions such as the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What features and functionality do you want on the website?&lt;/li&gt;
&lt;li&gt;Is there a content strategy for the website?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’d like your potential client to share their color preference for a certain element of a new website, for example the background color that would be shared among all pages, you can use yet another question type that SurveyJS offers out-of-the-boxt -a &lt;a href="https://surveyjs.io/form-library/examples/color-input-question/reactjs" rel="noopener noreferrer"&gt;Color Picker question&lt;/a&gt;. It allows respondents to enter a color in RGB, HSL, and HEX formats or select it with a visual interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkha4kf3w8h8qexpmf7yo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkha4kf3w8h8qexpmf7yo.png" alt="Image description" width="713" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case a client would like to have their logo unchanged and it includes several different colors, you can select a &lt;a href="https://surveyjs.io/form-library/examples/multiple-text-box-question/reactjs" rel="noopener noreferrer"&gt;Multiple Text Entry question&lt;/a&gt; and change the input type for each entry to “color”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0t4rhn2v5ztj5j7pi395.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0t4rhn2v5ztj5j7pi395.png" alt="Image description" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To enable a client to upload a file with a company logo, or any other existing branding guidelines and materials, add a &lt;a href="https://surveyjs.io/form-library/examples/file-upload/reactjs" rel="noopener noreferrer"&gt;File Upload question&lt;/a&gt; type to your form and restrict the allowed format to the one you prefer, for example SVG.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F01jw231e7vswg4f0w0jw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F01jw231e7vswg4f0w0jw.png" alt="Image description" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a TOC (Table of Contents)
&lt;/h2&gt;

&lt;p&gt;The purpose of a table of contents is to provide a client with a quick overview of the content and organization of the questionnaire and allow them to easily navigate to a specific question they want. Adding a TOC to a questionnaire (especially if it’s a long one) can also positively affect the completion rate as respondents can see in advance how many questions there are in a form, what those questions are, and how many remain unanswered.&lt;/p&gt;

&lt;p&gt;SurveyJS Form Library has a &lt;a href="https://surveyjs.io/form-library/examples/toc-feature/reactjs" rel="noopener noreferrer"&gt;built-in TOC feature&lt;/a&gt; that can be enabled and disabled and &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#tocLocation" rel="noopener noreferrer"&gt;repositioned to the left or right&lt;/a&gt; at your preference using the &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#showTOC" rel="noopener noreferrer"&gt;showTOC property&lt;/a&gt; with ‘true’ or ‘false’ values respectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  JSON ‘schema’
&lt;/h2&gt;

&lt;p&gt;As we already mentioned earlier, SurveyJS uses JSON objects to define the &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/survey-data-model" rel="noopener noreferrer"&gt;survey data model&lt;/a&gt;. As we were adding the questions to a web design client questionnaire in &lt;a href="https://surveyjs.io/create-free-survey" rel="noopener noreferrer"&gt;a no-code UI of the Survey Creator demo&lt;/a&gt;, it automatically generated such a schema in JSON format for us. Let’s take a look at it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
{
  title: "Website Intake Form",
  description:
    "Please fill out the form so that we can have better understanding as to what your expectations are of a new website.",
  logo:
    "https://api.surveyjs.io/private/Surveys/files?name=01deec1e-60dc-4438-8b8e-9a3f8a1afbbe",
  logoWidth: "270px",
  logoHeight: "120px",
  logoPosition: "right",
  pages: [
    {
      name: "page1",
      elements: [
        {
          type: "text",
          name: "What is the purpose of the website?",
          title: "What is the purpose of the website?"
        },
        {
          type: "text",
          name: "Who is the target audience for the website?",
          title: "Who is the target audience for the website?"
        },
        {
          type: "text",
          name: "What is the budget for the website project?",
          title: "What is the budget for the website project?",
          placeholder: "Enter a value in USD"
        },
        {
          type: "text",
          name:
            "Who will be responsible for maintaining and updating the website?",
          title:
            "Who will be responsible for maintaining and updating the website?"
        },
        {
          type: "text",
          name: "What is the due date for the website project?",
          title: "What is the due date for the website project?",
          inputType: "date"
        },
        {
          type: "comment",
          name:
            "What features and functionality does the client want on the website?",
          title:
            "What features and functionality does the client want on the website?"
        },
        {
          type: "file",
          name: "Please upload your company logo in SVG format.",
          title: "Please upload your company logo in SVG format.",
          acceptedTypes: ".svg"
        },
        {
          type: "multipletext",
          name: "Please specify the colors used in the company logo?",
          title: "Please specify the colors used in the company logo?",
          items: [
            {
              name: "Background color",
              isRequired: true,
              inputType: "color",
              title: "Background color"
            },
            {
              name: "Text color",
              isRequired: true,
              inputType: "color",
              title: "Text color"
            }
          ]
        },
        {
          type: "text",
          name:
            "Please specify the prefered background color for a new website.",
          title:
            "Please specify the prefered background color for a new website.",
          inputType: "color"
        }
      ]
    }
  ],
  showTOC: true,
  tocLocation: "right",
  questionsOnPageMode: "questionPerPage",
  widthMode: "static",
  width: "800"
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, each &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/text-entry-question-model" rel="noopener noreferrer"&gt;text entry field&lt;/a&gt; is simply an object defined with the type property set to “text” and added to the elements array. The &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/text-entry-question-model#inputType" rel="noopener noreferrer"&gt;inputType property&lt;/a&gt; is used to specify the input type. We only used a few values in our questionnaire. Please refer to the Form Library API reference to see all &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/text-entry-question-model#inputType" rel="noopener noreferrer"&gt;accepted values for the inputType property&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To demonstrate how it looks, here’s a ready-to-use multi-step Website Intake Form with a TOC that we made with &lt;a href="https://surveyjs.io/form-library" rel="noopener noreferrer"&gt;SurveyJS Form Library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/quizzical-farrell-n1nuls"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to start?
&lt;/h2&gt;

&lt;p&gt;Once you have decided on the type of data you want to obtain from your client and selected appropriate question types, you are ready &lt;a href="https://surveyjs.io/create-free-survey" rel="noopener noreferrer"&gt;to generate a survey JSON schema&lt;/a&gt; or modify the one we’ve just created. You then need to install and configure (using that JSON file) a framework-specific npm package by following one of the &lt;a href="https://surveyjs.io/form-library/documentation/get-started" rel="noopener noreferrer"&gt;dedicated getting started guides&lt;/a&gt; available for each frontend technology, and implement the backend. To help you get a backend up and running quickly, SurveyJS has prepared &lt;a href="https://surveyjs.io/backend-integration/examples" rel="noopener noreferrer"&gt;demo examples for ASP.NET Core, NodeJS, PHP, and WordPress&lt;/a&gt; that you can use for free.&lt;/p&gt;

&lt;p&gt;If you want to know more about the architecture of all SurveyJS libraries, please refer to the “&lt;a href="https://surveyjs.io/documentation/surveyjs-architecture" rel="noopener noreferrer"&gt;SurveyJS Architecture&lt;/a&gt;” guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Web development client questionnaire serves as a tool for collecting important information about client’s expectations, preferences, existing guidelines, and so on. Interviewing your potential clients with such a tool before proceeding to website development can save time during a meeting for both sides — a web developer can get ready by preparing further questions, while enabling a client to have more time to think about the information they are asked and provide well-considered answers. By adding SurveyJS to your web application, you can make the client interviewing process not only faster, but more secure — as it lets you stay in control of all sensitive respondent data you receive.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>form</category>
    </item>
    <item>
      <title>How to create an online quiz or assessment test using SurveyJS and add scoring and timing to it (Part 2)</title>
      <dc:creator>SurveyJS</dc:creator>
      <pubDate>Tue, 07 Mar 2023 14:49:27 +0000</pubDate>
      <link>https://forem.com/_surveyjs/how-to-create-an-online-quiz-or-assessment-test-using-surveyjs-and-add-scoring-and-timing-to-it-part-2-3maf</link>
      <guid>https://forem.com/_surveyjs/how-to-create-an-online-quiz-or-assessment-test-using-surveyjs-and-add-scoring-and-timing-to-it-part-2-3maf</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqbgjb7ky7zcmtmva5q8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqbgjb7ky7zcmtmva5q8.png" alt="Add scoring to a survey, quiz, or test - SurveyJS" width="720" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Survey Creator to Save the Day
&lt;/h2&gt;

&lt;p&gt;Writing a few dozen lines in JSON to configure a 3-question geography quiz isn't a big deal. But what if it is a multi-page assessment test or several of them? Then, manual coding is simply not an option, especially if there are other ways to create such complex tests (!) without a developer involved.&lt;/p&gt;

&lt;p&gt;We are talking about &lt;a href="https://surveyjs.io/survey-creator" rel="noopener noreferrer"&gt;Survey Creator&lt;/a&gt;, an embeddable GUI-based form builder that allows you to have a self-hosted tool for creating, storing, and analyzing any educational assessment materials. Whether it is a pop quiz at the end of a class or a midterm exam - your end users, e.g., teachers, can configure the contents and appearance of such forms easily.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto-generate the form model in JSON
&lt;/h3&gt;

&lt;p&gt;To demonstrate the functionally of Survey Creator, let's head over to its &lt;a href="https://surveyjs.io/create-free-survey" rel="noopener noreferrer"&gt;free full scale demo&lt;/a&gt;. Drop a radio button group question from the toolbox on the left onto the design surface to create a form.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4sg3p1j6d6ppsxcug1l8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4sg3p1j6d6ppsxcug1l8.png" alt="Free Survey Tool UI - SurveyJS | Adding a radio button group question" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, add a title, description, and assign values to the first question (“How many continents are there?” with four choice options: 4, 6, 5, and 7) to turn this form into our sample &lt;strong&gt;Geography test&lt;/strong&gt;. The folded tabs on the right make up the Property grid, where users can change the question, &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/panel-model" rel="noopener noreferrer"&gt;panel&lt;/a&gt;, and form settings.&lt;/p&gt;

&lt;p&gt;We will not focus on the basic functionality of the Survey Creator interface this time. Please refer to the &lt;a href="https://surveyjs.io/survey-creator/documentation/end-user-guide" rel="noopener noreferrer"&gt;dedicated end-user guide for Survey Creator&lt;/a&gt; for details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltx522xx8413pkpsc0ns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltx522xx8413pkpsc0ns.png" alt="The Property grid of the Survey Creator UI — SurveyJS" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Set the Correct Answer for a Question
&lt;/h3&gt;

&lt;p&gt;The default functionality of the Property Grid allows you to set a correct answer for a question. To do this, switch to the question settings level, click the Set Correct Answer button under Data, and select the right answer in the Correct Answer popup, then click Apply.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswmdyflvie7re2avivop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswmdyflvie7re2avivop.png" alt="How to set the correct answer for a question — SurveyJS" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s add a few more questions to our test and move on to setting up timing. As we can include any question type supported by the SurveyJS Form Library, let’s add a dropdown menu to the same page and another radio button group to the second one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flamxub1sa8d5c5v47c1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flamxub1sa8d5c5v47c1w.png" alt="Add a Single Selection Dropdown menu to a test — SurveyJS" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup time limits in Survey Creator UI
&lt;/h3&gt;

&lt;p&gt;To specify time limit, select survey-level settings, and under the Timer/Quiz section of the Property Grid, enter the number of seconds you want to allow for each page and/or for the entire survey to complete. You can also configure the time visibility and position to make sure students can self-pace to answer all questions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fky35e3v8zuer5jf1xt25.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fky35e3v8zuer5jf1xt25.png" alt="How to time a test in Survey Creator UI — SurveyJS" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Survey Complete section
&lt;/h3&gt;

&lt;p&gt;Like most other form settings, customized feedback pages can also be configured in the graphical interface of Survey Creator. If you only want to calculate scores by comparing choices with the predefined correct answers, then at the survey level setting, select the Survey Complete section and enter the rule in the Survey Complete markup using markup tags.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqqyfnkao6yl8a0pf3bzp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqqyfnkao6yl8a0pf3bzp.png" alt="Configure a custom test result page — SurveyJS" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to display a personalized feedback based on the number of correct answers a student provided, in the same section of the Property Grid add a Dynamic Survey Complete page markup and specify an expression that triggers it as shown in the example below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhbr623orfxe92p53entd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhbr623orfxe92p53entd.png" alt="Create a dynamic test result page — SurveyJS" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's scoring?
&lt;/h2&gt;

&lt;p&gt;Scoring is the process of evaluating or assigning a numerical value or score to a particular question of a test, exam, quiz, or other assessment form or to a single-choice option of such a question. It involves applying rules or criteria to assess the quality, quantity, or level of performance of the question or item being scored.&lt;/p&gt;

&lt;p&gt;Scoring has various fields of application, including academic or professional settings, sports, games, or contests. In education, for example, scoring is used to assess knowledge, skills, or abilities of students in a particular subject or course. Scores can be used to compare students’ performance, determine grades or rankings, or provide feedback for improvement. In the banking sector, scoring can help evaluate loan applicants based on their answers and sort out trustworthy ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Add a Scoring to a SurveyJS Form
&lt;/h3&gt;

&lt;p&gt;1.1 By default, the Property Grid doesn’t include a &lt;code&gt;score&lt;/code&gt; property. &lt;br&gt;
To &lt;a href="https://surveyjs.io/survey-creator/documentation/property-grid#add-custom-properties-to-the-property-grid" rel="noopener noreferrer"&gt;add a custom property to the Property Grid&lt;/a&gt;, we need to call the &lt;code&gt;addProperty(questionType, propertySettings)&lt;/code&gt; method on the &lt;code&gt;Survey.Serializer&lt;/code&gt; object. The only difference between adding a custom &lt;code&gt;score&lt;/code&gt; property to a question and to a choice option is the class you add it to. Since only a single answer is correct in a &lt;a href="https://surveyjs.io/form-library/examples/create-a-scored-quiz/reactjs" rel="noopener noreferrer"&gt;scored quiz&lt;/a&gt;, a score property is added to a &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/question" rel="noopener noreferrer"&gt;Question&lt;/a&gt; class. On the contrary, there are no correct answers in a &lt;a href="https://surveyjs.io/form-library/examples/create-a-scored-survey/reactjs" rel="noopener noreferrer"&gt;scored survey&lt;/a&gt;, so a custom &lt;code&gt;score&lt;/code&gt; property needs to be added to the &lt;code&gt;ItemValue&lt;/code&gt; class. Compare the following code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To add a custom &lt;code&gt;score&lt;/code&gt; property to questions:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Serializer } from “survey-core”;

Serializer.addProperty("question", {
   name: "score:number"
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;To add a custom &lt;code&gt;score&lt;/code&gt; property to choice options:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Serializer } from “survey-core”;

Serializer.addProperty("itemvalue", {
   name: "score:number"
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;1.2 Now when the score property is serialized and included in the survey JSON schema, you need to assign its values for each question, the same way we specified the &lt;code&gt;correctAnswer&lt;/code&gt; property earlier. Here is how the first question of our sample test looks like with both properties configured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "radiogroup",
  "name": "count_continents",
  "score": 5,
  "title": "How many continents are there?",
  "correctAnswer": "Item 7",
  "choices": [
    "4",
    "6",
    "5",
    "7"
  ],
  "colCount": 2
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Calculate the Total Score
&lt;/h3&gt;

&lt;p&gt;1.3 To sum up the total score, you need to handle the &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#onComplete" rel="noopener noreferrer"&gt;onComplete&lt;/a&gt; event and use the following &lt;code&gt;calculateTotalScore&lt;/code&gt; helper function with a question’s &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/question#isAnswerCorrect" rel="noopener noreferrer"&gt;isAnswerCorrect&lt;/a&gt; method, which checks if the question was answered correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function calculateTotalScore (data) {
  var totalScore = 0;
  Object.keys(data).forEach((qName) =&amp;gt; {
    const question = survey.getQuestionByValueName(qName);
    if (question.isAnswerCorrect()) {
      if (!!question.score) {
        totalScore += question.score;
      }
    }
  });
  return totalScore;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refer to this &lt;a href="https://surveyjs.io/form-library/examples/create-a-scored-quiz/reactjs" rel="noopener noreferrer"&gt;free demo showing how to configure a scored quiz&lt;/a&gt; to learn how to calculate the maximum score with the &lt;code&gt;calculateMaxScore&lt;/code&gt; helper function.&lt;/p&gt;

&lt;p&gt;1.4 Finally, once the total score has been calculated, we need to modify the &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#completedHtmlOnCondition" rel="noopener noreferrer"&gt;completedHtmlOnCondition&lt;/a&gt; array by using different placeholders in the expression property that triggers a custom markup. Since we don’t simply count correct or incorrect answers but points assigned to each correct answer, the arguments change to &lt;code&gt;{totalScore}&lt;/code&gt; or &lt;code&gt;{maxScore}&lt;/code&gt; etc. Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const surveyJson = {
  ...
  completedHtmlOnCondition: [{
    expression: "{totalScore} &amp;gt; 10",
    html: "&amp;lt;h4&amp;gt;Congratulations! You got {totalScore} points and passed the test. Well done!&amp;lt;/h4&amp;gt;"
  }]
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A Basic Geography Test Demo
&lt;/h2&gt;

&lt;p&gt;You can now see our basic Geography Test built with Survey Creator in action. Click “Open Sandbox” to run free demo:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/laughing-lumiere-yvnmg8?view=preview"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;SurveyJS offers a wide range of built-in features for online tests and quizzes, including timing, scoring, a custom feedback or &lt;a href="https://surveyjs.io/form-library/documentation/design-survey/create-a-quiz#set-up-a-start-page" rel="noopener noreferrer"&gt;start page&lt;/a&gt;, and more. You can manually write a form model in JSON (please consult with the &lt;a href="https://surveyjs.io/form-library/documentation/api-reference/survey-data-model" rel="noopener noreferrer"&gt;Form Library API references&lt;/a&gt;), run it for free in your app, and &lt;a href="https://surveyjs.io/form-library/documentation/handle-survey-results-store" rel="noopener noreferrer"&gt;store the results in your own database&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, if the complexity and number of assessment forms you deal with are significant, you might want to leverage the drag-and-drop UI of Survey Creator - a self-hosted form builder tool, which ships with a &lt;a href="https://surveyjs.io/survey-creator" rel="noopener noreferrer"&gt;free full scale demo&lt;/a&gt;. Once added to your application, Survey Creator auto-generates a form model for you while your end users configure the contents and layout of a form in a no-code UI. The generated form is then stored and loaded from your database in the same JSON format and is rendered in your app.&lt;/p&gt;

&lt;p&gt;The Creator UI is fully customizable, you can tailor it to the needs of your end users to make it even more pleasant and easy to work with. &lt;a href="https://surveyjs.io/survey-creator/examples/add-properties-to-property-grid/reactjs" rel="noopener noreferrer"&gt;Add&lt;/a&gt;, &lt;a href="https://surveyjs.io/survey-creator/examples/removeproperties/reactjs" rel="noopener noreferrer"&gt;remove&lt;/a&gt; or &lt;a href="https://surveyjs.io/survey-creator/examples/hide-category-from-property-grid/reactjs" rel="noopener noreferrer"&gt;hide properties&lt;/a&gt; of survey elements in the Property Grid, modify visibility of default tabs or add your custom tabs or buttons — you name it.&lt;/p&gt;

&lt;p&gt;With SurveyJS it’s never been easier to create, modify and run scored tests and surveys. Select your preferred frontend technology and &lt;a href="https://surveyjs.io/form-library/documentation/get-started" rel="noopener noreferrer"&gt;get started&lt;/a&gt; with your first Survey JS assessment form today!&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>oop</category>
      <category>discuss</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
