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,32 @@
1
+ # Getting Started
2
+
3
+ The Form Editor is a visual tool for building and editing pict-section-form configuration manifests. A manifest describes the structure of a form: its sections, groups, inputs, data types, and solver expressions.
4
+
5
+ ## The Editor Layout
6
+
7
+ The editor is divided into two main areas:
8
+
9
+ - **Visual Editor** (left) -- The main canvas where you build your form by adding sections, groups, and inputs. You can click on any element to select it and edit its properties.
10
+ - **Properties Panel** (right) -- A collapsible panel with tabs for editing the selected element. Switch between Form, Section, Group, Input, Options, and Help tabs.
11
+
12
+ ## Building a Form
13
+
14
+ 1. **Add a Section** -- Click the "Add Section" button in the visual editor toolbar. Every form needs at least one section.
15
+ 2. **Add a Group** -- Within a section, click "Add Group" to create an input group. Groups organize related inputs together.
16
+ 3. **Add Inputs** -- Inside a group, click "Add Input" to create form fields. Each input has a name, data type, and input type.
17
+ 4. **Configure Properties** -- Click on any section, group, or input to select it. Its properties will appear in the Properties Panel on the right.
18
+
19
+ ## Tabs
20
+
21
+ The main editor has several tabs across the top:
22
+
23
+ - **Visual** -- The drag-and-drop form builder
24
+ - **Solver Editor** -- Edit solver expressions for computed fields
25
+ - **Solvers** -- View all solver expressions at a glance
26
+ - **JSON** -- View and edit the raw manifest JSON
27
+
28
+ ## Next Steps
29
+
30
+ - Learn about [Sections](Sections.md) to understand form structure
31
+ - Explore [Solvers](Solvers.md) to add computed values
32
+ - Return to the [Table of Contents](ToC.md) for all topics
@@ -0,0 +1,52 @@
1
+ # Groups
2
+
3
+ Groups organize related inputs within a section. Each section contains one or more groups, and each group contains rows of inputs.
4
+
5
+ ## Creating a Group
6
+
7
+ Click the **Add Group** button inside a section in the visual editor. A new group is created with an auto-generated hash based on the section (e.g. "S1_G2") and a default Record layout.
8
+
9
+ ## Group Properties
10
+
11
+ Select a group by clicking its icon in the visual editor or choosing it from the Group tab's searchable dropdown in the properties panel. The following properties are available:
12
+
13
+ - **Name** -- The display label for the group (e.g. "Contact Details"). Click the name in the visual editor to edit it inline.
14
+ - **Hash** -- A unique identifier (e.g. "S1_G1"). Click the hash in the visual editor to edit it inline.
15
+ - **Layout** -- The group's layout strategy. Click the layout label in the visual editor to change it via a dropdown, or use the Group tab in the properties panel.
16
+ - **CSSClass** -- A CSS class name for styling the group container.
17
+
18
+ ## Layout Types
19
+
20
+ Groups support three layout modes:
21
+
22
+ ### Record
23
+
24
+ The default layout. Each row in the group displays a single record's worth of inputs side by side. This is the standard layout for most forms.
25
+
26
+ ### Tabular
27
+
28
+ A multi-column grid layout for displaying data in a table format. Tabular groups have additional properties:
29
+
30
+ - **RecordSetAddress** -- The AppData path to the data array (e.g. `FruitData.FruityVice`).
31
+ - **RecordManifest** -- A reference to an external manifest that defines the columns.
32
+ - **RecordSetSolvers** -- Solver expressions that apply to each record in the set.
33
+
34
+ The properties panel shows a summary of the referenced manifest, including column count and data types.
35
+
36
+ ### RecordSet
37
+
38
+ A multi-row layout for displaying and editing sets of records. Similar to Tabular, it uses a sub-manifest to define the structure of each record. RecordSet groups share the same additional properties as Tabular groups.
39
+
40
+ ## Reordering Groups
41
+
42
+ Use the arrow buttons on the group header in the visual editor to move groups up or down within their section. When drag-and-drop is enabled, groups can be dragged within a section or across sections.
43
+
44
+ ## Deleting a Group
45
+
46
+ Click the delete button on the group header. This removes the group, its rows, and all contained inputs.
47
+
48
+ ## Next Steps
49
+
50
+ - Learn about [Inputs & Data Types](Inputs.md) to add fields to your groups
51
+ - Return to [Sections](Sections.md) for the broader form structure
52
+ - Return to the [Table of Contents](ToC.md)
@@ -0,0 +1,98 @@
1
+ # Inputs & Data Types
2
+
3
+ Inputs are the individual form fields that users interact with. Each input has a data type that defines what kind of value it stores and an input type that controls how it is rendered.
4
+
5
+ ## Creating an Input
6
+
7
+ Click the **Add Input** button inside a row in the visual editor. A new input is created with a default String data type and no input type. You can also add rows to a group using the **Add Row** button, which creates a new horizontal row that can hold multiple inputs side by side.
8
+
9
+ ## Input Properties
10
+
11
+ Select an input by clicking it in the visual editor. Its properties appear in the Input tab of the properties panel:
12
+
13
+ - **Name** -- The display label shown to the user (e.g. "Email Address").
14
+ - **Hash** -- A unique identifier for this input within the manifest.
15
+ - **Address** -- The data path that binds this input to a value in AppData (e.g. `UserProfile.Email`). Changing the address re-keys the input in the manifest. A confirmation step prevents accidental changes.
16
+ - **DataType** -- The underlying data type for this field (see Data Types below).
17
+ - **InputType** -- The rendering and interaction style (see Input Types below). Click the InputType button to open a searchable picker.
18
+ - **Width** -- Grid width from 1 to 12 columns for responsive layout.
19
+
20
+ ## Data Types
21
+
22
+ Each input stores a value with one of the following data types:
23
+
24
+ - **String** -- Text values (the default)
25
+ - **Number** -- Numeric values
26
+ - **Float** -- Floating-point numbers
27
+ - **Integer** -- Whole numbers
28
+ - **PreciseNumber** -- High-precision decimal values
29
+ - **Boolean** -- True or false
30
+ - **Binary** -- Binary data
31
+ - **DateTime** -- Date and time values
32
+ - **Array** -- Ordered lists of values
33
+ - **Object** -- Key-value data structures
34
+ - **Null** -- Null/empty value
35
+
36
+ Change the data type from the Input tab dropdown or by clicking the data type label directly in the visual editor.
37
+
38
+ ## Input Types
39
+
40
+ Input types control how a field is rendered and how the user interacts with it. They are organized into categories:
41
+
42
+ ### Text & Content
43
+
44
+ - **TextArea** -- Multi-line text input
45
+ - **Markdown** -- Markdown-formatted text editor
46
+ - **HTML** -- Rich HTML content block
47
+
48
+ ### Selection
49
+
50
+ - **Option** -- Dropdown select from a set of choices. Has additional properties:
51
+ - *Select Options* -- A JSON array of `{id, text}` option objects
52
+ - *Pick List Name* -- A named dynamic pick list from AppData
53
+ - **Boolean** -- Checkbox or toggle for true/false values
54
+ - **Color** -- Color picker input
55
+
56
+ ### Display
57
+
58
+ - **Display Only** -- Read-only display of the value with no input control
59
+ - **Read Only** -- Input-styled read-only field
60
+ - **Precise Number (Read Only)** -- Formatted number display with additional properties:
61
+ - *Decimal Precision* -- Number of decimal places
62
+ - *Add Commas* -- Thousand-separator formatting
63
+ - *Prefix* -- String prepended to the value (e.g. "$")
64
+ - *Postfix* -- String appended to the value (e.g. " USD")
65
+ - **Hidden** -- Hidden input, not visible to the user
66
+ - **Chart** -- Data visualization with additional properties:
67
+ - *Chart Type* -- The chart style (bar, line, pie, doughnut, radar, polarArea)
68
+ - *Labels Address* -- AppData path for chart labels
69
+ - *Labels Solver* -- Solver expression for chart labels
70
+ - *Datasets Address* -- AppData path for chart datasets
71
+ - **Link** -- Clickable hyperlink display
72
+
73
+ ### Navigation
74
+
75
+ - **Tab Section Selector** -- Controls which sections display as tabs. Properties:
76
+ - *Section Set* -- JSON array of section hashes to show as tabs
77
+ - *Default Tab* -- Hash of the initially selected tab
78
+ - *Default From Data* -- Use the data value to pick the default
79
+ - **Tab Group Selector** -- Controls which groups display as tabs. Same properties as above but for groups.
80
+
81
+ ### Advanced
82
+
83
+ - **Templated** -- Custom template-driven rendering. The *Template* property holds the template string.
84
+ - **Templated Entity Lookup** -- Template-driven entity search and selection with a *Template* property.
85
+
86
+ When an InputType has additional properties, they appear in a dedicated section of the Input tab after the standard fields.
87
+
88
+ ## Reordering and Moving Inputs
89
+
90
+ - Use the left and right arrow buttons in the properties panel to move an input within its row.
91
+ - Rows can be moved up or down using arrow buttons on the row header.
92
+ - When drag-and-drop is enabled, inputs can be dragged within rows or across rows, and rows can be dragged within groups or across groups.
93
+
94
+ ## Next Steps
95
+
96
+ - Learn about [Solvers](Solvers.md) to add computed values
97
+ - Manage option lists for selection inputs in the Options tab (see [Getting Started](Getting-Started.md))
98
+ - Return to the [Table of Contents](ToC.md)
@@ -0,0 +1,36 @@
1
+ # Sections
2
+
3
+ Sections are the top-level building blocks of a form. Every form has at least one section, and each section contains one or more groups of inputs.
4
+
5
+ ## Creating a Section
6
+
7
+ Click the **Add Section** button in the visual editor toolbar. A new section is created with an auto-generated name and hash (e.g. "Section 2" with hash "S2"). The new section includes one empty group by default.
8
+
9
+ ## Section Properties
10
+
11
+ Select a section by clicking its header in the visual editor or choosing it from the Section tab in the properties panel. The following properties are available:
12
+
13
+ - **Name** -- The display label for the section (e.g. "Personal Information"). Click the name in the visual editor to edit it inline.
14
+ - **Hash** -- A unique identifier used in the manifest data structure (e.g. "S1", "PersonalInfo"). Click the hash in the visual editor to edit it inline.
15
+ - **Description** -- A multi-line description of the section's purpose.
16
+ - **CSSClass** -- A CSS class name applied to the section container for custom styling.
17
+ - **CustomCSS** -- Raw CSS rules scoped to the section (e.g. `h3 { color: red; }`).
18
+
19
+ ## Reordering Sections
20
+
21
+ Sections can be moved up or down using the arrow buttons on the section header in the visual editor. When drag-and-drop is enabled, you can also drag sections to reorder them.
22
+
23
+ ## Deleting a Section
24
+
25
+ Click the delete button on the section header. This removes the section and all of its groups, rows, and inputs.
26
+
27
+ ## Section Solvers
28
+
29
+ Each section can have solver expressions attached to it. These are evaluated when the form renders and can compute values, show/hide elements, or set defaults. Solvers are managed from the section properties in the properties panel, where you can add, edit, reorder, and remove them.
30
+
31
+ See [Solvers](Solvers.md) for details on how solver expressions work.
32
+
33
+ ## Next Steps
34
+
35
+ - Learn about [Groups](Groups.md) to organize inputs within sections
36
+ - Return to the [Table of Contents](ToC.md)
@@ -0,0 +1,44 @@
1
+ # Keyboard Shortcuts
2
+
3
+ The form editor supports keyboard shortcuts for common editing tasks. These work in the visual editor and properties panel.
4
+
5
+ ## Inline Editing
6
+
7
+ When editing a name, hash, or layout value inline in the visual editor:
8
+
9
+ - **Enter** -- Confirm the edit and save the value
10
+ - **Escape** -- Cancel the edit and revert to the original value
11
+
12
+ ## Input Type Picker
13
+
14
+ When the input type picker is open:
15
+
16
+ - **Escape** -- Close the picker without making a selection
17
+ - Type in the search box to filter input types by name
18
+
19
+ ## Searchable Selectors
20
+
21
+ The Group tab and other searchable dropdowns support keyboard navigation:
22
+
23
+ - **Escape** -- Close the dropdown
24
+ - Type to filter the list of items
25
+
26
+ ## Solver Editor
27
+
28
+ When working in the solver code editor:
29
+
30
+ - The code editor supports standard text editing shortcuts (select all, copy, paste, undo, redo)
31
+ - Click **Insert** next to any input in the reference list to paste its address at the cursor
32
+
33
+ ## General Tips
34
+
35
+ - Click any editable label in the visual editor to begin inline editing
36
+ - Click a section, group, or input to select it and show its properties
37
+ - Use the properties panel tabs to switch between Form, Section, Group, Input, Options, and Help views
38
+ - The tab bar shows a menu button when there are more tabs than can fit; click it to see hidden tabs
39
+
40
+ ## Next Steps
41
+
42
+ - Learn about [Solvers](Solvers.md) for computed values
43
+ - Review [Getting Started](Getting-Started.md) for an overview
44
+ - Return to the [Table of Contents](ToC.md)
@@ -0,0 +1,176 @@
1
+ # Solver Expression Walkthrough
2
+
3
+ This guide walks through the basics of writing solver expressions step by step. By the end, you will understand how to create computed values, reference form inputs, and use functions.
4
+
5
+ ## What is a Solver Expression?
6
+
7
+ A solver expression is a formula that the form engine evaluates at runtime. It can compute values, look up data, compare conditions, and assign results to form fields. Expressions are attached to sections (or to Tabular/RecordSet groups) and run automatically when the form renders or when data changes.
8
+
9
+ ## Your First Expression
10
+
11
+ The simplest expression assigns a constant value:
12
+
13
+ ```
14
+ DefaultRate = 0.05
15
+ ```
16
+
17
+ This creates a variable called `DefaultRate` with the value `0.05`. The left side of the `=` is the assignment target and the right side is the value.
18
+
19
+ ## Referencing Inputs
20
+
21
+ Solver expressions can reference any input in the form by its hash. If your form has inputs with hashes `Price` and `Quantity`, you can compute a total:
22
+
23
+ ```
24
+ Total = Price * Quantity
25
+ ```
26
+
27
+ When the form renders, the solver reads the current values of `Price` and `Quantity`, multiplies them, and writes the result to `Total`. If `Total` is also an input in the form, it will display the computed value.
28
+
29
+ ## Arithmetic Operators
30
+
31
+ Expressions support standard arithmetic with the following operators, listed from highest to lowest precedence:
32
+
33
+ | Operator | Description | Example |
34
+ |----------|-------------|---------|
35
+ | `^` | Exponentiation | `2 ^ 3` gives `8` |
36
+ | `*` | Multiplication | `5 * 3` gives `15` |
37
+ | `/` | Division | `15 / 3` gives `5` |
38
+ | `%` | Modulus | `7 % 3` gives `1` |
39
+ | `+` | Addition | `5 + 3` gives `8` |
40
+ | `-` | Subtraction | `5 - 3` gives `2` |
41
+
42
+ Parentheses override precedence:
43
+
44
+ ```
45
+ Result = (Price + Tax) * Quantity
46
+ ```
47
+
48
+ ## Using Functions
49
+
50
+ Functions are called by name with arguments in parentheses. For example, to round a result to two decimal places:
51
+
52
+ ```
53
+ RoundedTotal = round(Price * Quantity, 2)
54
+ ```
55
+
56
+ Functions are case-insensitive. `ROUND`, `Round`, and `round` all work the same way.
57
+
58
+ See [Solver Functions](Solver-Functions.md) for the complete list of available functions.
59
+
60
+ ## String Values
61
+
62
+ Use double quotes for string literals:
63
+
64
+ ```
65
+ Status = if(Total, ">", 1000, "High Value", "Standard")
66
+ ```
67
+
68
+ String values can contain special characters. Use `,` for commas inside function arguments (since commas normally separate arguments):
69
+
70
+ ```
71
+ Label = join(", ", FirstName, LastName)
72
+ ```
73
+
74
+ The `resolvehtmlentities` function can convert HTML entities to their actual characters when needed.
75
+
76
+ ## Conditional Logic
77
+
78
+ ### The if Function
79
+
80
+ The `if` function compares two values and returns one of two results:
81
+
82
+ ```
83
+ if(left, operator, right, trueValue, falseValue)
84
+ ```
85
+
86
+ Operators include `<`, `>`, `<=`, `>=`, `==` (loose equality), and `===` (strict equality). You can also use `LT`, `GT`, `LTE`, `GTE` as aliases.
87
+
88
+ ```
89
+ Discount = if(Total, ">=", 100, Total * 0.1, 0)
90
+ ```
91
+
92
+ Nested conditions handle multiple outcomes:
93
+
94
+ ```
95
+ Grade = if(Score, ">=", 90, "A", if(Score, ">=", 80, "B", if(Score, ">=", 70, "C", "F")))
96
+ ```
97
+
98
+ ### The when Function
99
+
100
+ The `when` function is a simpler check for whether a value is truthy (exists and is not empty):
101
+
102
+ ```
103
+ DisplayName = when(Nickname, Nickname, FullName)
104
+ ```
105
+
106
+ If `Nickname` has a value, use it; otherwise fall back to `FullName`.
107
+
108
+ ## Reading Application State
109
+
110
+ Use `getvalue` to access data from anywhere in the application state:
111
+
112
+ ```
113
+ TaxRate = getvalue("AppData.Settings.TaxRate")
114
+ ```
115
+
116
+ The path must be a quoted string. Array elements use bracket notation:
117
+
118
+ ```
119
+ FirstItem = getvalue("AppData.Cart.Items[0].Name")
120
+ ```
121
+
122
+ ## Aggregate Functions
123
+
124
+ When working with arrays of data, aggregate functions compute summaries:
125
+
126
+ ```
127
+ TotalCost = sum(ItemPrices)
128
+ AverageCost = mean(ItemPrices)
129
+ ItemCount = count(ItemPrices)
130
+ HighestPrice = max(ItemPrices)
131
+ LowestPrice = min(ItemPrices)
132
+ ```
133
+
134
+ These work on arrays. You can use `flatten` to gather values from nested data structures:
135
+
136
+ ```
137
+ AllPopulations = flatten(getvalue("AppData.Cities[].population"))
138
+ TotalPopulation = sum(AllPopulations)
139
+ ```
140
+
141
+ ## Null Coalescence Assignment
142
+
143
+ Use `?=` instead of `=` to only assign a value if the target is currently empty or undefined:
144
+
145
+ ```
146
+ DefaultName ?= "Unnamed"
147
+ ```
148
+
149
+ This sets `DefaultName` to `"Unnamed"` only if it does not already have a value. This is useful for setting initial defaults without overwriting user input.
150
+
151
+ ## Putting It All Together
152
+
153
+ Here is a realistic example that computes a shopping cart summary:
154
+
155
+ ```
156
+ Subtotal = sum(flatten(getvalue("AppData.Cart.Items[].Price")))
157
+ TaxRate = getvalue("AppData.Settings.TaxRate")
158
+ Tax = round(Subtotal * TaxRate, 2)
159
+ Total = Subtotal + Tax
160
+ DiscountApplied = if(Total, ">=", 100, "Yes", "No")
161
+ FinalTotal = if(DiscountApplied, "==", "Yes", round(Total * 0.9, 2), Total)
162
+ ```
163
+
164
+ Each expression references the results of previous ones. The ordinal system (all default to 1 here) ensures they execute in order.
165
+
166
+ ## Execution Order and Ordinals
167
+
168
+ Solvers execute in ordinal order. All solvers with ordinal 1 run first, then ordinal 2, and so on. Within the same ordinal, solvers execute in the order they appear in the manifest.
169
+
170
+ Most solvers use the default ordinal of 1. When you need a solver to run after others have completed, give it a higher ordinal (2, 3, etc.). This is useful when one group of calculations depends on the results of another.
171
+
172
+ ## Next Steps
173
+
174
+ - Read [Solver Expressions Advanced Topics](Solver-Expressions-Advanced.md) for scope rules, set operations, and tabular solvers
175
+ - Browse the [Solver Functions](Solver-Functions.md) reference for the complete function list
176
+ - Return to the [Table of Contents](ToC.md)