Skip to content

Commit 61a5af2

Browse files
committed
Add code generator to admin part
1 parent f6e7b56 commit 61a5af2

File tree

5 files changed

+98
-8
lines changed

5 files changed

+98
-8
lines changed

Data/nps-survey.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"name": "NPSSurvey",
23
"completedHtmlOnCondition": [
34
{
45
"expression": "{NPSScore} <= 6 or {Rebuy} = false",
@@ -181,7 +182,7 @@
181182
{
182183
"type": "text",
183184
"name": "Email",
184-
"inputType": "email",
185+
"inputType": "email",
185186
"visibleIf": "{Testimonial} = 'yes'",
186187
"title": {
187188
"default": "What is your email address?",

Data/patient-assessment.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"name": "PatientAssessment",
23
"title": "Patient Assessment Form",
34
"logoPosition": "right",
45
"focusFirstQuestionAutomatic": false,
@@ -429,7 +430,7 @@
429430
"name": "FamilyHistory",
430431
"cellType": "text",
431432
"titleLocation": "hidden",
432-
"rowCount": 1,
433+
"rowCount": 1,
433434
"columns": [
434435
{
435436
"name": "Relation"
@@ -507,7 +508,7 @@
507508
"columns": [
508509
{
509510
"name": "Name",
510-
"isRequired": true,
511+
"isRequired": true,
511512
"cellType": "dropdown",
512513
"choices": [
513514
{
@@ -534,8 +535,8 @@
534535
},
535536
{
536537
"name": "Date",
537-
"cellType": "text",
538-
"inputType": "date"
538+
"cellType": "text",
539+
"inputType": "date"
539540
},
540541
{
541542
"name": "Place",

Views/Home/EditForm.cshtml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<link rel="stylesheet" href="https://unpkg.com/survey-creator-core/survey-creator-core.css" />
1111
<script src="~/js/form_api.js" asp-append-version="true"></script>
1212
<script src="~/js/creatorjs.js" asp-append-version="true"></script>
13+
<script src="~/js/codegenerator.js" asp-append-version="true"></script>
1314
@{
1415
ViewData["Title"] = "Edit Form: " + Model.FormName;
1516
}

wwwroot/js/codegenerator.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
function isNameCorrect(name) {
2+
return /^@?[a-zA-Z_]\w*(\.@?[a-zA-Z_]\w*)*$/.test(name);
3+
}
4+
5+
function isListQuestionType(el) {
6+
return ["paneldynamic", "matrixdynamic", "matrixdropdown"].indexOf(el.getType()) > -1;
7+
}
8+
9+
function getNestedItemClassName(name) {
10+
return name + "Item";
11+
}
12+
13+
function getElementTypeName(el) {
14+
if (isListQuestionType(el)) return "IList<" + getNestedItemClassName(el.name) + ">";
15+
if (el.getType() === "text") {
16+
if (el.inputType === "number") return "int";
17+
if (el.inputType === "date" || el.inputType === "localedate") return "DateTime";
18+
}
19+
if (el.getType() === "boolean") return "bool"
20+
return "string";
21+
}
22+
function getCodePadding() { return " "; }
23+
24+
function generateClassByElements(className, elements, lines) {
25+
lines.push("public class " + className + " {");
26+
elements.forEach(el => {
27+
if (el.isQuestion || el.getType() === "matrixdropdowncolumn") {
28+
lines.push(getCodePadding() + getElementTypeName(el) + " " + el.name + " { get; set; }")
29+
}
30+
});
31+
lines.push("}")
32+
}
33+
34+
function generateDomainModelsCode(survey) {
35+
const lines = [];
36+
generateClassByElements(survey.name, survey.getAllQuestions(), lines);
37+
survey.getAllQuestions().forEach(q => {
38+
if (!isListQuestionType(q)) return;
39+
if (q.getType() === "paneldynamic") {
40+
lines.push("");
41+
generateClassByElements(getNestedItemClassName(q.name), q.elements, lines);
42+
} else {
43+
lines.push("");
44+
generateClassByElements(getNestedItemClassName(q.name), q.columns, lines);
45+
}
46+
});
47+
return lines.join("\n");
48+
}

wwwroot/js/creatorjs.js

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
function getCreatorOptions(isAdmin) {
1+
//Add survey name property and set the maximum length for question and column names
2+
Survey.Serializer.addProperty("survey", { name: "name", maxLength: 50, required: true, category: "general", visibleIndex: 0 });
3+
Survey.Serializer.findProperty("question", "name").maxLength = 50;
4+
Survey.Serializer.findProperty("matrixdropdown", "name").maxLength = 50;
5+
6+
function getCreatorOptions(isAdmin) {
27
return {
38
showLogicTab: true,
49
isAutoSave: true,
@@ -12,8 +17,10 @@ function setupCreator(creator, formName, isAdmin) {
1217
}
1318
creator.readOnly = true;
1419
SurveyCreator.settings.designer.showAddQuestionButton = isAdmin;
15-
if (!isAdmin) {
16-
//Setup Creator for a content manager
20+
if (isAdmin) {
21+
setupCreatorForProductManager(creator);
22+
}
23+
else {
1724
setupCreatorForContentManager(creator);
1825
}
1926
loadForm(formName, creator);
@@ -52,6 +59,38 @@ function setupCreatorForContentManager(creator) {
5259
}
5360
});
5461
}
62+
function setupCreatorForProductManager(creator) {
63+
ko.components.register("svc-tab-servercode", {
64+
viewModel: {
65+
createViewModel: (params, componentInfo) => {
66+
const creator = params.creator;
67+
var model = {
68+
generatedCode: generateDomainModelsCode(creator.survey)
69+
};
70+
return model;
71+
}
72+
},
73+
template: `
74+
<textarea data-bind="value:generatedCode" style="width:100%;height:100%;padding:'5px'">
75+
</textarea>
76+
`
77+
});
78+
creator.onPropertyValidationCustomError.add((sender, options) => {
79+
if (options.propertyName !== "name") return;
80+
//We need to validate the name property for a question, the survey and a matrix column
81+
if (options.obj.isQuestion || ["survey", "matrixdropdowncolumn"].indexOf(options.obj.getType()) > -1) {
82+
if (!isNameCorrect(options.value)) {
83+
options.error = "The current name can't be used as a property in the server code. Please correct it.";
84+
}
85+
}
86+
})
87+
const templatesPlugin = {
88+
activate: () => { },
89+
deactivate: () => { return true; }
90+
};
91+
//Add plug-in. We do nothing on activate/deactivate. Place it as first tab and set to "svc-tab-servercode" the component name
92+
creator.addPluginTab("servercode", templatesPlugin, "Domain Models Code", "svc-tab-servercode", 0);
93+
}
5594
function isObjColumn(obj) {
5695
return !!obj && obj.getType() === "matrixdropdowncolumn";
5796
}

0 commit comments

Comments
 (0)