|
1 |
| -# SurveyJS as front-end form library for ASP.Net Core app |
2 |
| - |
3 |
| -The examples show how to use SurveyJS Library to edit Domain Models defined as C# classes. |
4 |
| -You can edit JSON Form Definition in our SurveyJS Creator and your end-user will see |
5 |
| -a different form for editing/filling forms without an application re-building/re-deploying. |
6 |
| - |
7 |
| -There are 3 Domain Classes in this example: |
8 |
| - * [JobApplication](/DomainModels/JobApplication.cs) |
9 |
| - * [NPSSurvey](/DomainModels/NPSSurvey.cs) |
10 |
| - * [PatientAssessment](/DomainModels/PatientAssessment.cs) |
11 |
| - |
12 |
| -## Mock database |
13 |
| -To make an example simple, the current implementation doesn't work with a database. |
14 |
| -DomainModel objects are stored in the memory by using a singleton [DataStorage](/DomainModels/DataStorage.cs) class. |
15 |
| -This singleton stores and retrieve data by class type and object Id (Unique string) |
16 |
| -and serialize/deserialize objects by using MS .Net JsonSerializer Serialize/Deserialize functions. |
17 |
| -You can change our [DataStorage](/DomainModels/DataStorage.cs) class to write the code that will work with any database of your choice. |
18 |
| -As an alternative, you can use an ORM library. |
19 |
| - |
20 |
| -## Form List. Register a new form / DomainModel. |
21 |
| -To register a [DomainModelFormAttribute](/Code/FormAttributes.cs) class attribute is added. |
22 |
| -It has two parameters: "Name" and "Title". |
23 |
| -Here is the example of registering a new form: |
24 |
| -````csharp |
25 |
| - [DomainModelForm("nps-survey", "NPS Survey (Domain Model without attributes)")] |
26 |
| - public class NPSSurvey: DomainModel { |
27 |
| - ... |
28 |
| - } |
29 |
| -```` |
30 |
| -The [DomainModelList](/DomainModels/DomainModelList.cs) can return the list of all registered DomainModel classes (forms) |
31 |
| -by calling static function `DomainModelList.GetAllForms();`. It get all classes in the running assembly |
32 |
| -and check all classes inherited from "DomainModel" with "DomainModelForm" attribute. |
33 |
| -You can get a DomainModel type by form name by calling a static function `DomainModelList.GetTypeByFormName(string formName);`. |
34 |
| - |
35 |
| -## Form Response View to fill out forms |
36 |
| -[Form Response View](/Views/Home/FormResponse.cshtml) shows SurveyJS runner to fill out a form. |
37 |
| -It uses SurveyJS Library for knockout to render the form. We use it instead of React or Angular or Vue versions, because of simplicity. |
38 |
| -The page contains minimim code related to JavaScript framework implementation. |
39 |
| -The survey runner shows on loading JSON form definition and survey data, by calling [loadFormAndData](/wwwroot/js/form_api.js) function. |
40 |
| -The form (survey) model is setup in [setupSurveyModel](/wwwroot/js/surveyjs.js) function. |
41 |
| -Inside this function, on submitting form the [saveFormData](wwwroot/js/form_api.js) function is calling. |
42 |
| - |
43 |
| -## Getting JSON form definition |
44 |
| -There are two API server functions [loadform and loadform_and_data](/Controllers/FormController.cs). |
45 |
| -They return the JSON form definition by form name and the second function returns a previous entered form response by Id. |
46 |
| -The previous entered response data is getting by using our [DataStorage](/DomainModels/DataStorage.cs). |
47 |
| -JSON form definition is returning by the following rule. If there is a JSON with the same form name in "Data" directory then the context of this file is returned. |
48 |
| -If there is no such file in the directory, then the JSON form definition is generated on fly by DomainModel class corresponded with this form name. |
49 |
| - |
50 |
| -## Generating JSON by DomainModel |
51 |
| -By default the JSON form definition is generated based on DomainModel. |
52 |
| -[JsonFormGenerator](/DomainModelsViews/JsonFormGenerator.cs) class generates JSON by using .Net reflection API. |
53 |
| -Every public writable property in DomainModel is corresponded with a question in Form (Survey) JSON. |
54 |
| -Generator class uses property type and property attributes to generate the correct JSON. |
55 |
| -You can use .Net standard "Required" and "DisplayAttributes" as well as custom [FormPage and FormField](/Code/FormAttributes.cs) attributes. |
56 |
| -You can improve our current JSON generator class by adding new custom attributes or by adding more properties into our attributes. |
57 |
| - |
58 |
| -## Editing generating and existing Form JSONs |
59 |
| -You can edit default JSON Form Definition on [EditForm](/Views/Home/EditForm.cshtml) page. |
60 |
| -It loads form definition located in "Data" directory or generated by [JsonFormGenerator](/DomainModelsViews/JsonFormGenerator.cs) class |
61 |
| -and store changes in [DataStorage](/DomainModels/DataStorage.cs). After changing the JSON Form Definition, Form Response page will use new updated JSON for form editing. |
62 |
| -There are two modes for editing JSON Form Definition: admin and content manager. |
63 |
| -The first one has no limitation. Admin can add/delete any question/columns and so on. |
64 |
| -The mode for content manager doesn't allow to add/delete remove question or column or change question/column type or change their names. |
65 |
| -It means that content manager is not able to make form definition incorrect. It can change question title or change question location, |
66 |
| -but every question will be corresponded with a correct DomainModel property. |
| 1 | +# Generate Forms from Domain Models with SurveyJS |
| 2 | + |
| 3 | +This example demonstrates how to generate forms in JSON format based on strongly-typed domain models and vice versa. The generated forms can be displayed by SurveyJS Form Library and edited in Survey Creator. This solution will be beneficial for content and product managers who regularly create forms and for backend developers who implement domain models based on these forms. |
| 4 | + |
| 5 | +<!-- TODO: Add illustration --> |
| 6 | + |
| 7 | +This application was built using ASP.NET Core. Follow the same instructions if you need to implement this functionality with any other server-side framework. |
| 8 | + |
| 9 | +- [Domain Models and Attributes](#domain-models-and-attributes) |
| 10 | +- [Generate Form JSON Schemas from Server-Side Domain Models](#generate-form-json-schemas-from-server-side-domain-models) |
| 11 | +- [Display a Form](#display-a-form) |
| 12 | +- [Edit JSON Schemas](#edit-json-schemas) |
| 13 | +- [Generate Domain Model Code Based on Form JSON Schemas](#generate-domain-model-code-based-on-form-json-schemas) |
| 14 | + |
| 15 | +## Domain Models and Attributes |
| 16 | + |
| 17 | +Domain models are declared in server-side code. You can generate form JSON schemas based on them. Domain model properties become form fields. You can then feed the JSON schemas into SurveyJS Form Library to display a form on your website or in your application. This project contains three sample domain models, each describes an individual form: |
| 18 | + |
| 19 | +- [`JobApplication`](/DomainModels/JobApplication.cs) |
| 20 | +- [`NPSSurvey`](/DomainModels/NPSSurvey.cs) |
| 21 | +- [`PatientAssessment`](/DomainModels/PatientAssessment.cs) |
| 22 | + |
| 23 | +A domain model and its properties can include [attributes](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/). A form generator uses attribute parameters to generate form JSON schemas. For instance, all domain models have a `DomainModelForm` attribute shown below. Its parameters configure a form's `name` and `title` properties. |
| 24 | + |
| 25 | +```csharp |
| 26 | +[DomainModelForm("nps-survey", "NPS Survey (Domain Model without attributes)")] |
| 27 | +public class NPSSurvey: DomainModel { |
| 28 | + // ... |
| 29 | +} |
| 30 | +``` |
| 31 | + |
| 32 | +A form generator can support predefined .NET attributes, such as [`Required`](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute) or [`Display`](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.displayattribute), as well as custom attributes, like `DomainModelForm`. The following file shows how this project implements custom attributes: [FormAttributes.cs](/Code/FormAttributes.cs). |
| 33 | + |
| 34 | +You can get a list of all domain models in the running assembly. Call the `DomainModelList.GetAllForms()` static method. It finds all classes that are inherited from `DomainModel` and have the `DomainModelForm` attribute. Refer to the following file for full code: [DomainModelList.cs](/DomainModels/DomainModelList.cs). |
| 35 | + |
| 36 | +## Generate Form JSON Schemas from Server-Side Domain Models |
| 37 | + |
| 38 | +Form JSON schemas are generated based on property type and attributes. Each public writable property in a `DomainModel` class becomes a form field in the form JSON schema. Refer to the [`JSONGeneratorByModelClass`](/DomainModelsViews/JsonFormGenerator.cs#L13) class to view the form generator code. The class implements a `Generate()` method that extracts all properties from a domain model, gets their type and attributes, and uses this information to build a JSON schema. You can extend the form generator's functionality: implement new custom attributes or add more properties to the existing attributes. |
| 39 | + |
| 40 | +## Display a Form |
| 41 | + |
| 42 | +SurveyJS ships with a tool that displays surveys and forms—[SurveyJS Form Library](https://surveyjs.io/form-library). You no longer need to create a separate page for each form you have in your application. Set up SurveyJS Form Library and assign different JSON schemas to it to display different forms. This tool supports all most popular JavaScript frameworks, including React, Angular, and Vue. However, this project uses the Form Library version for Knockout because it is the easiest version to set up. The [FormResponse.cshtml](/Views/Home/FormResponse.cshtml) file shows the Form Library configuration code. |
| 43 | + |
| 44 | +In this project, SurveyJS Form Library displays JSON schemas that come from different sources. The "NPS Survey" and "Patient Assessment" forms are pre-generated and stored as JSON files in the [Data](/Data/) directory. The "Job Application" form is generated from the `JobApplication` domain model on the fly. If a form JSON schema has been edited, its most recent version is stored in a database (or [database emulator](/DomainModels/DataStorage.cs), as in this application). When Form Library requests a JSON schema of a certain type, the server first looks into the database to find the most recently edited schema of that type. If the schema is not found, the server returns a pre-generated schema from one of the JSON files. If a file with a schema of that type is also absent, the server generates the schema on the fly. Refer to the following file to find methods that implement this logic: [JsonForms.cs](/DomainModelsViews/JsonForms.cs). |
| 45 | + |
| 46 | +<!-- TODO: Add illustration --> |
| 47 | + |
| 48 | +## Edit JSON Schemas |
| 49 | + |
| 50 | +JSON schemas can be edited in any text editor, but they are easier to edit in [Survey Creator](https://surveyjs.io/survey-creator). This JavaScript component is a UI form designer by SurveyJS that content and product managers can use to create and modify JSON schemas without writing code. Similar to SurveyJS Form Library, Survey Creator supports React, Angular, Vue, Knockout, and jQuery and is easy to integrate into your application. The project in this repository sets up the Knockout version (view the [EditForm.cshtml](/Views/Home/EditForm.cshtml) file). |
| 51 | + |
| 52 | +If in your team more than one person creates and edits forms, you can configure multiple roles with different access rights. For example, you may define two roles: content manager and product manager. Content managers cannot create new forms and can edit only those form properties that do not require server-side code modification. These restrictions ensure the synchronization between domain models and form JSON schemas. Product managers on the other hand have unlimited capabilities and can request the backend development team to update domain models on the server. The role separation is implemented at the Survey Creator level. Refer to the [`creatorjs.js`](/wwwroot/js/creatorjs.js) file to see the implementation. You can also view the restricted UI for content managers in the following demo: [Setup for Content Managers](https://surveyjs.io/survey-creator/examples/setup-for-content-manager/). |
| 53 | + |
| 54 | +To make edited schemas available to the users, you do not need to wait until the backend development team rebuilds and redeploys the entire application. Edited schemas are saved in a database, and you can implement the functionality to prioritize them when SurveyJS Form Library loads a schema for display (see the [Display a Form](#display-a-form) section above). As a result, users can use an edited form immediately after the content or product manager modifies it. If the schema modification requires an update of domain models to maintain the model–schema synchronization, the backend development team may perform this update and rebuild and redeploy the application according to their own schedule. |
| 55 | + |
| 56 | +## Generate Domain Model Code Based on Form JSON Schemas |
| 57 | + |
| 58 | +Previously, you saw how to [implement a form generator](#generate-form-json-schemas-from-server-side-domain-models) that creates JSON schemas for client-side forms based on server-side domain models. You can also implement code that does the opposite—generates domain model code based on JSON schemas. This capability saves time for backend developers who implement domain models based on JSON schemas created by product managers. |
| 59 | + |
| 60 | +To implement a domain model generator, you need to parse the JSON schema being edited and convert the form fields to model properties. Users can view the generated domain model code under the Domain Model Code tab when they edit a form in Survey Creator as a product manager. View the following demo to see this functionality in action: [Create Domain Models](https://surveyjs.io/survey-creator/examples/create-domain-models/). Refer to the following file for full code: [codegenerator.js](/wwwroot/js/codegenerator.js). |
| 61 | + |
| 62 | +## Useful Links |
| 63 | + |
| 64 | +- [SurveyJS Website](https://surveyjs.io/) |
| 65 | +- [Form Library Documentation](https://surveyjs.io/form-library/documentation/overview) |
| 66 | +- [Form Library Demos](https://surveyjs.io/form-library/examples/nps-question/) |
| 67 | +- [Survey Creator Documentation](https://surveyjs.io/survey-creator/documentation/overview) |
| 68 | +- [Survey Creator Demos](https://surveyjs.io/survey-creator/examples/free-nps-survey-template/) |
0 commit comments