pict-section-formeditor 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +118 -0
- package/docs/.nojekyll +0 -0
- package/docs/README.md +162 -0
- package/docs/_sidebar.md +23 -0
- package/docs/_topbar.md +5 -0
- package/docs/cover.md +12 -0
- package/docs/css/docuserve.css +73 -0
- package/docs/index.html +39 -0
- package/docs/retold-catalog.json +224 -0
- package/docs/retold-keyword-index.json +46846 -0
- package/example_applications/form_editor/.quackage.json +10 -0
- package/example_applications/form_editor/FormEditor-Example-Application.js +226 -0
- package/example_applications/form_editor/html/icon-chooser.html +375 -0
- package/example_applications/form_editor/html/index.html +54 -0
- package/example_applications/form_editor/package.json +50 -0
- package/package.json +55 -0
- package/sample_manifests/Complex-Table.json +974 -0
- package/sample_manifests/Distill-Example.json +200 -0
- package/sample_manifests/Gradebook-Assignment.json +38 -0
- package/sample_manifests/Gradebook-Student.json +40 -0
- package/sample_manifests/Manyfest-Editor.json +347 -0
- package/sample_manifests/Simple-Form.json +232 -0
- package/sample_manifests/Simple-Table.json +79 -0
- package/source/Pict-Section-FormEditor-DefaultConfiguration.js +3321 -0
- package/source/Pict-Section-FormEditor.js +35 -0
- package/source/providers/Pict-Provider-ChildPictManager-Application.js +40 -0
- package/source/providers/Pict-Provider-ChildPictManager.js +238 -0
- package/source/providers/Pict-Provider-FormEditorDocumentation.js +356 -0
- package/source/providers/Pict-Provider-FormEditorDragDrop.js +535 -0
- package/source/providers/Pict-Provider-FormEditorIconography.js +1002 -0
- package/source/providers/Pict-Provider-FormEditorManifestOps.js +1443 -0
- package/source/providers/Pict-Provider-FormEditorRendering.js +730 -0
- package/source/providers/Pict-Provider-FormEditorUtilities.js +862 -0
- package/source/providers/Pict-Provider-PreviewCSS.js +42 -0
- package/source/views/PictView-FormEditor-InlineEditing.js +309 -0
- package/source/views/PictView-FormEditor-InputTypePicker.js +532 -0
- package/source/views/PictView-FormEditor-PropertiesPanel.js +7730 -0
- package/source/views/PictView-FormEditor.js +681 -0
- package/test/Pict-Section-FormEditor_tests.js +4102 -0
- package/user-documentation/.pict_documentation_topics.json +695 -0
- package/user-documentation/Getting-Started.md +32 -0
- package/user-documentation/Groups.md +52 -0
- package/user-documentation/Inputs.md +98 -0
- package/user-documentation/Sections.md +36 -0
- package/user-documentation/Shortcuts.md +44 -0
- package/user-documentation/Solver-Expression-Walkthrough.md +176 -0
- package/user-documentation/Solver-Expressions-Advanced.md +344 -0
- package/user-documentation/Solver-Functions.md +213 -0
- package/user-documentation/Solvers.md +81 -0
- package/user-documentation/ToC.md +18 -0
- package/user-documentation/solverfunctions/abs.md +84 -0
- package/user-documentation/solverfunctions/aggregationhistogram.md +83 -0
- package/user-documentation/solverfunctions/aggregationhistogrambyobject.md +64 -0
- package/user-documentation/solverfunctions/arrayconcat.md +64 -0
- package/user-documentation/solverfunctions/avg.md +81 -0
- package/user-documentation/solverfunctions/bucketset.md +69 -0
- package/user-documentation/solverfunctions/ceil.md +70 -0
- package/user-documentation/solverfunctions/cleanvaluearray.md +66 -0
- package/user-documentation/solverfunctions/cleanvalueobject.md +68 -0
- package/user-documentation/solverfunctions/colorgroupbackground.md +60 -0
- package/user-documentation/solverfunctions/colorinputbackground.md +62 -0
- package/user-documentation/solverfunctions/colorinputbackgroundtabular.md +64 -0
- package/user-documentation/solverfunctions/colorsectionbackground.md +59 -0
- package/user-documentation/solverfunctions/compare.md +72 -0
- package/user-documentation/solverfunctions/concat.md +73 -0
- package/user-documentation/solverfunctions/concatraw.md +73 -0
- package/user-documentation/solverfunctions/cos.md +75 -0
- package/user-documentation/solverfunctions/count.md +73 -0
- package/user-documentation/solverfunctions/countset.md +65 -0
- package/user-documentation/solverfunctions/countsetelements.md +63 -0
- package/user-documentation/solverfunctions/createarrayfromabsolutevalues.md +63 -0
- package/user-documentation/solverfunctions/createvalueobjectbyhashes.md +69 -0
- package/user-documentation/solverfunctions/cumulativesummation.md +96 -0
- package/user-documentation/solverfunctions/dateadddays.md +79 -0
- package/user-documentation/solverfunctions/dateaddhours.md +74 -0
- package/user-documentation/solverfunctions/dateaddmilliseconds.md +65 -0
- package/user-documentation/solverfunctions/dateaddminutes.md +72 -0
- package/user-documentation/solverfunctions/dateaddmonths.md +74 -0
- package/user-documentation/solverfunctions/dateaddseconds.md +66 -0
- package/user-documentation/solverfunctions/dateaddweeks.md +73 -0
- package/user-documentation/solverfunctions/dateaddyears.md +74 -0
- package/user-documentation/solverfunctions/datedaydifference.md +84 -0
- package/user-documentation/solverfunctions/datefromparts.md +81 -0
- package/user-documentation/solverfunctions/datehourdifference.md +64 -0
- package/user-documentation/solverfunctions/datemathadd.md +72 -0
- package/user-documentation/solverfunctions/datemilliseconddifference.md +64 -0
- package/user-documentation/solverfunctions/dateminutedifference.md +64 -0
- package/user-documentation/solverfunctions/datemonthdifference.md +66 -0
- package/user-documentation/solverfunctions/dateseconddifference.md +64 -0
- package/user-documentation/solverfunctions/dateweekdifference.md +65 -0
- package/user-documentation/solverfunctions/dateyeardifference.md +64 -0
- package/user-documentation/solverfunctions/differencearrays.md +59 -0
- package/user-documentation/solverfunctions/disablesolverordinal.md +58 -0
- package/user-documentation/solverfunctions/distributionhistogram.md +96 -0
- package/user-documentation/solverfunctions/distributionhistogrambyobject.md +64 -0
- package/user-documentation/solverfunctions/enablesolverordinal.md +57 -0
- package/user-documentation/solverfunctions/entryinset.md +72 -0
- package/user-documentation/solverfunctions/euler.md +77 -0
- package/user-documentation/solverfunctions/exp.md +74 -0
- package/user-documentation/solverfunctions/findfirstvaluebyexactmatch.md +67 -0
- package/user-documentation/solverfunctions/findfirstvaluebystringincludes.md +67 -0
- package/user-documentation/solverfunctions/flatten.md +76 -0
- package/user-documentation/solverfunctions/floor.md +70 -0
- package/user-documentation/solverfunctions/gaussianelimination.md +75 -0
- package/user-documentation/solverfunctions/generatearrayofobjectsfromsets.md +70 -0
- package/user-documentation/solverfunctions/generatehtmlhexcolor.md +67 -0
- package/user-documentation/solverfunctions/getvalue.md +90 -0
- package/user-documentation/solverfunctions/getvaluearray.md +64 -0
- package/user-documentation/solverfunctions/getvalueobject.md +67 -0
- package/user-documentation/solverfunctions/hidesections.md +58 -0
- package/user-documentation/solverfunctions/if.md +109 -0
- package/user-documentation/solverfunctions/iterativeseries.md +107 -0
- package/user-documentation/solverfunctions/join.md +75 -0
- package/user-documentation/solverfunctions/joinraw.md +64 -0
- package/user-documentation/solverfunctions/largestinset.md +63 -0
- package/user-documentation/solverfunctions/leastsquares.md +66 -0
- package/user-documentation/solverfunctions/linest.md +58 -0
- package/user-documentation/solverfunctions/log.md +74 -0
- package/user-documentation/solverfunctions/logvalues.md +65 -0
- package/user-documentation/solverfunctions/match.md +71 -0
- package/user-documentation/solverfunctions/matrixinverse.md +67 -0
- package/user-documentation/solverfunctions/matrixmultiply.md +71 -0
- package/user-documentation/solverfunctions/matrixtranspose.md +72 -0
- package/user-documentation/solverfunctions/matrixvectormultiply.md +69 -0
- package/user-documentation/solverfunctions/max.md +73 -0
- package/user-documentation/solverfunctions/mean.md +63 -0
- package/user-documentation/solverfunctions/median.md +79 -0
- package/user-documentation/solverfunctions/min.md +73 -0
- package/user-documentation/solverfunctions/mode.md +66 -0
- package/user-documentation/solverfunctions/objectkeystoarray.md +66 -0
- package/user-documentation/solverfunctions/objectvaluessortbyexternalobjectarray.md +65 -0
- package/user-documentation/solverfunctions/objectvaluestoarray.md +67 -0
- package/user-documentation/solverfunctions/percent.md +75 -0
- package/user-documentation/solverfunctions/pi.md +77 -0
- package/user-documentation/solverfunctions/polynomialregression.md +69 -0
- package/user-documentation/solverfunctions/predict.md +71 -0
- package/user-documentation/solverfunctions/rad.md +85 -0
- package/user-documentation/solverfunctions/randomfloat.md +63 -0
- package/user-documentation/solverfunctions/randomfloatbetween.md +72 -0
- package/user-documentation/solverfunctions/randomfloatupto.md +65 -0
- package/user-documentation/solverfunctions/randominteger.md +56 -0
- package/user-documentation/solverfunctions/randomintegerbetween.md +72 -0
- package/user-documentation/solverfunctions/randomintegerupto.md +64 -0
- package/user-documentation/solverfunctions/refreshtabularsection.md +57 -0
- package/user-documentation/solverfunctions/resolvehtmlentities.md +64 -0
- package/user-documentation/solverfunctions/round.md +111 -0
- package/user-documentation/solverfunctions/runsolvers.md +49 -0
- package/user-documentation/solverfunctions/setconcatenate.md +64 -0
- package/user-documentation/solverfunctions/setgroupvisibility.md +60 -0
- package/user-documentation/solverfunctions/setsectionvisibility.md +59 -0
- package/user-documentation/solverfunctions/setsolverordinalenabled.md +59 -0
- package/user-documentation/solverfunctions/settabularrowlength.md +57 -0
- package/user-documentation/solverfunctions/setvalue.md +65 -0
- package/user-documentation/solverfunctions/showsections.md +58 -0
- package/user-documentation/solverfunctions/sin.md +83 -0
- package/user-documentation/solverfunctions/slice.md +80 -0
- package/user-documentation/solverfunctions/smallestinset.md +63 -0
- package/user-documentation/solverfunctions/sortarray.md +58 -0
- package/user-documentation/solverfunctions/sorthistogram.md +70 -0
- package/user-documentation/solverfunctions/sorthistogrambykeys.md +69 -0
- package/user-documentation/solverfunctions/sortset.md +75 -0
- package/user-documentation/solverfunctions/sqrt.md +85 -0
- package/user-documentation/solverfunctions/stdev.md +81 -0
- package/user-documentation/solverfunctions/stdeva.md +58 -0
- package/user-documentation/solverfunctions/stdevp.md +83 -0
- package/user-documentation/solverfunctions/stringcountsegments.md +66 -0
- package/user-documentation/solverfunctions/stringgetsegments.md +74 -0
- package/user-documentation/solverfunctions/subtractingsummation.md +66 -0
- package/user-documentation/solverfunctions/sum.md +78 -0
- package/user-documentation/solverfunctions/tan.md +78 -0
- package/user-documentation/solverfunctions/tofixed.md +75 -0
- package/user-documentation/solverfunctions/unionarrays.md +59 -0
- package/user-documentation/solverfunctions/uniquearray.md +58 -0
- package/user-documentation/solverfunctions/var.md +67 -0
- package/user-documentation/solverfunctions/vara.md +58 -0
- package/user-documentation/solverfunctions/varp.md +66 -0
- package/user-documentation/solverfunctions/when.md +98 -0
|
@@ -0,0 +1,1443 @@
|
|
|
1
|
+
const libPictProvider = require('pict-provider');
|
|
2
|
+
|
|
3
|
+
class FormEditorManifestOps extends libPictProvider
|
|
4
|
+
{
|
|
5
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
6
|
+
{
|
|
7
|
+
super(pFable, pOptions, pServiceHash);
|
|
8
|
+
|
|
9
|
+
this.serviceType = 'PictProvider';
|
|
10
|
+
|
|
11
|
+
// Back-reference to the parent FormEditor view (set after construction)
|
|
12
|
+
this._ParentFormEditor = null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Reconcile the manifest structure so that every Descriptor's PictForm
|
|
17
|
+
* reference is reflected in its Section's Group's Rows[].Inputs[] arrays.
|
|
18
|
+
*
|
|
19
|
+
* Existing manifests store layout information entirely in the Descriptors'
|
|
20
|
+
* PictForm objects (Section, Group, Row) and do not carry Rows/Inputs
|
|
21
|
+
* arrays on the Groups. This method builds those arrays from the
|
|
22
|
+
* Descriptors so the visual editor can render them.
|
|
23
|
+
*
|
|
24
|
+
* It is safe to call repeatedly — it only adds missing structure and never
|
|
25
|
+
* removes or duplicates entries.
|
|
26
|
+
*/
|
|
27
|
+
_reconcileManifestStructure()
|
|
28
|
+
{
|
|
29
|
+
let tmpManifest = this._resolveManifestData();
|
|
30
|
+
if (!tmpManifest)
|
|
31
|
+
{
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!Array.isArray(tmpManifest.Sections))
|
|
36
|
+
{
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!tmpManifest.Descriptors || typeof tmpManifest.Descriptors !== 'object')
|
|
41
|
+
{
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Build a quick lookup: SectionHash -> section index
|
|
46
|
+
let tmpSectionMap = {};
|
|
47
|
+
for (let i = 0; i < tmpManifest.Sections.length; i++)
|
|
48
|
+
{
|
|
49
|
+
let tmpSection = tmpManifest.Sections[i];
|
|
50
|
+
if (tmpSection.Hash)
|
|
51
|
+
{
|
|
52
|
+
tmpSectionMap[tmpSection.Hash] = i;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Ensure every section has a Groups array
|
|
56
|
+
if (!Array.isArray(tmpSection.Groups))
|
|
57
|
+
{
|
|
58
|
+
tmpSection.Groups = [];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Build a lookup: SectionHash -> GroupHash -> group index
|
|
63
|
+
let tmpGroupMap = {};
|
|
64
|
+
for (let i = 0; i < tmpManifest.Sections.length; i++)
|
|
65
|
+
{
|
|
66
|
+
let tmpSection = tmpManifest.Sections[i];
|
|
67
|
+
let tmpSectionHash = tmpSection.Hash || '';
|
|
68
|
+
tmpGroupMap[tmpSectionHash] = {};
|
|
69
|
+
for (let j = 0; j < tmpSection.Groups.length; j++)
|
|
70
|
+
{
|
|
71
|
+
let tmpGroup = tmpSection.Groups[j];
|
|
72
|
+
if (tmpGroup.Hash)
|
|
73
|
+
{
|
|
74
|
+
tmpGroupMap[tmpSectionHash][tmpGroup.Hash] = j;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Build a set of all Addresses already present in any Rows[].Inputs[]
|
|
80
|
+
let tmpExistingAddresses = {};
|
|
81
|
+
for (let i = 0; i < tmpManifest.Sections.length; i++)
|
|
82
|
+
{
|
|
83
|
+
let tmpSection = tmpManifest.Sections[i];
|
|
84
|
+
for (let j = 0; j < tmpSection.Groups.length; j++)
|
|
85
|
+
{
|
|
86
|
+
let tmpGroup = tmpSection.Groups[j];
|
|
87
|
+
if (Array.isArray(tmpGroup.Rows))
|
|
88
|
+
{
|
|
89
|
+
for (let k = 0; k < tmpGroup.Rows.length; k++)
|
|
90
|
+
{
|
|
91
|
+
let tmpRow = tmpGroup.Rows[k];
|
|
92
|
+
if (tmpRow && Array.isArray(tmpRow.Inputs))
|
|
93
|
+
{
|
|
94
|
+
for (let m = 0; m < tmpRow.Inputs.length; m++)
|
|
95
|
+
{
|
|
96
|
+
tmpExistingAddresses[tmpRow.Inputs[m]] = true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Walk every Descriptor and place it into the correct Rows[].Inputs[]
|
|
105
|
+
let tmpDescriptorKeys = Object.keys(tmpManifest.Descriptors);
|
|
106
|
+
for (let d = 0; d < tmpDescriptorKeys.length; d++)
|
|
107
|
+
{
|
|
108
|
+
let tmpAddress = tmpDescriptorKeys[d];
|
|
109
|
+
|
|
110
|
+
// Skip if already placed
|
|
111
|
+
if (tmpExistingAddresses[tmpAddress])
|
|
112
|
+
{
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let tmpDescriptor = tmpManifest.Descriptors[tmpAddress];
|
|
117
|
+
if (!tmpDescriptor || !tmpDescriptor.PictForm)
|
|
118
|
+
{
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let tmpPictForm = tmpDescriptor.PictForm;
|
|
123
|
+
let tmpSectionHash = tmpPictForm.Section;
|
|
124
|
+
if (!tmpSectionHash || !tmpSectionMap.hasOwnProperty(tmpSectionHash))
|
|
125
|
+
{
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
let tmpSectionIndex = tmpSectionMap[tmpSectionHash];
|
|
130
|
+
let tmpSection = tmpManifest.Sections[tmpSectionIndex];
|
|
131
|
+
|
|
132
|
+
// Resolve the group — if PictForm.Group is missing, use the first
|
|
133
|
+
// group; create a default group if none exist.
|
|
134
|
+
let tmpGroupHash = tmpPictForm.Group || null;
|
|
135
|
+
let tmpGroupIndex = -1;
|
|
136
|
+
|
|
137
|
+
if (tmpGroupHash && tmpGroupMap[tmpSectionHash].hasOwnProperty(tmpGroupHash))
|
|
138
|
+
{
|
|
139
|
+
tmpGroupIndex = tmpGroupMap[tmpSectionHash][tmpGroupHash];
|
|
140
|
+
}
|
|
141
|
+
else if (!tmpGroupHash && tmpSection.Groups.length > 0)
|
|
142
|
+
{
|
|
143
|
+
// Default to first group when PictForm.Group is omitted
|
|
144
|
+
tmpGroupIndex = 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (tmpGroupIndex < 0)
|
|
148
|
+
{
|
|
149
|
+
// Create a default group for this section
|
|
150
|
+
let tmpNewGroupHash = tmpGroupHash || (tmpSectionHash + 'Group_Default');
|
|
151
|
+
let tmpNewGroupName = tmpGroupHash || 'Default';
|
|
152
|
+
tmpSection.Groups.push(
|
|
153
|
+
{
|
|
154
|
+
Hash: tmpNewGroupHash,
|
|
155
|
+
Name: tmpNewGroupName,
|
|
156
|
+
Layout: 'Record'
|
|
157
|
+
});
|
|
158
|
+
tmpGroupIndex = tmpSection.Groups.length - 1;
|
|
159
|
+
tmpGroupMap[tmpSectionHash][tmpNewGroupHash] = tmpGroupIndex;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let tmpGroup = tmpSection.Groups[tmpGroupIndex];
|
|
163
|
+
|
|
164
|
+
// Ensure the group has a Rows array
|
|
165
|
+
if (!Array.isArray(tmpGroup.Rows))
|
|
166
|
+
{
|
|
167
|
+
tmpGroup.Rows = [];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// PictForm.Row is 1-based; pad with empty rows if necessary
|
|
171
|
+
let tmpRowNumber = (typeof tmpPictForm.Row === 'number' && tmpPictForm.Row > 0) ? tmpPictForm.Row : 1;
|
|
172
|
+
let tmpRowIndex = tmpRowNumber - 1;
|
|
173
|
+
while (tmpGroup.Rows.length <= tmpRowIndex)
|
|
174
|
+
{
|
|
175
|
+
tmpGroup.Rows.push({ Inputs: [] });
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
let tmpRow = tmpGroup.Rows[tmpRowIndex];
|
|
179
|
+
if (!Array.isArray(tmpRow.Inputs))
|
|
180
|
+
{
|
|
181
|
+
tmpRow.Inputs = [];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
tmpRow.Inputs.push(tmpAddress);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
addSection()
|
|
189
|
+
{
|
|
190
|
+
let tmpManifest = this._resolveManifestData();
|
|
191
|
+
if (!tmpManifest)
|
|
192
|
+
{
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (!Array.isArray(tmpManifest.Sections))
|
|
197
|
+
{
|
|
198
|
+
tmpManifest.Sections = [];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
let tmpIndex = tmpManifest.Sections.length;
|
|
202
|
+
let tmpSectionNum = tmpIndex + 1;
|
|
203
|
+
let tmpSectionName = `Section ${tmpSectionNum}`;
|
|
204
|
+
let tmpSectionHash = `S${tmpSectionNum}`;
|
|
205
|
+
let tmpGroupName = 'Group 1';
|
|
206
|
+
let tmpGroupHash = `${tmpSectionHash}_G1`;
|
|
207
|
+
|
|
208
|
+
tmpManifest.Sections.push(
|
|
209
|
+
{
|
|
210
|
+
Hash: tmpSectionHash,
|
|
211
|
+
Name: tmpSectionName,
|
|
212
|
+
Groups:
|
|
213
|
+
[
|
|
214
|
+
{
|
|
215
|
+
Hash: tmpGroupHash,
|
|
216
|
+
Name: tmpGroupName,
|
|
217
|
+
Layout: 'Record'
|
|
218
|
+
}
|
|
219
|
+
]
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
removeSection(pIndex)
|
|
226
|
+
{
|
|
227
|
+
let tmpManifest = this._resolveManifestData();
|
|
228
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
229
|
+
{
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (pIndex >= 0 && pIndex < tmpManifest.Sections.length)
|
|
234
|
+
{
|
|
235
|
+
// Clean up Descriptor entries for all inputs in this section
|
|
236
|
+
let tmpSection = tmpManifest.Sections[pIndex];
|
|
237
|
+
this._removeDescriptorsForSection(tmpManifest, tmpSection);
|
|
238
|
+
|
|
239
|
+
tmpManifest.Sections.splice(pIndex, 1);
|
|
240
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
moveSectionUp(pIndex)
|
|
245
|
+
{
|
|
246
|
+
let tmpManifest = this._resolveManifestData();
|
|
247
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections) || pIndex <= 0)
|
|
248
|
+
{
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
let tmpSection = tmpManifest.Sections.splice(pIndex, 1)[0];
|
|
253
|
+
tmpManifest.Sections.splice(pIndex - 1, 0, tmpSection);
|
|
254
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
moveSectionDown(pIndex)
|
|
258
|
+
{
|
|
259
|
+
let tmpManifest = this._resolveManifestData();
|
|
260
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections) || pIndex >= tmpManifest.Sections.length - 1)
|
|
261
|
+
{
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
let tmpSection = tmpManifest.Sections.splice(pIndex, 1)[0];
|
|
266
|
+
tmpManifest.Sections.splice(pIndex + 1, 0, tmpSection);
|
|
267
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
updateSectionProperty(pSectionIndex, pProperty, pValue)
|
|
271
|
+
{
|
|
272
|
+
let tmpManifest = this._resolveManifestData();
|
|
273
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
274
|
+
{
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
279
|
+
if (tmpSection)
|
|
280
|
+
{
|
|
281
|
+
let tmpOldValue = tmpSection[pProperty];
|
|
282
|
+
tmpSection[pProperty] = pValue;
|
|
283
|
+
|
|
284
|
+
// When the section Hash changes, cascade to group hashes that
|
|
285
|
+
// are still auto-generated. Auto-generated group hashes follow
|
|
286
|
+
// the pattern {SectionHash}_G{...}. If the user has overridden
|
|
287
|
+
// a group hash the "_G" prefix after the old section hash will
|
|
288
|
+
// no longer be present, so it is skipped.
|
|
289
|
+
if (pProperty === 'Hash' && tmpOldValue !== pValue && Array.isArray(tmpSection.Groups))
|
|
290
|
+
{
|
|
291
|
+
let tmpOldPrefix = tmpOldValue + '_G';
|
|
292
|
+
let tmpNewPrefix = pValue + '_G';
|
|
293
|
+
for (let i = 0; i < tmpSection.Groups.length; i++)
|
|
294
|
+
{
|
|
295
|
+
let tmpGroup = tmpSection.Groups[i];
|
|
296
|
+
if (tmpGroup.Hash && tmpGroup.Hash.indexOf(tmpOldPrefix) === 0)
|
|
297
|
+
{
|
|
298
|
+
tmpGroup.Hash = tmpNewPrefix + tmpGroup.Hash.substring(tmpOldPrefix.length);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
addGroup(pSectionIndex)
|
|
306
|
+
{
|
|
307
|
+
let tmpManifest = this._resolveManifestData();
|
|
308
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
309
|
+
{
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
314
|
+
if (!tmpSection)
|
|
315
|
+
{
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (!Array.isArray(tmpSection.Groups))
|
|
320
|
+
{
|
|
321
|
+
tmpSection.Groups = [];
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
let tmpIndex = tmpSection.Groups.length;
|
|
325
|
+
let tmpSectionHash = tmpSection.Hash || '';
|
|
326
|
+
let tmpGroupNum = tmpIndex + 1;
|
|
327
|
+
let tmpGroupName = `Group ${tmpGroupNum}`;
|
|
328
|
+
let tmpGroupHash = `${tmpSectionHash}_G${tmpGroupNum}`;
|
|
329
|
+
|
|
330
|
+
tmpSection.Groups.push(
|
|
331
|
+
{
|
|
332
|
+
Hash: tmpGroupHash,
|
|
333
|
+
Name: tmpGroupName,
|
|
334
|
+
Layout: 'Record'
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
removeGroup(pSectionIndex, pGroupIndex)
|
|
341
|
+
{
|
|
342
|
+
let tmpManifest = this._resolveManifestData();
|
|
343
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
344
|
+
{
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
349
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
350
|
+
{
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (pGroupIndex >= 0 && pGroupIndex < tmpSection.Groups.length)
|
|
355
|
+
{
|
|
356
|
+
// Clean up Descriptor entries for all inputs in this group
|
|
357
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
358
|
+
this._removeDescriptorsForGroup(tmpManifest, tmpGroup);
|
|
359
|
+
|
|
360
|
+
tmpSection.Groups.splice(pGroupIndex, 1);
|
|
361
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
moveGroupUp(pSectionIndex, pGroupIndex)
|
|
366
|
+
{
|
|
367
|
+
let tmpManifest = this._resolveManifestData();
|
|
368
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
369
|
+
{
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
374
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups) || pGroupIndex <= 0)
|
|
375
|
+
{
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
let tmpGroup = tmpSection.Groups.splice(pGroupIndex, 1)[0];
|
|
380
|
+
tmpSection.Groups.splice(pGroupIndex - 1, 0, tmpGroup);
|
|
381
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
moveGroupDown(pSectionIndex, pGroupIndex)
|
|
385
|
+
{
|
|
386
|
+
let tmpManifest = this._resolveManifestData();
|
|
387
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
388
|
+
{
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
393
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups) || pGroupIndex >= tmpSection.Groups.length - 1)
|
|
394
|
+
{
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
let tmpGroup = tmpSection.Groups.splice(pGroupIndex, 1)[0];
|
|
399
|
+
tmpSection.Groups.splice(pGroupIndex + 1, 0, tmpGroup);
|
|
400
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
updateGroupProperty(pSectionIndex, pGroupIndex, pProperty, pValue)
|
|
404
|
+
{
|
|
405
|
+
let tmpManifest = this._resolveManifestData();
|
|
406
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
407
|
+
{
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
412
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
413
|
+
{
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
418
|
+
if (tmpGroup)
|
|
419
|
+
{
|
|
420
|
+
tmpGroup[pProperty] = pValue;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
addRow(pSectionIndex, pGroupIndex)
|
|
425
|
+
{
|
|
426
|
+
let tmpManifest = this._resolveManifestData();
|
|
427
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
428
|
+
{
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
433
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
434
|
+
{
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
439
|
+
if (!tmpGroup)
|
|
440
|
+
{
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (!Array.isArray(tmpGroup.Rows))
|
|
445
|
+
{
|
|
446
|
+
tmpGroup.Rows = [];
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
tmpGroup.Rows.push({ Inputs: [] });
|
|
450
|
+
|
|
451
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
removeRow(pSectionIndex, pGroupIndex, pRowIndex)
|
|
455
|
+
{
|
|
456
|
+
let tmpManifest = this._resolveManifestData();
|
|
457
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
458
|
+
{
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
463
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
464
|
+
{
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
469
|
+
if (!tmpGroup || !Array.isArray(tmpGroup.Rows))
|
|
470
|
+
{
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
if (pRowIndex >= 0 && pRowIndex < tmpGroup.Rows.length)
|
|
475
|
+
{
|
|
476
|
+
// Clean up Descriptor entries for all inputs in this row
|
|
477
|
+
let tmpRow = tmpGroup.Rows[pRowIndex];
|
|
478
|
+
if (tmpRow && Array.isArray(tmpRow.Inputs) && tmpManifest.Descriptors)
|
|
479
|
+
{
|
|
480
|
+
for (let i = 0; i < tmpRow.Inputs.length; i++)
|
|
481
|
+
{
|
|
482
|
+
let tmpAddress = tmpRow.Inputs[i];
|
|
483
|
+
if (typeof tmpAddress === 'string' && tmpManifest.Descriptors.hasOwnProperty(tmpAddress))
|
|
484
|
+
{
|
|
485
|
+
delete tmpManifest.Descriptors[tmpAddress];
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
tmpGroup.Rows.splice(pRowIndex, 1);
|
|
491
|
+
|
|
492
|
+
// Update PictForm.Row for inputs in subsequent rows
|
|
493
|
+
this._syncRowIndices(tmpManifest, tmpGroup);
|
|
494
|
+
|
|
495
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
moveRowUp(pSectionIndex, pGroupIndex, pRowIndex)
|
|
500
|
+
{
|
|
501
|
+
let tmpManifest = this._resolveManifestData();
|
|
502
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
503
|
+
{
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
508
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
509
|
+
{
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
514
|
+
if (!tmpGroup || !Array.isArray(tmpGroup.Rows) || pRowIndex <= 0)
|
|
515
|
+
{
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
let tmpRow = tmpGroup.Rows.splice(pRowIndex, 1)[0];
|
|
520
|
+
tmpGroup.Rows.splice(pRowIndex - 1, 0, tmpRow);
|
|
521
|
+
|
|
522
|
+
this._syncRowIndices(tmpManifest, tmpGroup);
|
|
523
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
moveRowDown(pSectionIndex, pGroupIndex, pRowIndex)
|
|
527
|
+
{
|
|
528
|
+
let tmpManifest = this._resolveManifestData();
|
|
529
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
530
|
+
{
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
535
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
536
|
+
{
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
541
|
+
if (!tmpGroup || !Array.isArray(tmpGroup.Rows) || pRowIndex >= tmpGroup.Rows.length - 1)
|
|
542
|
+
{
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
let tmpRow = tmpGroup.Rows.splice(pRowIndex, 1)[0];
|
|
547
|
+
tmpGroup.Rows.splice(pRowIndex + 1, 0, tmpRow);
|
|
548
|
+
|
|
549
|
+
this._syncRowIndices(tmpManifest, tmpGroup);
|
|
550
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
addInput(pSectionIndex, pGroupIndex, pRowIndex)
|
|
554
|
+
{
|
|
555
|
+
let tmpManifest = this._resolveManifestData();
|
|
556
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
557
|
+
{
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
562
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
563
|
+
{
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
568
|
+
if (!tmpGroup || !Array.isArray(tmpGroup.Rows))
|
|
569
|
+
{
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
let tmpRow = tmpGroup.Rows[pRowIndex];
|
|
574
|
+
if (!tmpRow)
|
|
575
|
+
{
|
|
576
|
+
return;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
if (!Array.isArray(tmpRow.Inputs))
|
|
580
|
+
{
|
|
581
|
+
tmpRow.Inputs = [];
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
if (!tmpManifest.Descriptors || typeof tmpManifest.Descriptors !== 'object')
|
|
585
|
+
{
|
|
586
|
+
tmpManifest.Descriptors = {};
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// Generate a unique address for this input using short format
|
|
590
|
+
let tmpInputNum = tmpRow.Inputs.length + 1;
|
|
591
|
+
let tmpSectionHash = tmpSection.Hash || 'S';
|
|
592
|
+
let tmpGroupHash = tmpGroup.Hash || 'G';
|
|
593
|
+
let tmpRowNum = pRowIndex + 1;
|
|
594
|
+
let tmpInputHash = `${tmpGroupHash}_R${tmpRowNum}_Input${tmpInputNum}`;
|
|
595
|
+
let tmpAddress = tmpInputHash;
|
|
596
|
+
|
|
597
|
+
// Ensure the address is unique in the Descriptors
|
|
598
|
+
while (tmpManifest.Descriptors.hasOwnProperty(tmpAddress))
|
|
599
|
+
{
|
|
600
|
+
tmpInputNum++;
|
|
601
|
+
tmpInputHash = `${tmpGroupHash}_R${tmpRowNum}_Input${tmpInputNum}`;
|
|
602
|
+
tmpAddress = tmpInputHash;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
let tmpInputName = `Input ${tmpInputNum}`;
|
|
606
|
+
|
|
607
|
+
// Create the Descriptor entry
|
|
608
|
+
tmpManifest.Descriptors[tmpAddress] =
|
|
609
|
+
{
|
|
610
|
+
Name: tmpInputName,
|
|
611
|
+
Hash: tmpInputHash,
|
|
612
|
+
DataType: 'String',
|
|
613
|
+
PictForm:
|
|
614
|
+
{
|
|
615
|
+
Section: tmpSectionHash,
|
|
616
|
+
Group: tmpGroupHash,
|
|
617
|
+
Row: tmpRowNum
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
// Store the Address reference in the row's Inputs array
|
|
622
|
+
tmpRow.Inputs.push(tmpAddress);
|
|
623
|
+
|
|
624
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
removeInput(pSectionIndex, pGroupIndex, pRowIndex, pInputIndex)
|
|
628
|
+
{
|
|
629
|
+
let tmpManifest = this._resolveManifestData();
|
|
630
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
631
|
+
{
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
636
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
637
|
+
{
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
642
|
+
if (!tmpGroup || !Array.isArray(tmpGroup.Rows))
|
|
643
|
+
{
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
let tmpRow = tmpGroup.Rows[pRowIndex];
|
|
648
|
+
if (!tmpRow || !Array.isArray(tmpRow.Inputs))
|
|
649
|
+
{
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
if (pInputIndex >= 0 && pInputIndex < tmpRow.Inputs.length)
|
|
654
|
+
{
|
|
655
|
+
// Remove the corresponding Descriptor entry
|
|
656
|
+
let tmpAddress = tmpRow.Inputs[pInputIndex];
|
|
657
|
+
if (typeof tmpAddress === 'string' && tmpManifest.Descriptors && tmpManifest.Descriptors.hasOwnProperty(tmpAddress))
|
|
658
|
+
{
|
|
659
|
+
delete tmpManifest.Descriptors[tmpAddress];
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
tmpRow.Inputs.splice(pInputIndex, 1);
|
|
663
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Move an input left (earlier) within its row.
|
|
669
|
+
*
|
|
670
|
+
* @param {number} pSectionIndex
|
|
671
|
+
* @param {number} pGroupIndex
|
|
672
|
+
* @param {number} pRowIndex
|
|
673
|
+
* @param {number} pInputIndex
|
|
674
|
+
*/
|
|
675
|
+
moveInputLeft(pSectionIndex, pGroupIndex, pRowIndex, pInputIndex)
|
|
676
|
+
{
|
|
677
|
+
let tmpManifest = this._resolveManifestData();
|
|
678
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
679
|
+
{
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
684
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
685
|
+
{
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
690
|
+
if (!tmpGroup || !Array.isArray(tmpGroup.Rows))
|
|
691
|
+
{
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
let tmpRow = tmpGroup.Rows[pRowIndex];
|
|
696
|
+
if (!tmpRow || !Array.isArray(tmpRow.Inputs))
|
|
697
|
+
{
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
if (pInputIndex <= 0 || pInputIndex >= tmpRow.Inputs.length)
|
|
702
|
+
{
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
let tmpItem = tmpRow.Inputs.splice(pInputIndex, 1)[0];
|
|
707
|
+
tmpRow.Inputs.splice(pInputIndex - 1, 0, tmpItem);
|
|
708
|
+
|
|
709
|
+
// Update the selection to follow the moved input
|
|
710
|
+
this._ParentFormEditor._SelectedInputIndices = [pSectionIndex, pGroupIndex, pRowIndex, pInputIndex - 1];
|
|
711
|
+
if (this._ParentFormEditor._PropertiesPanelView && this._ParentFormEditor._PropertiesPanelView._SelectedInput)
|
|
712
|
+
{
|
|
713
|
+
this._ParentFormEditor._PropertiesPanelView._SelectedInput.InputIndex = pInputIndex - 1;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* Move an input right (later) within its row.
|
|
721
|
+
*
|
|
722
|
+
* @param {number} pSectionIndex
|
|
723
|
+
* @param {number} pGroupIndex
|
|
724
|
+
* @param {number} pRowIndex
|
|
725
|
+
* @param {number} pInputIndex
|
|
726
|
+
*/
|
|
727
|
+
moveInputRight(pSectionIndex, pGroupIndex, pRowIndex, pInputIndex)
|
|
728
|
+
{
|
|
729
|
+
let tmpManifest = this._resolveManifestData();
|
|
730
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
731
|
+
{
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
736
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
737
|
+
{
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
742
|
+
if (!tmpGroup || !Array.isArray(tmpGroup.Rows))
|
|
743
|
+
{
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
let tmpRow = tmpGroup.Rows[pRowIndex];
|
|
748
|
+
if (!tmpRow || !Array.isArray(tmpRow.Inputs))
|
|
749
|
+
{
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
if (pInputIndex < 0 || pInputIndex >= tmpRow.Inputs.length - 1)
|
|
754
|
+
{
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
let tmpItem = tmpRow.Inputs.splice(pInputIndex, 1)[0];
|
|
759
|
+
tmpRow.Inputs.splice(pInputIndex + 1, 0, tmpItem);
|
|
760
|
+
|
|
761
|
+
// Update the selection to follow the moved input
|
|
762
|
+
this._ParentFormEditor._SelectedInputIndices = [pSectionIndex, pGroupIndex, pRowIndex, pInputIndex + 1];
|
|
763
|
+
if (this._ParentFormEditor._PropertiesPanelView && this._ParentFormEditor._PropertiesPanelView._SelectedInput)
|
|
764
|
+
{
|
|
765
|
+
this._ParentFormEditor._PropertiesPanelView._SelectedInput.InputIndex = pInputIndex + 1;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Return the list of ReferenceManifest keys in the manifest.
|
|
773
|
+
*
|
|
774
|
+
* @returns {Array<string>}
|
|
775
|
+
*/
|
|
776
|
+
getReferenceManifestNames()
|
|
777
|
+
{
|
|
778
|
+
let tmpManifest = this._resolveManifestData();
|
|
779
|
+
if (!tmpManifest || !tmpManifest.ReferenceManifests || typeof tmpManifest.ReferenceManifests !== 'object')
|
|
780
|
+
{
|
|
781
|
+
return [];
|
|
782
|
+
}
|
|
783
|
+
return Object.keys(tmpManifest.ReferenceManifests);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* Create a new ReferenceManifest entry.
|
|
788
|
+
*
|
|
789
|
+
* @param {string} pName - Desired name/key for the ReferenceManifest
|
|
790
|
+
* @returns {string} The actual key used (may differ if pName was taken)
|
|
791
|
+
*/
|
|
792
|
+
createReferenceManifest(pName)
|
|
793
|
+
{
|
|
794
|
+
let tmpManifest = this._resolveManifestData();
|
|
795
|
+
if (!tmpManifest)
|
|
796
|
+
{
|
|
797
|
+
return '';
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
if (!tmpManifest.ReferenceManifests || typeof tmpManifest.ReferenceManifests !== 'object')
|
|
801
|
+
{
|
|
802
|
+
tmpManifest.ReferenceManifests = {};
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
let tmpKey = (typeof pName === 'string' && pName.length > 0) ? pName : 'SubManifest_1';
|
|
806
|
+
|
|
807
|
+
// Ensure uniqueness
|
|
808
|
+
let tmpBase = tmpKey;
|
|
809
|
+
let tmpCounter = 1;
|
|
810
|
+
while (tmpManifest.ReferenceManifests.hasOwnProperty(tmpKey))
|
|
811
|
+
{
|
|
812
|
+
tmpCounter++;
|
|
813
|
+
tmpKey = tmpBase + '_' + tmpCounter;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
tmpManifest.ReferenceManifests[tmpKey] =
|
|
817
|
+
{
|
|
818
|
+
Scope: tmpKey,
|
|
819
|
+
Descriptors: {}
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
return tmpKey;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* Resolve a ReferenceManifest by name.
|
|
827
|
+
*
|
|
828
|
+
* @param {string} pManifestName - Key in ReferenceManifests
|
|
829
|
+
* @returns {object|null}
|
|
830
|
+
*/
|
|
831
|
+
_resolveReferenceManifest(pManifestName)
|
|
832
|
+
{
|
|
833
|
+
if (!pManifestName || typeof pManifestName !== 'string')
|
|
834
|
+
{
|
|
835
|
+
return null;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
let tmpManifest = this._resolveManifestData();
|
|
839
|
+
if (!tmpManifest || !tmpManifest.ReferenceManifests)
|
|
840
|
+
{
|
|
841
|
+
return null;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
return tmpManifest.ReferenceManifests[pManifestName] || null;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
/**
|
|
848
|
+
* Bind an existing ReferenceManifest to a group.
|
|
849
|
+
*
|
|
850
|
+
* @param {number} pSectionIndex
|
|
851
|
+
* @param {number} pGroupIndex
|
|
852
|
+
* @param {string} pManifestName - Key in ReferenceManifests
|
|
853
|
+
*/
|
|
854
|
+
bindReferenceManifest(pSectionIndex, pGroupIndex, pManifestName)
|
|
855
|
+
{
|
|
856
|
+
let tmpManifest = this._resolveManifestData();
|
|
857
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
858
|
+
{
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
863
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
864
|
+
{
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
869
|
+
if (!tmpGroup)
|
|
870
|
+
{
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
tmpGroup.RecordManifest = pManifestName;
|
|
875
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
* Unbind a ReferenceManifest from a group.
|
|
880
|
+
*
|
|
881
|
+
* @param {number} pSectionIndex
|
|
882
|
+
* @param {number} pGroupIndex
|
|
883
|
+
*/
|
|
884
|
+
unbindReferenceManifest(pSectionIndex, pGroupIndex)
|
|
885
|
+
{
|
|
886
|
+
let tmpManifest = this._resolveManifestData();
|
|
887
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
888
|
+
{
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
893
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
894
|
+
{
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
899
|
+
if (!tmpGroup)
|
|
900
|
+
{
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
delete tmpGroup.RecordManifest;
|
|
905
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* Create a new ReferenceManifest and bind it to a group in one step.
|
|
910
|
+
*
|
|
911
|
+
* @param {number} pSectionIndex
|
|
912
|
+
* @param {number} pGroupIndex
|
|
913
|
+
*/
|
|
914
|
+
createAndBindReferenceManifest(pSectionIndex, pGroupIndex)
|
|
915
|
+
{
|
|
916
|
+
let tmpManifest = this._resolveManifestData();
|
|
917
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
918
|
+
{
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
923
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
924
|
+
{
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
929
|
+
if (!tmpGroup)
|
|
930
|
+
{
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// Generate name based on group hash
|
|
935
|
+
let tmpBaseName = tmpGroup.Hash || ('Manifest_' + pSectionIndex + '_' + pGroupIndex);
|
|
936
|
+
let tmpKey = this.createReferenceManifest(tmpBaseName);
|
|
937
|
+
|
|
938
|
+
if (tmpKey)
|
|
939
|
+
{
|
|
940
|
+
tmpGroup.RecordManifest = tmpKey;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
/**
|
|
947
|
+
* Add a column (Descriptor) to the bound ReferenceManifest.
|
|
948
|
+
*
|
|
949
|
+
* @param {number} pSectionIndex
|
|
950
|
+
* @param {number} pGroupIndex
|
|
951
|
+
* @param {number} [pRow] - PictForm.Row value (defaults to 1)
|
|
952
|
+
*/
|
|
953
|
+
addSubmanifestColumn(pSectionIndex, pGroupIndex, pRow)
|
|
954
|
+
{
|
|
955
|
+
let tmpManifest = this._resolveManifestData();
|
|
956
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
957
|
+
{
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
962
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
963
|
+
{
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
968
|
+
if (!tmpGroup || !tmpGroup.RecordManifest)
|
|
969
|
+
{
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
let tmpRefManifest = this._resolveReferenceManifest(tmpGroup.RecordManifest);
|
|
974
|
+
if (!tmpRefManifest)
|
|
975
|
+
{
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
if (!tmpRefManifest.Descriptors || typeof tmpRefManifest.Descriptors !== 'object')
|
|
980
|
+
{
|
|
981
|
+
tmpRefManifest.Descriptors = {};
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
let tmpRow = (typeof pRow === 'number' && pRow > 0) ? pRow : 1;
|
|
985
|
+
|
|
986
|
+
// Generate a unique column address
|
|
987
|
+
let tmpColumnNum = Object.keys(tmpRefManifest.Descriptors).length + 1;
|
|
988
|
+
let tmpAddress = 'Column_' + tmpColumnNum;
|
|
989
|
+
while (tmpRefManifest.Descriptors.hasOwnProperty(tmpAddress))
|
|
990
|
+
{
|
|
991
|
+
tmpColumnNum++;
|
|
992
|
+
tmpAddress = 'Column_' + tmpColumnNum;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
let tmpColumnName = 'Column ' + tmpColumnNum;
|
|
996
|
+
|
|
997
|
+
tmpRefManifest.Descriptors[tmpAddress] =
|
|
998
|
+
{
|
|
999
|
+
Name: tmpColumnName,
|
|
1000
|
+
Hash: tmpAddress,
|
|
1001
|
+
DataType: 'String',
|
|
1002
|
+
PictForm:
|
|
1003
|
+
{
|
|
1004
|
+
Section: tmpSection.Hash || '',
|
|
1005
|
+
Group: tmpGroup.Hash || '',
|
|
1006
|
+
Row: tmpRow
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
/**
|
|
1014
|
+
* Remove a column (Descriptor) from the bound ReferenceManifest.
|
|
1015
|
+
*
|
|
1016
|
+
* @param {number} pSectionIndex
|
|
1017
|
+
* @param {number} pGroupIndex
|
|
1018
|
+
* @param {string} pColumnAddress - The Descriptor address key
|
|
1019
|
+
*/
|
|
1020
|
+
removeSubmanifestColumn(pSectionIndex, pGroupIndex, pColumnAddress)
|
|
1021
|
+
{
|
|
1022
|
+
let tmpManifest = this._resolveManifestData();
|
|
1023
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
1024
|
+
{
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
1029
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
1030
|
+
{
|
|
1031
|
+
return;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
1035
|
+
if (!tmpGroup || !tmpGroup.RecordManifest)
|
|
1036
|
+
{
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
let tmpRefManifest = this._resolveReferenceManifest(tmpGroup.RecordManifest);
|
|
1041
|
+
if (!tmpRefManifest || !tmpRefManifest.Descriptors)
|
|
1042
|
+
{
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
if (tmpRefManifest.Descriptors.hasOwnProperty(pColumnAddress))
|
|
1047
|
+
{
|
|
1048
|
+
delete tmpRefManifest.Descriptors[pColumnAddress];
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* Move a submanifest column up (earlier in key order).
|
|
1056
|
+
*/
|
|
1057
|
+
moveSubmanifestColumnUp(pSectionIndex, pGroupIndex, pColumnAddress)
|
|
1058
|
+
{
|
|
1059
|
+
this._reorderSubmanifestColumn(pSectionIndex, pGroupIndex, pColumnAddress, -1);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
/**
|
|
1063
|
+
* Move a submanifest column down (later in key order).
|
|
1064
|
+
*/
|
|
1065
|
+
moveSubmanifestColumnDown(pSectionIndex, pGroupIndex, pColumnAddress)
|
|
1066
|
+
{
|
|
1067
|
+
this._reorderSubmanifestColumn(pSectionIndex, pGroupIndex, pColumnAddress, 1);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
/**
|
|
1071
|
+
* Reorder a column within the submanifest Descriptors by rebuilding the object.
|
|
1072
|
+
*
|
|
1073
|
+
* @param {number} pSectionIndex
|
|
1074
|
+
* @param {number} pGroupIndex
|
|
1075
|
+
* @param {string} pColumnAddress
|
|
1076
|
+
* @param {number} pDirection - -1 for up, +1 for down
|
|
1077
|
+
*/
|
|
1078
|
+
_reorderSubmanifestColumn(pSectionIndex, pGroupIndex, pColumnAddress, pDirection)
|
|
1079
|
+
{
|
|
1080
|
+
let tmpManifest = this._resolveManifestData();
|
|
1081
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
1082
|
+
{
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
1087
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
1088
|
+
{
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
1093
|
+
if (!tmpGroup || !tmpGroup.RecordManifest)
|
|
1094
|
+
{
|
|
1095
|
+
return;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
let tmpRefManifest = this._resolveReferenceManifest(tmpGroup.RecordManifest);
|
|
1099
|
+
if (!tmpRefManifest || !tmpRefManifest.Descriptors)
|
|
1100
|
+
{
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
let tmpKeys = Object.keys(tmpRefManifest.Descriptors);
|
|
1105
|
+
let tmpIndex = tmpKeys.indexOf(pColumnAddress);
|
|
1106
|
+
if (tmpIndex < 0)
|
|
1107
|
+
{
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
let tmpNewIndex = tmpIndex + pDirection;
|
|
1112
|
+
if (tmpNewIndex < 0 || tmpNewIndex >= tmpKeys.length)
|
|
1113
|
+
{
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
// Swap keys
|
|
1118
|
+
let tmpSwap = tmpKeys[tmpNewIndex];
|
|
1119
|
+
tmpKeys[tmpNewIndex] = tmpKeys[tmpIndex];
|
|
1120
|
+
tmpKeys[tmpIndex] = tmpSwap;
|
|
1121
|
+
|
|
1122
|
+
// Rebuild the Descriptors object in new order
|
|
1123
|
+
let tmpNewDescriptors = {};
|
|
1124
|
+
for (let i = 0; i < tmpKeys.length; i++)
|
|
1125
|
+
{
|
|
1126
|
+
tmpNewDescriptors[tmpKeys[i]] = tmpRefManifest.Descriptors[tmpKeys[i]];
|
|
1127
|
+
}
|
|
1128
|
+
tmpRefManifest.Descriptors = tmpNewDescriptors;
|
|
1129
|
+
|
|
1130
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
/**
|
|
1134
|
+
* Group submanifest Descriptors by PictForm.Row.
|
|
1135
|
+
*
|
|
1136
|
+
* @param {object} pRefManifest - A ReferenceManifest object
|
|
1137
|
+
* @returns {Array} Array of { Row: number, Columns: [{ Address, Descriptor }, ...] }
|
|
1138
|
+
*/
|
|
1139
|
+
_getSubmanifestRows(pRefManifest)
|
|
1140
|
+
{
|
|
1141
|
+
let tmpResult = [];
|
|
1142
|
+
|
|
1143
|
+
if (!pRefManifest || !pRefManifest.Descriptors || typeof pRefManifest.Descriptors !== 'object')
|
|
1144
|
+
{
|
|
1145
|
+
return tmpResult;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
let tmpRowMap = {};
|
|
1149
|
+
let tmpKeys = Object.keys(pRefManifest.Descriptors);
|
|
1150
|
+
|
|
1151
|
+
for (let i = 0; i < tmpKeys.length; i++)
|
|
1152
|
+
{
|
|
1153
|
+
let tmpDescriptor = pRefManifest.Descriptors[tmpKeys[i]];
|
|
1154
|
+
let tmpRow = 1;
|
|
1155
|
+
if (tmpDescriptor && tmpDescriptor.PictForm && tmpDescriptor.PictForm.Row)
|
|
1156
|
+
{
|
|
1157
|
+
tmpRow = parseInt(tmpDescriptor.PictForm.Row, 10);
|
|
1158
|
+
if (isNaN(tmpRow) || tmpRow < 1)
|
|
1159
|
+
{
|
|
1160
|
+
tmpRow = 1;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
if (!tmpRowMap[tmpRow])
|
|
1165
|
+
{
|
|
1166
|
+
tmpRowMap[tmpRow] = [];
|
|
1167
|
+
}
|
|
1168
|
+
tmpRowMap[tmpRow].push({ Address: tmpKeys[i], Descriptor: tmpDescriptor });
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
// Sort by row number
|
|
1172
|
+
let tmpRowNumbers = Object.keys(tmpRowMap).map(Number).sort(function(a, b) { return a - b; });
|
|
1173
|
+
for (let i = 0; i < tmpRowNumbers.length; i++)
|
|
1174
|
+
{
|
|
1175
|
+
tmpResult.push({ Row: tmpRowNumbers[i], Columns: tmpRowMap[tmpRowNumbers[i]] });
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
return tmpResult;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
/**
|
|
1182
|
+
* Get the highest PictForm.Row value across all Descriptors in a ReferenceManifest.
|
|
1183
|
+
*
|
|
1184
|
+
* @param {object} pRefManifest
|
|
1185
|
+
* @returns {number}
|
|
1186
|
+
*/
|
|
1187
|
+
_getSubmanifestMaxRow(pRefManifest)
|
|
1188
|
+
{
|
|
1189
|
+
if (!pRefManifest || !pRefManifest.Descriptors || typeof pRefManifest.Descriptors !== 'object')
|
|
1190
|
+
{
|
|
1191
|
+
return 0;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
let tmpMaxRow = 0;
|
|
1195
|
+
let tmpKeys = Object.keys(pRefManifest.Descriptors);
|
|
1196
|
+
|
|
1197
|
+
for (let i = 0; i < tmpKeys.length; i++)
|
|
1198
|
+
{
|
|
1199
|
+
let tmpDescriptor = pRefManifest.Descriptors[tmpKeys[i]];
|
|
1200
|
+
if (tmpDescriptor && tmpDescriptor.PictForm && tmpDescriptor.PictForm.Row)
|
|
1201
|
+
{
|
|
1202
|
+
let tmpRow = parseInt(tmpDescriptor.PictForm.Row, 10);
|
|
1203
|
+
if (!isNaN(tmpRow) && tmpRow > tmpMaxRow)
|
|
1204
|
+
{
|
|
1205
|
+
tmpMaxRow = tmpRow;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
return tmpMaxRow;
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
/**
|
|
1214
|
+
* Add a new row to a RecordSet submanifest by creating a column in the next row.
|
|
1215
|
+
*
|
|
1216
|
+
* @param {number} pSectionIndex
|
|
1217
|
+
* @param {number} pGroupIndex
|
|
1218
|
+
*/
|
|
1219
|
+
addSubmanifestRow(pSectionIndex, pGroupIndex)
|
|
1220
|
+
{
|
|
1221
|
+
let tmpManifest = this._resolveManifestData();
|
|
1222
|
+
if (!tmpManifest || !Array.isArray(tmpManifest.Sections))
|
|
1223
|
+
{
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
let tmpSection = tmpManifest.Sections[pSectionIndex];
|
|
1228
|
+
if (!tmpSection || !Array.isArray(tmpSection.Groups))
|
|
1229
|
+
{
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
let tmpGroup = tmpSection.Groups[pGroupIndex];
|
|
1234
|
+
if (!tmpGroup || !tmpGroup.RecordManifest)
|
|
1235
|
+
{
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
let tmpRefManifest = this._resolveReferenceManifest(tmpGroup.RecordManifest);
|
|
1240
|
+
if (!tmpRefManifest)
|
|
1241
|
+
{
|
|
1242
|
+
return;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
let tmpNextRow = this._getSubmanifestMaxRow(tmpRefManifest) + 1;
|
|
1246
|
+
this.addSubmanifestColumn(pSectionIndex, pGroupIndex, tmpNextRow);
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
/**
|
|
1250
|
+
* Select a submanifest column (Tabular/RecordSet) for the properties panel.
|
|
1251
|
+
*
|
|
1252
|
+
* @param {number} pSectionIndex
|
|
1253
|
+
* @param {number} pGroupIndex
|
|
1254
|
+
* @param {string} pColumnAddress - The Descriptor address key
|
|
1255
|
+
*/
|
|
1256
|
+
selectSubmanifestColumn(pSectionIndex, pGroupIndex, pColumnAddress)
|
|
1257
|
+
{
|
|
1258
|
+
// Clear Record input selection
|
|
1259
|
+
this._ParentFormEditor._SelectedInputIndices = null;
|
|
1260
|
+
// Also select the containing section and group
|
|
1261
|
+
this._ParentFormEditor._SelectedSectionIndex = pSectionIndex;
|
|
1262
|
+
this._ParentFormEditor._SelectedGroupIndices = { SectionIndex: pSectionIndex, GroupIndex: pGroupIndex };
|
|
1263
|
+
|
|
1264
|
+
this._ParentFormEditor._SelectedTabularColumn =
|
|
1265
|
+
{
|
|
1266
|
+
SectionIndex: pSectionIndex,
|
|
1267
|
+
GroupIndex: pGroupIndex,
|
|
1268
|
+
ColumnAddress: pColumnAddress
|
|
1269
|
+
};
|
|
1270
|
+
|
|
1271
|
+
if (this._ParentFormEditor._PropertiesPanelView)
|
|
1272
|
+
{
|
|
1273
|
+
this._ParentFormEditor._PropertiesPanelView.selectTabularColumn(pSectionIndex, pGroupIndex, pColumnAddress);
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
// Auto-switch to properties tab and expand panel
|
|
1277
|
+
this._ParentFormEditor._PanelActiveTab = 'properties';
|
|
1278
|
+
if (this._ParentFormEditor._PanelCollapsed)
|
|
1279
|
+
{
|
|
1280
|
+
this._ParentFormEditor._PanelCollapsed = false;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
this._ParentFormEditor.renderVisualEditor();
|
|
1284
|
+
|
|
1285
|
+
// Align the properties panel with the selected column after layout settles
|
|
1286
|
+
let tmpSelf = this._ParentFormEditor;
|
|
1287
|
+
setTimeout(function () { tmpSelf._UtilitiesProvider._alignPanelToSelection(); }, 0);
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
_resolveManifestData()
|
|
1291
|
+
{
|
|
1292
|
+
let tmpAddress = this._ParentFormEditor.options.ManifestDataAddress;
|
|
1293
|
+
if (!tmpAddress)
|
|
1294
|
+
{
|
|
1295
|
+
return null;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
let tmpSegments = tmpAddress.split('.');
|
|
1299
|
+
let tmpCurrent = this.fable;
|
|
1300
|
+
|
|
1301
|
+
for (let i = 0; i < tmpSegments.length; i++)
|
|
1302
|
+
{
|
|
1303
|
+
if (tmpCurrent && typeof tmpCurrent === 'object' && tmpCurrent.hasOwnProperty(tmpSegments[i]))
|
|
1304
|
+
{
|
|
1305
|
+
tmpCurrent = tmpCurrent[tmpSegments[i]];
|
|
1306
|
+
}
|
|
1307
|
+
else
|
|
1308
|
+
{
|
|
1309
|
+
return null;
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
return tmpCurrent;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
_setManifestData(pData)
|
|
1317
|
+
{
|
|
1318
|
+
let tmpAddress = this._ParentFormEditor.options.ManifestDataAddress;
|
|
1319
|
+
if (!tmpAddress)
|
|
1320
|
+
{
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
let tmpSegments = tmpAddress.split('.');
|
|
1325
|
+
let tmpCurrent = this.fable;
|
|
1326
|
+
|
|
1327
|
+
for (let i = 0; i < tmpSegments.length - 1; i++)
|
|
1328
|
+
{
|
|
1329
|
+
if (!tmpCurrent.hasOwnProperty(tmpSegments[i]) || typeof tmpCurrent[tmpSegments[i]] !== 'object')
|
|
1330
|
+
{
|
|
1331
|
+
tmpCurrent[tmpSegments[i]] = {};
|
|
1332
|
+
}
|
|
1333
|
+
tmpCurrent = tmpCurrent[tmpSegments[i]];
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
tmpCurrent[tmpSegments[tmpSegments.length - 1]] = pData;
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
_createEmptyManifest()
|
|
1340
|
+
{
|
|
1341
|
+
return (
|
|
1342
|
+
{
|
|
1343
|
+
Scope: 'NewForm',
|
|
1344
|
+
Sections: [],
|
|
1345
|
+
Descriptors: {},
|
|
1346
|
+
ReferenceManifests: {},
|
|
1347
|
+
StaticOptionLists: [],
|
|
1348
|
+
PickLists: []
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
/**
|
|
1353
|
+
* Synchronize PictForm.Row indices for all inputs in a group's rows.
|
|
1354
|
+
*
|
|
1355
|
+
* Called after row reorder or removal so each Descriptor's PictForm.Row
|
|
1356
|
+
* value matches the input's actual position (1-based).
|
|
1357
|
+
*
|
|
1358
|
+
* @param {object} pManifest - The manifest data object
|
|
1359
|
+
* @param {object} pGroup - The group whose rows need syncing
|
|
1360
|
+
*/
|
|
1361
|
+
_syncRowIndices(pManifest, pGroup)
|
|
1362
|
+
{
|
|
1363
|
+
if (!pGroup || !Array.isArray(pGroup.Rows) || !pManifest || !pManifest.Descriptors)
|
|
1364
|
+
{
|
|
1365
|
+
return;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
for (let i = 0; i < pGroup.Rows.length; i++)
|
|
1369
|
+
{
|
|
1370
|
+
let tmpRow = pGroup.Rows[i];
|
|
1371
|
+
if (!tmpRow || !Array.isArray(tmpRow.Inputs))
|
|
1372
|
+
{
|
|
1373
|
+
continue;
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
for (let j = 0; j < tmpRow.Inputs.length; j++)
|
|
1377
|
+
{
|
|
1378
|
+
let tmpAddress = tmpRow.Inputs[j];
|
|
1379
|
+
if (typeof tmpAddress === 'string' && pManifest.Descriptors.hasOwnProperty(tmpAddress))
|
|
1380
|
+
{
|
|
1381
|
+
let tmpDescriptor = pManifest.Descriptors[tmpAddress];
|
|
1382
|
+
if (tmpDescriptor && tmpDescriptor.PictForm)
|
|
1383
|
+
{
|
|
1384
|
+
tmpDescriptor.PictForm.Row = i + 1;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
/**
|
|
1392
|
+
* Remove all Descriptor entries for inputs within a group.
|
|
1393
|
+
*
|
|
1394
|
+
* @param {object} pManifest - The manifest data object
|
|
1395
|
+
* @param {object} pGroup - The group being removed
|
|
1396
|
+
*/
|
|
1397
|
+
_removeDescriptorsForGroup(pManifest, pGroup)
|
|
1398
|
+
{
|
|
1399
|
+
if (!pGroup || !Array.isArray(pGroup.Rows) || !pManifest || !pManifest.Descriptors)
|
|
1400
|
+
{
|
|
1401
|
+
return;
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
for (let i = 0; i < pGroup.Rows.length; i++)
|
|
1405
|
+
{
|
|
1406
|
+
let tmpRow = pGroup.Rows[i];
|
|
1407
|
+
if (!tmpRow || !Array.isArray(tmpRow.Inputs))
|
|
1408
|
+
{
|
|
1409
|
+
continue;
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
for (let j = 0; j < tmpRow.Inputs.length; j++)
|
|
1413
|
+
{
|
|
1414
|
+
let tmpAddress = tmpRow.Inputs[j];
|
|
1415
|
+
if (typeof tmpAddress === 'string' && pManifest.Descriptors.hasOwnProperty(tmpAddress))
|
|
1416
|
+
{
|
|
1417
|
+
delete pManifest.Descriptors[tmpAddress];
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
/**
|
|
1424
|
+
* Remove all Descriptor entries for inputs within a section.
|
|
1425
|
+
*
|
|
1426
|
+
* @param {object} pManifest - The manifest data object
|
|
1427
|
+
* @param {object} pSection - The section being removed
|
|
1428
|
+
*/
|
|
1429
|
+
_removeDescriptorsForSection(pManifest, pSection)
|
|
1430
|
+
{
|
|
1431
|
+
if (!pSection || !Array.isArray(pSection.Groups) || !pManifest)
|
|
1432
|
+
{
|
|
1433
|
+
return;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
for (let i = 0; i < pSection.Groups.length; i++)
|
|
1437
|
+
{
|
|
1438
|
+
this._removeDescriptorsForGroup(pManifest, pSection.Groups[i]);
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
module.exports = FormEditorManifestOps;
|