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.
Files changed (178) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +118 -0
  3. package/docs/.nojekyll +0 -0
  4. package/docs/README.md +162 -0
  5. package/docs/_sidebar.md +23 -0
  6. package/docs/_topbar.md +5 -0
  7. package/docs/cover.md +12 -0
  8. package/docs/css/docuserve.css +73 -0
  9. package/docs/index.html +39 -0
  10. package/docs/retold-catalog.json +224 -0
  11. package/docs/retold-keyword-index.json +46846 -0
  12. package/example_applications/form_editor/.quackage.json +10 -0
  13. package/example_applications/form_editor/FormEditor-Example-Application.js +226 -0
  14. package/example_applications/form_editor/html/icon-chooser.html +375 -0
  15. package/example_applications/form_editor/html/index.html +54 -0
  16. package/example_applications/form_editor/package.json +50 -0
  17. package/package.json +55 -0
  18. package/sample_manifests/Complex-Table.json +974 -0
  19. package/sample_manifests/Distill-Example.json +200 -0
  20. package/sample_manifests/Gradebook-Assignment.json +38 -0
  21. package/sample_manifests/Gradebook-Student.json +40 -0
  22. package/sample_manifests/Manyfest-Editor.json +347 -0
  23. package/sample_manifests/Simple-Form.json +232 -0
  24. package/sample_manifests/Simple-Table.json +79 -0
  25. package/source/Pict-Section-FormEditor-DefaultConfiguration.js +3321 -0
  26. package/source/Pict-Section-FormEditor.js +35 -0
  27. package/source/providers/Pict-Provider-ChildPictManager-Application.js +40 -0
  28. package/source/providers/Pict-Provider-ChildPictManager.js +238 -0
  29. package/source/providers/Pict-Provider-FormEditorDocumentation.js +356 -0
  30. package/source/providers/Pict-Provider-FormEditorDragDrop.js +535 -0
  31. package/source/providers/Pict-Provider-FormEditorIconography.js +1002 -0
  32. package/source/providers/Pict-Provider-FormEditorManifestOps.js +1443 -0
  33. package/source/providers/Pict-Provider-FormEditorRendering.js +730 -0
  34. package/source/providers/Pict-Provider-FormEditorUtilities.js +862 -0
  35. package/source/providers/Pict-Provider-PreviewCSS.js +42 -0
  36. package/source/views/PictView-FormEditor-InlineEditing.js +309 -0
  37. package/source/views/PictView-FormEditor-InputTypePicker.js +532 -0
  38. package/source/views/PictView-FormEditor-PropertiesPanel.js +7730 -0
  39. package/source/views/PictView-FormEditor.js +681 -0
  40. package/test/Pict-Section-FormEditor_tests.js +4102 -0
  41. package/user-documentation/.pict_documentation_topics.json +695 -0
  42. package/user-documentation/Getting-Started.md +32 -0
  43. package/user-documentation/Groups.md +52 -0
  44. package/user-documentation/Inputs.md +98 -0
  45. package/user-documentation/Sections.md +36 -0
  46. package/user-documentation/Shortcuts.md +44 -0
  47. package/user-documentation/Solver-Expression-Walkthrough.md +176 -0
  48. package/user-documentation/Solver-Expressions-Advanced.md +344 -0
  49. package/user-documentation/Solver-Functions.md +213 -0
  50. package/user-documentation/Solvers.md +81 -0
  51. package/user-documentation/ToC.md +18 -0
  52. package/user-documentation/solverfunctions/abs.md +84 -0
  53. package/user-documentation/solverfunctions/aggregationhistogram.md +83 -0
  54. package/user-documentation/solverfunctions/aggregationhistogrambyobject.md +64 -0
  55. package/user-documentation/solverfunctions/arrayconcat.md +64 -0
  56. package/user-documentation/solverfunctions/avg.md +81 -0
  57. package/user-documentation/solverfunctions/bucketset.md +69 -0
  58. package/user-documentation/solverfunctions/ceil.md +70 -0
  59. package/user-documentation/solverfunctions/cleanvaluearray.md +66 -0
  60. package/user-documentation/solverfunctions/cleanvalueobject.md +68 -0
  61. package/user-documentation/solverfunctions/colorgroupbackground.md +60 -0
  62. package/user-documentation/solverfunctions/colorinputbackground.md +62 -0
  63. package/user-documentation/solverfunctions/colorinputbackgroundtabular.md +64 -0
  64. package/user-documentation/solverfunctions/colorsectionbackground.md +59 -0
  65. package/user-documentation/solverfunctions/compare.md +72 -0
  66. package/user-documentation/solverfunctions/concat.md +73 -0
  67. package/user-documentation/solverfunctions/concatraw.md +73 -0
  68. package/user-documentation/solverfunctions/cos.md +75 -0
  69. package/user-documentation/solverfunctions/count.md +73 -0
  70. package/user-documentation/solverfunctions/countset.md +65 -0
  71. package/user-documentation/solverfunctions/countsetelements.md +63 -0
  72. package/user-documentation/solverfunctions/createarrayfromabsolutevalues.md +63 -0
  73. package/user-documentation/solverfunctions/createvalueobjectbyhashes.md +69 -0
  74. package/user-documentation/solverfunctions/cumulativesummation.md +96 -0
  75. package/user-documentation/solverfunctions/dateadddays.md +79 -0
  76. package/user-documentation/solverfunctions/dateaddhours.md +74 -0
  77. package/user-documentation/solverfunctions/dateaddmilliseconds.md +65 -0
  78. package/user-documentation/solverfunctions/dateaddminutes.md +72 -0
  79. package/user-documentation/solverfunctions/dateaddmonths.md +74 -0
  80. package/user-documentation/solverfunctions/dateaddseconds.md +66 -0
  81. package/user-documentation/solverfunctions/dateaddweeks.md +73 -0
  82. package/user-documentation/solverfunctions/dateaddyears.md +74 -0
  83. package/user-documentation/solverfunctions/datedaydifference.md +84 -0
  84. package/user-documentation/solverfunctions/datefromparts.md +81 -0
  85. package/user-documentation/solverfunctions/datehourdifference.md +64 -0
  86. package/user-documentation/solverfunctions/datemathadd.md +72 -0
  87. package/user-documentation/solverfunctions/datemilliseconddifference.md +64 -0
  88. package/user-documentation/solverfunctions/dateminutedifference.md +64 -0
  89. package/user-documentation/solverfunctions/datemonthdifference.md +66 -0
  90. package/user-documentation/solverfunctions/dateseconddifference.md +64 -0
  91. package/user-documentation/solverfunctions/dateweekdifference.md +65 -0
  92. package/user-documentation/solverfunctions/dateyeardifference.md +64 -0
  93. package/user-documentation/solverfunctions/differencearrays.md +59 -0
  94. package/user-documentation/solverfunctions/disablesolverordinal.md +58 -0
  95. package/user-documentation/solverfunctions/distributionhistogram.md +96 -0
  96. package/user-documentation/solverfunctions/distributionhistogrambyobject.md +64 -0
  97. package/user-documentation/solverfunctions/enablesolverordinal.md +57 -0
  98. package/user-documentation/solverfunctions/entryinset.md +72 -0
  99. package/user-documentation/solverfunctions/euler.md +77 -0
  100. package/user-documentation/solverfunctions/exp.md +74 -0
  101. package/user-documentation/solverfunctions/findfirstvaluebyexactmatch.md +67 -0
  102. package/user-documentation/solverfunctions/findfirstvaluebystringincludes.md +67 -0
  103. package/user-documentation/solverfunctions/flatten.md +76 -0
  104. package/user-documentation/solverfunctions/floor.md +70 -0
  105. package/user-documentation/solverfunctions/gaussianelimination.md +75 -0
  106. package/user-documentation/solverfunctions/generatearrayofobjectsfromsets.md +70 -0
  107. package/user-documentation/solverfunctions/generatehtmlhexcolor.md +67 -0
  108. package/user-documentation/solverfunctions/getvalue.md +90 -0
  109. package/user-documentation/solverfunctions/getvaluearray.md +64 -0
  110. package/user-documentation/solverfunctions/getvalueobject.md +67 -0
  111. package/user-documentation/solverfunctions/hidesections.md +58 -0
  112. package/user-documentation/solverfunctions/if.md +109 -0
  113. package/user-documentation/solverfunctions/iterativeseries.md +107 -0
  114. package/user-documentation/solverfunctions/join.md +75 -0
  115. package/user-documentation/solverfunctions/joinraw.md +64 -0
  116. package/user-documentation/solverfunctions/largestinset.md +63 -0
  117. package/user-documentation/solverfunctions/leastsquares.md +66 -0
  118. package/user-documentation/solverfunctions/linest.md +58 -0
  119. package/user-documentation/solverfunctions/log.md +74 -0
  120. package/user-documentation/solverfunctions/logvalues.md +65 -0
  121. package/user-documentation/solverfunctions/match.md +71 -0
  122. package/user-documentation/solverfunctions/matrixinverse.md +67 -0
  123. package/user-documentation/solverfunctions/matrixmultiply.md +71 -0
  124. package/user-documentation/solverfunctions/matrixtranspose.md +72 -0
  125. package/user-documentation/solverfunctions/matrixvectormultiply.md +69 -0
  126. package/user-documentation/solverfunctions/max.md +73 -0
  127. package/user-documentation/solverfunctions/mean.md +63 -0
  128. package/user-documentation/solverfunctions/median.md +79 -0
  129. package/user-documentation/solverfunctions/min.md +73 -0
  130. package/user-documentation/solverfunctions/mode.md +66 -0
  131. package/user-documentation/solverfunctions/objectkeystoarray.md +66 -0
  132. package/user-documentation/solverfunctions/objectvaluessortbyexternalobjectarray.md +65 -0
  133. package/user-documentation/solverfunctions/objectvaluestoarray.md +67 -0
  134. package/user-documentation/solverfunctions/percent.md +75 -0
  135. package/user-documentation/solverfunctions/pi.md +77 -0
  136. package/user-documentation/solverfunctions/polynomialregression.md +69 -0
  137. package/user-documentation/solverfunctions/predict.md +71 -0
  138. package/user-documentation/solverfunctions/rad.md +85 -0
  139. package/user-documentation/solverfunctions/randomfloat.md +63 -0
  140. package/user-documentation/solverfunctions/randomfloatbetween.md +72 -0
  141. package/user-documentation/solverfunctions/randomfloatupto.md +65 -0
  142. package/user-documentation/solverfunctions/randominteger.md +56 -0
  143. package/user-documentation/solverfunctions/randomintegerbetween.md +72 -0
  144. package/user-documentation/solverfunctions/randomintegerupto.md +64 -0
  145. package/user-documentation/solverfunctions/refreshtabularsection.md +57 -0
  146. package/user-documentation/solverfunctions/resolvehtmlentities.md +64 -0
  147. package/user-documentation/solverfunctions/round.md +111 -0
  148. package/user-documentation/solverfunctions/runsolvers.md +49 -0
  149. package/user-documentation/solverfunctions/setconcatenate.md +64 -0
  150. package/user-documentation/solverfunctions/setgroupvisibility.md +60 -0
  151. package/user-documentation/solverfunctions/setsectionvisibility.md +59 -0
  152. package/user-documentation/solverfunctions/setsolverordinalenabled.md +59 -0
  153. package/user-documentation/solverfunctions/settabularrowlength.md +57 -0
  154. package/user-documentation/solverfunctions/setvalue.md +65 -0
  155. package/user-documentation/solverfunctions/showsections.md +58 -0
  156. package/user-documentation/solverfunctions/sin.md +83 -0
  157. package/user-documentation/solverfunctions/slice.md +80 -0
  158. package/user-documentation/solverfunctions/smallestinset.md +63 -0
  159. package/user-documentation/solverfunctions/sortarray.md +58 -0
  160. package/user-documentation/solverfunctions/sorthistogram.md +70 -0
  161. package/user-documentation/solverfunctions/sorthistogrambykeys.md +69 -0
  162. package/user-documentation/solverfunctions/sortset.md +75 -0
  163. package/user-documentation/solverfunctions/sqrt.md +85 -0
  164. package/user-documentation/solverfunctions/stdev.md +81 -0
  165. package/user-documentation/solverfunctions/stdeva.md +58 -0
  166. package/user-documentation/solverfunctions/stdevp.md +83 -0
  167. package/user-documentation/solverfunctions/stringcountsegments.md +66 -0
  168. package/user-documentation/solverfunctions/stringgetsegments.md +74 -0
  169. package/user-documentation/solverfunctions/subtractingsummation.md +66 -0
  170. package/user-documentation/solverfunctions/sum.md +78 -0
  171. package/user-documentation/solverfunctions/tan.md +78 -0
  172. package/user-documentation/solverfunctions/tofixed.md +75 -0
  173. package/user-documentation/solverfunctions/unionarrays.md +59 -0
  174. package/user-documentation/solverfunctions/uniquearray.md +58 -0
  175. package/user-documentation/solverfunctions/var.md +67 -0
  176. package/user-documentation/solverfunctions/vara.md +58 -0
  177. package/user-documentation/solverfunctions/varp.md +66 -0
  178. package/user-documentation/solverfunctions/when.md +98 -0
