Create a Multi-Page Form and Run it in an Angular app in Minutes with SurveyJS
Tags: form, survey, angular, javascript
Published: 2023-01-18 09:33:36

{% embed https://youtu.be/wX06XXlcXJw %}
Whether you come from the healthcare or education sector, human resources, or anything in between - collecting sensitive data can become a maintenance nightmare, since you, as a form creator, must guarantee anonymity and privacy to your respondents (very often - to thousands of them) in order to remain legally compliant and ensure honest answers.

The software you use to create and host forms needs to be more than just a third-party, black-box SaaS platform where you’re locked into too many dependencies, and locked out of engagement, monitoring, and improvement of the actual service because of intellectual property laws.

Regardless of the type of form workflow you deal with - internal or external, it’s often the case that form contents require systematic and sometimes rapid changes, which as a consequence forces your software developers to constantly be involved in the creation and further modification of those forms.

So to solve the form automation issue, you want a **no-code** instrument for content creators that **performs well even with hundreds of questions**. You also want it to be fully customizable, so you can use [custom CSS](https://surveyjs.io/form-library/examples/survey-customcss/reactjs) to make your surveys and forms look great and stand out with [your brand’s own design language](https://surveyjs.io/form-library/examples/survey-logo/reactjs), not the same old default styles provided by third-party vendors. 

You probably also want such a tool to enable you to apply **complex [conditional logic](https://surveyjs.io/form-library/examples/condition-kids/reactjs) and branching** to your forms so you don’t ask questions that are not relevant to certain respondents, and stay in control of your form workflow. 
And it’s also handy if this form builder **supports [auto-localization](https://surveyjs.io/form-library/examples/survey-localization/reactjs)** and switches form contents at runtime from, say, English to another language based on a respondent’s system locale.

And what would really be cool is if this tool also knew how to **save a form to your organization’s database** as soon as it’s submitted, or **send you emails or Slack notifications** whenever a unique respondent takes your survey.

Quite a lot to ask for, right? We’ve got great news for you all! Such a form builder does exist, and it’s called [SurveyJS](https://surveyjs.io/)!

Self-hosting SurveyJS is the easiest way to do both - ensure individual privacy and legal compliance, and offload content work from software developers. You would [create simple surveys](https://surveyjs.io/form-library/documentation/design-survey/create-a-simple-survey) or [multi-page surveys](https://surveyjs.io/form-library/documentation/design-survey/create-a-multi-page-survey), run them, and **store responses completely within your own infrastructure**, thus being in total control of the data flow between server and client without any third-party involved.

It also gives your front-end developers the freedom to not have to be involved in form creation, thanks to an **intuitive drag-and-drop interface** that content managers can use directly.

In this article, you’ll learn the basic functionality of the Survey Creator interface. We will also create a job application form together and [run it in a test Angular app](https://surveyjs.io/form-library/documentation/get-started-angular). 

_A quick note for those who haven’t heard of SurveyJS yet: [Survey Creator](https://surveyjs.io/survey-creator/documentation/overview) is one of the four open-source JS libraries of the SurveyJS project and once it is added to your application, it lets you build a secure and self-hosted form management system to generate multiple forms and run them using another SurveyJS library called [Form Library](https://surveyjs.io/form-library/documentation/overview)._
 
![SurveyJS Libraries](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/srbp98baxa0p7d8o4tum.png)

We’ll talk about this library a bit later. Now, let’s get started!

So for this tutorial, I’ll be using a free and [full-scale demo of Survey Creator](https://surveyjs.io/create-free-survey) that you can easily find at surveyjs.io by clicking the Create a Survey button in the top right corner of the page.

As you can see, the default UI of Survey Creator is organized in multiple tabs. We’ll mostly be focusing on the Designer tab as this is where forms are configured. 

![Survey Creator: Tabbed Interface](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7an16ovxbkfwd1mwoqnn.png)

You can drag and drop questions and panels from the Toolbox on the left onto the design surface, and then use the Property Grid on the right to change the question, panel, and entire form settings. We’ll also be switching to the Preview during the design process to check how applied changes will look.

![Survey Creator UI Elements](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/js73b2a93q6h1iw38rv2.png)

Now let’s see the final version of our [job application form](https://surveyjs.io/published?id=8e1ae568-b306-498b-a9ce-299b23ce49f6) including the number of pages the form will have and the fields on each page. The form that we will create during this tutorial is composed of two different pages - Personal Information and Employment Details. The first page includes such fields as:
* Full name
* Date of birth
* Current address
* Contact email
* And a field for resume file upload

The second page is dedicated to employment details and it covers current employment status, the position an applicant is applying for, expected monthly salary, and available start date.
As you might have noticed, some of the questions from the first page are grouped together inside a frame that is called a [panel](https://surveyjs.io/form-library/examples/questiontype-panel/reactjs). A panel is a sort of container for other questions and panels. You can use it if you want to configure or modify several form elements at the same time.

![Panel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/worpyeuhzudrx65z6eyz.png)


A new page is created automatically, once you add an element to it. Let’s drop a panel onto the design surface. Alternatively, you can just click it to add it to your form. 

![Add a Panel to a Form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3cry46sin1pcl0wpsyd.png)

Now let’s assign a name and a title to the form itself,  the first page, and the panel we just added. _A quick note here - the name is used for internal purposes like form configuration, while the title is what your respondents will see._ 

![Edit Name and Title for Form, Page, and Panel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/409s8u7xol8a9u3w5kmc.png)

There are two places where you can assign a name to your form and its elements. The first option is to do it on the design surface, by simply clicking the title and typing its name. The other place is the property grid here on the right. First, make sure you are on the right settings level. [Survey](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model) is always the highest level, and once it’s chosen the property grid displays the settings that are related to the entire form rather than its element. [Page](https://surveyjs.io/form-library/documentation/api-reference/page-model) or [panel](https://surveyjs.io/form-library/documentation/api-reference/panel-model)-level settings, on the other hand, allow you to configure the behavior of a particular page, or of a set of elements, inside a panel.

![Survey Elements](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pe1be16yevzyhs9fxxq1.png)

I am also going to add a little description under the form title to thank an applicant for taking the time to fill out the form and a [company logo](https://surveyjs.io/form-library/examples/survey-logo/reactjs) to make the header of my form look unique and more complete. 


![SurveyJS Form Logo and Description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iavt4bpas9dowpk3cwaa.png)

Now let’s insert three [simple text entry fields](https://surveyjs.io/form-library/documentation/api-reference/text-entry-question-model) into our panel for First name, Surname, and Date of Birth. 

![Text Input fields](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92ngac6l006yv0u5ymdk.png)

Because it’s not a survey, I don’t want my questions to have numbers, so I will hide them by selecting survey level settings, and under Question, I select the “Hide question numbers” option from the Question numbering dropdown menu. As you can see, since I’ve made this change at the highest level, it’s applied to all questions inside the form.  

![Survey Question Numbering Settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egecb4tqg4e8d3q01q7a.png)

Now I want to enhance my questions a bit. I’ll select an input type for each question and place the Surname field on the same line as the First name field. To do this, I need to select the second question, go to the property grid and under Layout, unselect the “Display question on a new line” option. I don’t really need to modify the input type for the first question, so I am going to leave the default text value here. But I want to make those two questions mandatory, to ensure that respondents don’t skip them while filling out the form. For this, I simply need to select the desired question and toggle the “Required” option. I’ll also set the autocomplete type for those questions to Name and Family-name, respectively, so that the user's browser can retrieve this data either from past values entered by the user or from pre-configured values if any have been saved by the user for autocomplete purposes.
For the third question, since the entry value is a date, I’ll specify the Date input type, which automatically applies the date format to the entry box.

![Date Input Box](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/361n98go8dicz3k1s9uj.png)

Now let’s add one more panel for Current Address and insert three text entry fields into it for Street address, City or Town, and Zip code. I’ll display the second and third questions together on a new line. And, since the Zip code field requires digits as an input type, I will set the input type to Number. Now let’s quickly check the Preview tab to make sure that the form looks exactly the way I expect it to. As you can see in the Preview tab, when you try to type letters in the zip code field, letters are not displayed since only the Number input type is allowed.
The last question I want to add to this panel is Country. For this question with a long list of choices, the text entry question type is not the best option, so I’ll [use a dropdown box](https://surveyjs.io/form-library/documentation/api-reference/dropdown-menu-model) here. There are several [ways to populate a dropdown list with choices](https://surveyjs.io/form-library/documentation/design-survey/pre-populate-form-fields). The easiest way is to simply click each item either on the design surface or under the Choices category and assign a value to it. Another option is to type or copy and paste a list of choices in the Choices popup that appears as you click the Edit button here. But none of those options suit me because it's too time-consuming to enter a long list of countries. I also want my drop-down question to support a search-as-you-type option with server-side filtering, so a respondent can simply type in the input area to bring up a list of matches that have been filtered on the server side on the fly. To do this, I will populate my drop-down menu with data loaded from a REST API web service by adding a URL to the Service URL box under ‘Choices from a RESTful service’. 

![Dropdown: Load Choices from RESTful API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2cnpsf98ouv7lsprwxbx.png)

Although it’s a list of countries in this particular case, it can otherwise be used to populate a drop-down menu with any list of choices that you require. So what happens is that we store a list of countries in our database and the RESTful service sends a request to the server to get this list, filter the choices to match the respondent’s input values, and then send the list of matches to browsers. And the good news is that this drop-down functionality - whether single selection or multi selection - is included out-of-the-box, so you don’t need to integrate any third-party libraries.

Now let’s add the remaining two questions to this page and move on to the second one. The next question is Email address. To make sure respondents enter their email correctly, I’ll set the input type to Email and add a placeholder saying ‘Enter your valid email address in an 'example@example.com' format’. The placeholder is the area inside the entry field. As you can see, if a respondent enters a bunch of random symbols here, the [input validation](https://surveyjs.io/form-library/examples/javascript-form-validation/reactjs) kicks in and doesn’t let them proceed to the next question in the form.

The last question on this page is Resume. To enable a user to upload their resume, I select a [File upload element](https://surveyjs.io/form-library/documentation/api-reference/file-model), name it, and restrict its type to PDF format by specifying .pdf in ‘Accepted file types’ under General. All files uploaded by users are stored in the SurveyResults binary JSON file (the default file), but you can certainly configure a separate storage of answers and uploaded files on your server. I’ll also select the ‘Confirm file deletion’ option to make it easy for respondents to replace unwanted files, and the ‘Wait for the upload to complete’ option to make sure no file goes missing. 

![File Upload](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ncwzdpk6br9nns95qrqn.png)

OK. Great!

Now let’s quickly add a [Radio button group](https://surveyjs.io/form-library/documentation/api-reference/radio-button-question-model) to trigger creation of the next page. I opted for this question type instead of, say, checkboxes, because I need a respondent to select only one answer here. I’ll name the page Employment Details and assign a name and a title to its first question, which is ‘What is your current employment status?’ I’ll add a list of choices using the Choices popup this time. 

![Radiogroup: Edit Choices](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hpgrrgp9dkqj8vzrqi1t.png)

The next question is a text entry field that says, ‘What is your expected graduation date?’ As you might have guessed, based on the list of choices for the previous question, this one is a follow-up question, and I only want it to be seen by those who answer ‘Student’ to the first question on the page. To do this, I’ll create a new conditional rule in the logic tab. To set a new rule, we need to select the main question, which in this case is ‘What is your current employment status?’ Then, we choose a condition for the dependent question to appear, which is that the reply ‘equals’ ‘Student’. If the condition is met, then the question ‘What year are you?’ is shown. **Done**. 

![Logic Tab](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b4kicws7t067jw48t3w7.png)


Let’s go to the Preview tab, select ‘Student’, and there it is, the follow-up question appears. 

You can also hide or show a form element or an entire page by setting up the [visibleIf/enableIf](https://surveyjs.io/form-library/examples/condition-kids/reactjs) property of a question, panel, or page under the Logic category of the Property grid.

![Logic: Visible If Expression](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ldrwmm8r0e5n1jfw0ads.png)

The next question is: What position are you applying for? It requires a single choice from respondents, so I can either go with a Radio button group again or choose a drop-down box. Let’s select a drop-down menu and populate its items with the values I prepared. The last two questions are ‘Expected monthly salary in USD’ and ‘Available Start Date’, which as we already know requires the date input type.
Our form is almost ready. Let’s take a quick look at it in the Preview tab. Okay, it looks good but I don’t want it to take up the entire screen, so I’ll switch to the Survey settings level and under General, I need to change the width mode to Static and set the Width value to, say, 800px. By the way, you can also use any relative CSS units here - like vw and em. I’ll go with pixels this time. Responsive mode takes all available horizontal space. And Auto mode, as the name implies, automatically chooses between Static and Responsive modes depending on the type and width of questions in a form.

![Survey: Width Mode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a5q56i2wggy7eykknux6.png)

While we were configuring our survey, its JSON definition file that represents the survey model or schema is automatically generated for us.

![JSON Editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d9xojvjenbynpa28uhg8.png)

Now all we need to do is add the Form Library component to run the form in our test Angular application. Let’s do it!
To add the Form Library component to your application, go to the Documentation and in the left menu under the Form Library, click ‘Get started’ and select Angular to see a [step-by-step getting started guide](https://surveyjs.io/form-library/documentation/get-started-angular). Alternatively, you can simply clone the [library repository](https://github.com/surveyjs/code-examples/tree/main/get-started-library/angular), install dependencies and open a ready-to-run sample Angular application in your IDE. 

We’ll start by installing the [survey-angular-ui npm package](https://www.npmjs.com/package/survey-angular-ui). 
```
npm install survey-angular-ui --save
```
Then, we need to import the CSS file of the built-in theme to configure the style of our form.
```
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  // ...
  "projects": {
    "project-name": {
      "projectType": "application",
      // ...
      "architect": {
        "build": {
          // ...
          "options": {
            // ...
            "styles": [
              "src/styles.css",
              // Default V2 theme
              "node_modules/survey-core/defaultV2.min.css",
              // Modern theme
              // "node_modules/survey-core/modern.min.css"
            ],
            // ...
          }
        }
      }
    }
  }
}
```
The next step is to instantiate a survey Model by passing the data schema to the Model constructor.
```
import { Component, OnInit } from '@angular/core';
import { Model, StylesManager } from "survey-core";

StylesManager.applyTheme("defaultV2");

const surveyJson = {
  elements: [{
    name: "FirstName",
    title: "Enter your first name:",
    type: "text"
  }, {
    name: "LastName",
    title: "Enter your last name:",
    type: "text"
  }]
};

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'My First Survey';
  surveyModel: Model;
  ngOnInit() {
    const survey = new Model(surveyJson);
    this.surveyModel = survey;
  }
}
```
Now we need to import the framework-specific rendering component and pass the Model instance to the component's model attribute. 
```
// app.module.ts
// ...
import { SurveyModule } from "survey-angular-ui";

@NgModule({
  declarations: [ ... ],
  imports: [
    ...,
    SurveyModule
  ],
  providers: [ ... ],
  bootstrap: [ ... ]
})
export class AppModule { }
...
<survey [model]="surveyModel"></survey>
```
Finally, let’s copy and replace the sample JSON schema with the one we created.

Run the `npm start` command.
```
npm start
```
Here it is!

As you can see, it only took a few minutes to get started and run our form. The SurveyJS Library comes with [over a hundred free demos](https://surveyjs.io/form-library/examples/nps-question/reactjs), and it is completely free, so make sure to add it to your application today!