@@ -0,0 +1,42 @@
1
+ const libPictProvider = require('pict-provider');
2
+
3
+ /**
4
+ * Provider that prevents the child pict form preview from injecting CSS
5
+ * into the parent form editor's #PICT-CSS style element.
6
+ *
7
+ * The parent pict already loads all necessary pict-section-form styles.
8
+ * The child pict does not need its own CSS injection — it just needs to
9
+ * be told not to touch #PICT-CSS.
10
+ *
11
+ * Usage:
12
+ * After creating the child pict instance, call:
13
+ * previewCSSProvider.disableChildCSSInjection(childPict);
14
+ */
15
+ class PreviewCSSProvider extends libPictProvider
16
+ {
17
+ constructor(pFable, pOptions, pServiceHash)
18
+ {
19
+ super(pFable, pOptions, pServiceHash);
20
+
21
+ this.serviceType = 'PictProvider';
22
+ }
23
+
24
+ /**
25
+ * Disable CSS injection on a child pict instance so its CSSMap
26
+ * does not overwrite the parent's #PICT-CSS element.
27
+ *
28
+ * Replaces the child's injectCSS method with a no-op.
29
+ *
30
+ * @param {Object} pChildPict - The child pict instance
31
+ */
32
+ disableChildCSSInjection(pChildPict)
33
+ {
34
+ if (pChildPict && pChildPict.CSSMap)
35
+ {
36
+ pChildPict.CSSMap.injectCSS = function() {};
37
+ }
38
+ }
39
+ }
40
+
41
+ module.exports = PreviewCSSProvider;
42
+ module.exports.default_configuration = {};
@@ -0,0 +1,309 @@
1
+ const libPictView = require('pict-view');
2
+
3
+ class PictViewFormEditorInlineEditing extends libPictView
4
+ {
5
+ constructor(pFable, pOptions, pServiceHash)
6
+ {
7
+ super(pFable, pOptions, pServiceHash);
8
+ this._ParentFormEditor = null;
9
+ }
10
+
11
+ /**
12
+ * Begin inline editing of a Section or Group property (Name or Hash).
13
+ *
14
+ * @param {string} pType - 'Section' or 'Group'
15
+ * @param {number} pSectionIndex - Index of the section
16
+ * @param {number} pGroupIndex - Index of the group (-1 for section properties)
17
+ * @param {string} pProperty - 'Name' or 'Hash'
18
+ */
19
+ beginEditProperty(pType, pSectionIndex, pGroupIndex, pProperty)
20
+ {
21
+ let tmpHash = this._ParentFormEditor.Hash;
22
+ let tmpViewRef = this._ParentFormEditor._browserViewRef();
23
+
24
+ // Build the element ID that matches what we rendered
25
+ let tmpElementId = '';
26
+ if (pType === 'Section')
27
+ {
28
+ tmpElementId = `FormEditor-Section${pProperty}-${tmpHash}-${pSectionIndex}`;
29
+ }
30
+ else
31
+ {
32
+ tmpElementId = `FormEditor-Group${pProperty}-${tmpHash}-${pSectionIndex}-${pGroupIndex}`;
33
+ }
34
+
35
+ // Get the current value
36
+ let tmpManifest = this._ParentFormEditor._resolveManifestData();
37
+ let tmpCurrentValue = '';
38
+ if (pType === 'Section' && tmpManifest && tmpManifest.Sections && tmpManifest.Sections[pSectionIndex])
39
+ {
40
+ tmpCurrentValue = tmpManifest.Sections[pSectionIndex][pProperty] || '';
41
+ }
42
+ else if (pType === 'Group' && tmpManifest && tmpManifest.Sections && tmpManifest.Sections[pSectionIndex] && tmpManifest.Sections[pSectionIndex].Groups && tmpManifest.Sections[pSectionIndex].Groups[pGroupIndex])
43
+ {
44
+ tmpCurrentValue = tmpManifest.Sections[pSectionIndex].Groups[pGroupIndex][pProperty] || '';
45
+ }
46
+
47
+ // Replace the span with an inline editor
48
+ let tmpEditorHTML = '';
49
+
50
+ if (pProperty === 'Layout')
51
+ {
52
+ // Layout uses a select dropdown
53
+ // onclick stopPropagation prevents the parent span's onclick from re-calling beginEditProperty
54
+ let tmpLayouts = ['Record', 'Tabular', 'RecordSet'];
55
+ let tmpCommitCall = `${tmpViewRef}.commitEditProperty('${pType}', ${pSectionIndex}, ${pGroupIndex}, '${pProperty}')`;
56
+ tmpEditorHTML += `<select class="pict-fe-inline-edit-select" id="${tmpElementId}-Input" onclick="event.stopPropagation()" onchange="${tmpCommitCall}" onblur="setTimeout(function(){${tmpCommitCall}},150)" onkeydown="if(event.key==='Escape'){this.dataset.cancelled='true';this.blur();}">`;
57
+ for (let i = 0; i < tmpLayouts.length; i++)
58
+ {
59
+ let tmpSelected = (tmpLayouts[i] === tmpCurrentValue) ? ' selected' : '';
60
+ tmpEditorHTML += `<option value="${tmpLayouts[i]}"${tmpSelected}>${tmpLayouts[i]}</option>`;
61
+ }
62
+ tmpEditorHTML += '</select>';
63
+ }
64
+ else
65
+ {
66
+ // Name and Hash use a text input
67
+ // onclick stopPropagation prevents the parent span's onclick from re-calling beginEditProperty
68
+ let tmpHashClass = (pProperty === 'Hash') ? ' pict-fe-inline-edit-hash' : '';
69
+ tmpEditorHTML += `<input class="pict-fe-inline-edit-input${tmpHashClass}" id="${tmpElementId}-Input" type="text" value="${this._ParentFormEditor._UtilitiesProvider._escapeAttr(tmpCurrentValue)}" onclick="event.stopPropagation()" onblur="${tmpViewRef}.commitEditProperty('${pType}', ${pSectionIndex}, ${pGroupIndex}, '${pProperty}')" onkeydown="if(event.key==='Enter'){this.blur();}if(event.key==='Escape'){this.dataset.cancelled='true';this.blur();}" />`;
70
+ }
71
+
72
+ this.pict.ContentAssignment.assignContent(`#${tmpElementId}`, tmpEditorHTML);
73
+
74
+ // Focus the editor
75
+ let tmpInputSet = this.pict.ContentAssignment.getElement(`#${tmpElementId}-Input`);
76
+ let tmpInput = (Array.isArray(tmpInputSet) && tmpInputSet.length > 0) ? tmpInputSet[0] : tmpInputSet;
77
+ if (tmpInput && tmpInput.focus)
78
+ {
79
+ tmpInput.focus();
80
+ if (tmpInput.select)
81
+ {
82
+ tmpInput.select();
83
+ }
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Commit the inline edit, updating the property and re-rendering.
89
+ *
90
+ * @param {string} pType - 'Section' or 'Group'
91
+ * @param {number} pSectionIndex - Index of the section
92
+ * @param {number} pGroupIndex - Index of the group (-1 for section properties)
93
+ * @param {string} pProperty - 'Name' or 'Hash'
94
+ */
95
+ commitEditProperty(pType, pSectionIndex, pGroupIndex, pProperty)
96
+ {
97
+ let tmpHash = this._ParentFormEditor.Hash;
98
+
99
+ let tmpElementId = '';
100
+ if (pType === 'Section')
101
+ {
102
+ tmpElementId = `FormEditor-Section${pProperty}-${tmpHash}-${pSectionIndex}`;
103
+ }
104
+ else
105
+ {
106
+ tmpElementId = `FormEditor-Group${pProperty}-${tmpHash}-${pSectionIndex}-${pGroupIndex}`;
107
+ }
108
+
109
+ let tmpInputSet = this.pict.ContentAssignment.getElement(`#${tmpElementId}-Input`);
110
+ let tmpInput = (Array.isArray(tmpInputSet) && tmpInputSet.length > 0) ? tmpInputSet[0] : tmpInputSet;
111
+
112
+ if (!tmpInput || tmpInput.value === undefined)
113
+ {
114
+ // Element already gone from a previous commit; nothing to do
115
+ return;
116
+ }
117
+
118
+ // Guard against double-commit (onchange + onblur on selects)
119
+ if (tmpInput.dataset && tmpInput.dataset.committed === 'true')
120
+ {
121
+ return;
122
+ }
123
+
124
+ // Check if the edit was cancelled via Escape
125
+ if (tmpInput.dataset && tmpInput.dataset.cancelled === 'true')
126
+ {
127
+ this._ParentFormEditor.renderVisualEditor();
128
+ return;
129
+ }
130
+
131
+ // Mark as committed so a second call is a no-op
132
+ if (tmpInput.dataset)
133
+ {
134
+ tmpInput.dataset.committed = 'true';
135
+ }
136
+
137
+ let tmpNewValue = tmpInput.value;
138
+
139
+ if (pType === 'Section')
140
+ {
141
+ // Capture the old hash before updating, so we can detect
142
+ // whether the hash was auto-generated.
143
+ let tmpOldHash = null;
144
+ if (pProperty === 'Name')
145
+ {
146
+ let tmpSection = this._ParentFormEditor._resolveManifestData().Sections[pSectionIndex];
147
+ if (tmpSection)
148
+ {
149
+ tmpOldHash = tmpSection.Hash || '';
150
+ }
151
+ }
152
+
153
+ this._ParentFormEditor._ManifestOpsProvider.updateSectionProperty(pSectionIndex, pProperty, tmpNewValue);
154
+
155
+ // When the user edits the Name, auto-generate the Hash if the
156
+ // current hash still matches the auto-generated format (S{n}).
157
+ // If the user has manually overridden the hash it will no
158
+ // longer match and we leave it alone.
159
+ if (pProperty === 'Name' && tmpOldHash !== null)
160
+ {
161
+ if (this._ParentFormEditor._UtilitiesProvider._isAutoGeneratedSectionHash(tmpOldHash))
162
+ {
163
+ let tmpAutoHash = this._ParentFormEditor._UtilitiesProvider.sanitizeObjectKey(tmpNewValue);
164
+ this._ParentFormEditor._ManifestOpsProvider.updateSectionProperty(pSectionIndex, 'Hash', tmpAutoHash);
165
+ }
166
+ }
167
+ }
168
+ else
169
+ {
170
+ this._ParentFormEditor._ManifestOpsProvider.updateGroupProperty(pSectionIndex, pGroupIndex, pProperty, tmpNewValue);
171
+
172
+ // When the user edits the Name, auto-generate the Hash if it
173
+ // still follows the auto-generated pattern ({SectionHash}_G...).
174
+ if (pProperty === 'Name')
175
+ {
176
+ let tmpManifest = this._ParentFormEditor._resolveManifestData();
177
+ let tmpSection = tmpManifest.Sections[pSectionIndex];
178
+ let tmpGroup = tmpSection && tmpSection.Groups ? tmpSection.Groups[pGroupIndex] : null;
179
+ if (tmpGroup)
180
+ {
181
+ let tmpSectionHash = tmpSection.Hash || '';
182
+ let tmpAutoPrefix = tmpSectionHash + '_G';
183
+ if (tmpGroup.Hash && tmpGroup.Hash.indexOf(tmpAutoPrefix) === 0)
184
+ {
185
+ let tmpAutoHash = tmpAutoPrefix + this._ParentFormEditor._UtilitiesProvider.sanitizeObjectKey(tmpNewValue);
186
+ this._ParentFormEditor._ManifestOpsProvider.updateGroupProperty(pSectionIndex, pGroupIndex, 'Hash', tmpAutoHash);
187
+ }
188
+ }
189
+ }
190
+ }
191
+
192
+ this._ParentFormEditor.renderVisualEditor();
193
+ }
194
+
195
+ /**
196
+ * Begin inline editing of an Input's DataType via a select dropdown.
197
+ *
198
+ * @param {number} pSectionIndex - Index of the section
199
+ * @param {number} pGroupIndex - Index of the group
200
+ * @param {number} pRowIndex - Index of the row
201
+ * @param {number} pInputIndex - Index of the input within the row
202
+ */
203
+ beginEditInputDataType(pSectionIndex, pGroupIndex, pRowIndex, pInputIndex)
204
+ {
205
+ let tmpHash = this._ParentFormEditor.Hash;
206
+ let tmpViewRef = this._ParentFormEditor._browserViewRef();
207
+ let tmpElementId = `FormEditor-InputType-${tmpHash}-${pSectionIndex}-${pGroupIndex}-${pRowIndex}-${pInputIndex}`;
208
+
209
+ // Resolve the current DataType from the Descriptor
210
+ let tmpManifest = this._ParentFormEditor._resolveManifestData();
211
+ let tmpCurrentValue = 'String';
212
+ if (tmpManifest && tmpManifest.Sections)
213
+ {
214
+ let tmpSection = tmpManifest.Sections[pSectionIndex];
215
+ let tmpGroup = tmpSection && tmpSection.Groups ? tmpSection.Groups[pGroupIndex] : null;
216
+ let tmpRow = tmpGroup && tmpGroup.Rows ? tmpGroup.Rows[pRowIndex] : null;
217
+ if (tmpRow && Array.isArray(tmpRow.Inputs))
218
+ {
219
+ let tmpAddress = tmpRow.Inputs[pInputIndex];
220
+ if (typeof tmpAddress === 'string' && tmpManifest.Descriptors && tmpManifest.Descriptors[tmpAddress])
221
+ {
222
+ tmpCurrentValue = tmpManifest.Descriptors[tmpAddress].DataType || 'String';
223
+ }
224
+ }
225
+ }
226
+
227
+ let tmpCommitCall = `${tmpViewRef}.commitEditInputDataType(${pSectionIndex}, ${pGroupIndex}, ${pRowIndex}, ${pInputIndex})`;
228
+ let tmpEditorHTML = `<select class="pict-fe-inline-edit-select" id="${tmpElementId}-Input" onclick="event.stopPropagation()" onchange="${tmpCommitCall}" onblur="setTimeout(function(){${tmpCommitCall}},150)" onkeydown="if(event.key==='Escape'){this.dataset.cancelled='true';this.blur();}">`;
229
+ for (let i = 0; i < this._ParentFormEditor._ManyfestDataTypes.length; i++)
230
+ {
231
+ let tmpSelected = (this._ParentFormEditor._ManyfestDataTypes[i] === tmpCurrentValue) ? ' selected' : '';
232
+ tmpEditorHTML += `<option value="${this._ParentFormEditor._ManyfestDataTypes[i]}"${tmpSelected}>${this._ParentFormEditor._ManyfestDataTypes[i]}</option>`;
233
+ }
234
+ tmpEditorHTML += '</select>';
235
+
236
+ this.pict.ContentAssignment.assignContent(`#${tmpElementId}`, tmpEditorHTML);
237
+
238
+ // Focus the select
239
+ let tmpInputSet = this.pict.ContentAssignment.getElement(`#${tmpElementId}-Input`);
240
+ let tmpInput = (Array.isArray(tmpInputSet) && tmpInputSet.length > 0) ? tmpInputSet[0] : tmpInputSet;
241
+ if (tmpInput && tmpInput.focus)
242
+ {
243
+ tmpInput.focus();
244
+ }
245
+ }
246
+
247
+ /**
248
+ * Commit the inline DataType edit, updating the Descriptor and re-rendering.
249
+ *
250
+ * @param {number} pSectionIndex - Index of the section
251
+ * @param {number} pGroupIndex - Index of the group
252
+ * @param {number} pRowIndex - Index of the row
253
+ * @param {number} pInputIndex - Index of the input within the row
254
+ */
255
+ commitEditInputDataType(pSectionIndex, pGroupIndex, pRowIndex, pInputIndex)
256
+ {
257
+ let tmpHash = this._ParentFormEditor.Hash;
258
+ let tmpElementId = `FormEditor-InputType-${tmpHash}-${pSectionIndex}-${pGroupIndex}-${pRowIndex}-${pInputIndex}`;
259
+
260
+ let tmpInputSet = this.pict.ContentAssignment.getElement(`#${tmpElementId}-Input`);
261
+ let tmpInput = (Array.isArray(tmpInputSet) && tmpInputSet.length > 0) ? tmpInputSet[0] : tmpInputSet;
262
+
263
+ if (!tmpInput || tmpInput.value === undefined)
264
+ {
265
+ return;
266
+ }
267
+
268
+ // Guard against double-commit
269
+ if (tmpInput.dataset && tmpInput.dataset.committed === 'true')
270
+ {
271
+ return;
272
+ }
273
+
274
+ // Check if cancelled via Escape
275
+ if (tmpInput.dataset && tmpInput.dataset.cancelled === 'true')
276
+ {
277
+ this._ParentFormEditor.renderVisualEditor();
278
+ return;
279
+ }
280
+
281
+ if (tmpInput.dataset)
282
+ {
283
+ tmpInput.dataset.committed = 'true';
284
+ }
285
+
286
+ let tmpNewValue = tmpInput.value;
287
+
288
+ // Update the Descriptor's DataType
289
+ let tmpManifest = this._ParentFormEditor._resolveManifestData();
290
+ if (tmpManifest && tmpManifest.Sections)
291
+ {
292
+ let tmpSection = tmpManifest.Sections[pSectionIndex];
293
+ let tmpGroup = tmpSection && tmpSection.Groups ? tmpSection.Groups[pGroupIndex] : null;
294
+ let tmpRow = tmpGroup && tmpGroup.Rows ? tmpGroup.Rows[pRowIndex] : null;
295
+ if (tmpRow && Array.isArray(tmpRow.Inputs))
296
+ {
297
+ let tmpAddress = tmpRow.Inputs[pInputIndex];
298
+ if (typeof tmpAddress === 'string' && tmpManifest.Descriptors && tmpManifest.Descriptors[tmpAddress])
299
+ {
300
+ tmpManifest.Descriptors[tmpAddress].DataType = tmpNewValue;
301
+ }
302
+ }
303
+ }
304
+
305
+ this._ParentFormEditor.renderVisualEditor();
306
+ }
307
+ }
308
+
309
+ module.exports = PictViewFormEditorInlineEditing;