pict-section-form 1.0.158 → 1.0.160

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.
@@ -86,7 +86,8 @@ module.exports.default_configuration.pict_configuration = {
86
86
  "RecipeCounterSurfaceArea = RecipeCounterWidth * RecipeCounterDepth",
87
87
  "RecipeCounterVolume = RecipeCounterSurfaceArea * RecipeVerticalClearance",
88
88
  `InspirationLink = CONCAT("https://www.google.com/search?q=", RecipeName, " recipe")`,
89
- 'cumulativeSummationResult = cumulativeSummation(getvalue("AppData.FruitData.FruityVice"), "nutritions.calories", "SummedCalories")'
89
+ 'cumulativeSummationResult = cumulativeSummation(getvalue("AppData.FruitData.FruityVice"), "nutritions.calories", "SummedCalories")',
90
+ `MAP VAR row FROM FruitData.FruityVice : ColorInputBackgroundTabular("FruitGrid", "FruitGrid", "PercentTotalFat", stepIndex, "#FFCCCC", IF(row.nutritions.percent_total_fat, ">", 0.25, 1, 0))`,
90
91
  ],
91
92
 
92
93
  MetaTemplates:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pict-section-form",
3
- "version": "1.0.158",
3
+ "version": "1.0.160",
4
4
  "description": "Pict dynamic form sections",
5
5
  "main": "source/Pict-Section-Form.js",
6
6
  "directories": {
@@ -34,7 +34,7 @@
34
34
  "browser-env": "^3.3.0",
35
35
  "eslint": "^9.39.1",
36
36
  "jquery": "^3.7.1",
37
- "pict": "^1.0.334",
37
+ "pict": "^1.0.341",
38
38
  "pict-application": "^1.0.29",
39
39
  "pict-service-commandlineutility": "^1.0.16",
40
40
  "quackage": "^1.0.45",
@@ -48,7 +48,7 @@
48
48
  "pict-provider": "^1.0.6",
49
49
  "pict-section-tuigrid": "^1.0.27",
50
50
  "pict-template": "^1.0.13",
51
- "pict-view": "^1.0.63"
51
+ "pict-view": "^1.0.64"
52
52
  },
53
53
  "mocha": {
54
54
  "diff": true,
@@ -51,6 +51,7 @@ module.exports.default_configuration = (
51
51
  "Hash": "PictFormsApp",
52
52
 
53
53
  "MainViewportViewIdentifier": "PictFormMetacontroller",
54
+ "AutoSolveAfterInitialize": false,
54
55
 
55
56
  "pict_configuration":
56
57
  {
@@ -82,6 +82,7 @@ class PictDynamicFormsSolverBehaviors extends libPictProvider
82
82
  this.addSolverFunction(pExpressionParser, 'colorSectionBackground', 'fable.providers.DynamicFormSolverBehaviors.colorSectionBackground', 'Colors a section background with a HTML hex color (e.g. #FF0000 for red).');
83
83
  this.addSolverFunction(pExpressionParser, 'colorGroupBackground', 'fable.providers.DynamicFormSolverBehaviors.colorGroupBackground', 'Colors a group background with a HTML hex color (e.g. #FF0000 for red).');
84
84
  this.addSolverFunction(pExpressionParser, 'colorInputBackground', 'fable.providers.DynamicFormSolverBehaviors.colorInputBackground', 'Colors an input background with a HTML hex color (e.g. #FF0000 for red).');
85
+ this.addSolverFunction(pExpressionParser, 'colorInputBackgroundTabular', 'fable.providers.DynamicFormSolverBehaviors.colorInputBackgroundTabular', 'Colors a tabular input background with a HTML hex color (e.g. #FF0000 for red).');
85
86
 
86
87
  return false;
87
88
  }
@@ -293,7 +294,8 @@ class PictDynamicFormsSolverBehaviors extends libPictProvider
293
294
  return true;
294
295
  }
295
296
 
296
- let tmpInputView = this.pict.views.PictFormMetacontroller.getSectionViewFromHash(pSectionHash)
297
+ /** @type {import('../views/Pict-View-DynamicForm.js')} */
298
+ let tmpInputView = this.pict.views.PictFormMetacontroller.getSectionViewFromHash(pSectionHash);
297
299
 
298
300
  if (!tmpInputView)
299
301
  {
@@ -313,22 +315,89 @@ class PictDynamicFormsSolverBehaviors extends libPictProvider
313
315
 
314
316
  if (tmpElementSet.length < 1)
315
317
  {
316
- this.log.warn(`PictDynamicFormsInformary: colorInput could not find input element with section hash [${pSectionHash}] input [${pInputHash}] selector [${ tmpElementSet[0].id}].`);
318
+ this.log.warn(`PictDynamicFormsInformary: colorInput could not find input element with section hash [${pSectionHash}] input [${pInputHash}] selector [#${tmpInput.Macro.RawHTMLID}].`);
317
319
  return false;
318
320
  }
319
321
 
320
- let tmpElement = tmpElementSet[0];
322
+ return this.colorElementBackground(tmpElementSet, pColor, pCSSSelector);
323
+ }
324
+
325
+ /**
326
+ * Colors an input background or its container with a HTML hex color (e.g. #FF0000 for red).
327
+ * @param {string} pSectionHash - The hash of the section containing the input.
328
+ * @param {string} pGroupHash - The hash of the group containing the input.
329
+ * @param {number} pRowIndex - The index of the row.
330
+ * @param {string} pInputHash - The hash of the input to color.
331
+ * @param {string} pColor - The HTML hex color to apply (e.g. #FF0000 for red).
332
+ * @param {string} pApplyChange - If "0", the change will not be applied.
333
+ * @param {string} [pCSSSelector] - Optional. If provided, the color will be applied to the closest element matching this selector instead of the input itself.
334
+ * @param {string} [pElementIDPrefix] - Optional. The prefix for the tabular element ID. Default is 'TABULAR-DATA-'.
335
+ * @returns {boolean} - Returns true if the color was applied successfully or if the change was skipped for pApplyChange equal to "0", false otherwise.
336
+ */
337
+ colorInputBackgroundTabular(pSectionHash, pGroupHash, pInputHash, pRowIndex, pColor, pApplyChange, pCSSSelector, pElementIDPrefix = 'TABULAR-DATA-')
338
+ {
339
+ if (pApplyChange == "0")
340
+ {
341
+ return true;
342
+ }
343
+
344
+ /** @type {import('../views/Pict-View-DynamicForm.js')} */
345
+ let tmpInputView = this.pict.views.PictFormMetacontroller.getSectionViewFromHash(pSectionHash);
346
+
347
+ if (!tmpInputView)
348
+ {
349
+ this.log.warn(`PictDynamicFormsInformary: colorInputBackgroundTabular could not find input with section hash [${pSectionHash}] group hash [${pGroupHash}] input hash [${pInputHash}].`);
350
+ return false;
351
+ }
352
+
353
+ let tmpInput = tmpInputView.getTabularRecordInputByHash(pGroupHash, pInputHash);
354
+
355
+ if (!tmpInput)
356
+ {
357
+ this.log.warn(`PictDynamicFormsInformary: colorInputBackgroundTabular could not find input with section hash [${pSectionHash}] group hash [${pGroupHash}] input hash [${pInputHash}].`);
358
+ return false;
359
+ }
360
+
361
+ if (!tmpInput.Macro)
362
+ {
363
+ this.log.warn(`PictDynamicFormsInformary: colorInputBackgroundTabular input with section hash [${pSectionHash}] group hash [${pGroupHash}] input hash [${pInputHash}] is missing Macro data.`);
364
+ return false;
365
+ }
366
+
367
+ //FIXME: is this reliable for all input types?
368
+ let tmpElementSet = this.pict.ContentAssignment.getElement(`#${pElementIDPrefix}${tmpInput.Macro.RawHTMLID}-${pRowIndex}`);
369
+
370
+ if (tmpElementSet.length < 1)
371
+ {
372
+ this.log.warn(`PictDynamicFormsInformary: colorInputBackgroundTabular could not find input element with section hash [${pSectionHash}] group hash [${pGroupHash}] input hash [${pInputHash}] row index [${pRowIndex}] selector [#${tmpInput.Macro.RawHTMLID}-${pRowIndex}].`);
373
+ return false;
374
+ }
375
+
376
+ return this.colorElementBackground(tmpElementSet, pColor, pCSSSelector);
377
+ }
378
+
379
+ /**
380
+ * @param {Array<HTMLElement>} pElementSet - The element to color.
381
+ * @param {string} pColor - The HTML hex color to apply (e.g. #FF0000 for red).
382
+ * @param {string} [pCSSSelector] - Optional. If provided, the color will be applied to the closest element matching this selector instead of the input itself.
383
+ *
384
+ * @returns {boolean}
385
+ */
386
+ colorElementBackground(pElementSet, pColor, pCSSSelector)
387
+ {
388
+ /** @type {HTMLElement} */
389
+ let tmpElement = pElementSet[0];
321
390
 
322
391
  // if we passed a class target, find the closest element with that class and apply the color to it
323
392
  // otherwise, just apply it to the input element itself
324
393
  if (pCSSSelector)
325
394
  {
326
395
  // find closest target by class name and if we find it, immediately break out of the loop
327
- for (let i = 0; i < tmpElementSet.length; i++)
396
+ for (let i = 0; i < pElementSet.length; i++)
328
397
  {
329
- const element = tmpElementSet[i];
398
+ const element = pElementSet[i];
330
399
  const closest = element.closest(`${pCSSSelector}`);
331
- if (closest)
400
+ if (closest && closest instanceof HTMLElement)
332
401
  {
333
402
  tmpElement = closest;
334
403
  break;
@@ -78,7 +78,117 @@ class PictDynamicSolver extends libPictProvider
78
78
  this.pict.addProviderSingleton('Pict-Input-Chart', libInputChart.default_configuration, libInputChart);
79
79
  }
80
80
 
81
- runSolver(pSolverExpression)
81
+ logSolveOutcome(pSolveOutcome)
82
+ {
83
+ let tmpSolveOutcome = pSolveOutcome;
84
+ if (typeof(tmpSolveOutcome) !== 'object' || tmpSolveOutcome === null)
85
+ {
86
+ tmpSolveOutcome = this.lastSolveOutcome;
87
+ }
88
+ if (typeof(tmpSolveOutcome) !== 'object' || tmpSolveOutcome === null)
89
+ {
90
+ this.log.error(`DynamicSolver [${this.UUID}]::[${this.Hash}] No solve outcome available to log.`);
91
+ return;
92
+ }
93
+
94
+ let tmpSolversRun = tmpSolveOutcome.SolverResultsMap.ExecutedSolvers.length;
95
+
96
+ this.log.info(`DynamicSolver completed solving ${tmpSolversRun} solvers in ${tmpSolveOutcome.EndTimeStamp - tmpSolveOutcome.StartTimeStamp} ms.`);
97
+
98
+ for (let i = 0; i < tmpSolveOutcome.SolverResultsMap.ExecutedSolvers.length; i++)
99
+ {
100
+ let tmpSolver = tmpSolveOutcome.SolverResultsMap.ExecutedSolvers[i];
101
+ this.log.info(` Solver [${tmpSolver.Hash}] Ordinal ${tmpSolver.Ordinal} executed in ${tmpSolver.EndTimeStamp - tmpSolver.StartTimeStamp}ms solving for [${tmpSolver?.ResultsObject?.PostfixedAssignmentAddress}] expression [${tmpSolver.Expression}]`);
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Prepares the solver results map by ensuring it has the necessary structure.
107
+ *
108
+ * @param {Object} pSolverResultsMap - The solver results map to prepare.
109
+ * @returns {Object} - The prepared solver results map.
110
+ */
111
+ prepareSolverResultsMap(pSolverResultsMap)
112
+ {
113
+ let tmpSolverResultsMap = pSolverResultsMap;
114
+ if (typeof(tmpSolverResultsMap) !== 'object' || tmpSolverResultsMap === null)
115
+ {
116
+ tmpSolverResultsMap = {};
117
+ }
118
+ if (!('ExecutedSolvers' in tmpSolverResultsMap))
119
+ {
120
+ tmpSolverResultsMap.ExecutedSolvers = [];
121
+ }
122
+ if (!('SolverResolutionMap' in tmpSolverResultsMap))
123
+ {
124
+ tmpSolverResultsMap.SolverResolutionMap = {};
125
+ }
126
+ return tmpSolverResultsMap;
127
+ }
128
+
129
+ /**
130
+ * Backfills solver dependencies into the solve outcome.
131
+ *
132
+ * @param {Object} pSolveOutcome - The solve outcome object.
133
+ * @returns {Object} - The updated solve outcome with backfilled dependencies.
134
+ */
135
+ backfillSolverDependencies(pSolveOutcome)
136
+ {
137
+ let tmpSolveOutcome = pSolveOutcome;
138
+
139
+ if (typeof(tmpSolveOutcome) !== 'object' || tmpSolveOutcome === null)
140
+ {
141
+ tmpSolveOutcome = this.lastSolveOutcome;
142
+ }
143
+
144
+ if (typeof(tmpSolveOutcome) !== 'object' || tmpSolveOutcome === null)
145
+ {
146
+ this.log.error(`DynamicSolver [${this.UUID}]::[${this.Hash}] No solve outcome available to backfill solver dependencies.`);
147
+ return;
148
+ }
149
+
150
+ for (let i = 0; i < tmpSolveOutcome.SolverResultsMap.ExecutedSolvers.length; i++)
151
+ {
152
+ let tmpSolver = tmpSolveOutcome.SolverResultsMap.ExecutedSolvers[i];
153
+ if (('ResultsObject' in tmpSolver) && (typeof(tmpSolver.ResultsObject) === 'object') && (tmpSolver.ResultsObject !== null))
154
+ {
155
+ // Now fill any dependencies from the results object
156
+ // If the Postfixed Assignment Address is "Result" it hasn't been set and we will ignore it.
157
+ if (tmpSolver.ResultsObject.PostfixedAssignmentAddress && (tmpSolver.ResultsObject.PostfixedAssignmentAddress != 'Result'))
158
+ {
159
+ if (typeof(tmpSolveOutcome.SolverResultsMap.SolverResolutionMap[tmpSolver.ResultsObject.PostfixedAssignmentAddress]) !== 'object')
160
+ {
161
+ tmpSolveOutcome.SolverResultsMap.SolverResolutionMap[tmpSolver.ResultsObject.PostfixedAssignmentAddress] = {};
162
+ }
163
+ // Go through the postfixed list and pull out any symbols being assigned
164
+ for (let j = 0; j < tmpSolver.ResultsObject.PostfixTokenObjects.length; j++)
165
+ {
166
+ let tmpTokenObject = tmpSolver.ResultsObject.PostfixTokenObjects[j];
167
+ if (tmpTokenObject.Type == 'Token.Symbol')
168
+ {
169
+ if (!(tmpTokenObject.Token in tmpSolveOutcome.SolverResultsMap.SolverResolutionMap[tmpSolver.ResultsObject.PostfixedAssignmentAddress]))
170
+ {
171
+ tmpSolveOutcome.SolverResultsMap.SolverResolutionMap[tmpSolver.ResultsObject.PostfixedAssignmentAddress][tmpTokenObject.Token] = 0;
172
+ }
173
+ tmpSolveOutcome.SolverResultsMap.SolverResolutionMap[tmpSolver.ResultsObject.PostfixedAssignmentAddress][tmpTokenObject.Token] = tmpSolveOutcome.SolverResultsMap.SolverResolutionMap[tmpSolver.ResultsObject.PostfixedAssignmentAddress][tmpTokenObject.Token] + 1;
174
+ }
175
+ }
176
+ }
177
+
178
+ }
179
+ }
180
+
181
+ return tmpSolveOutcome;
182
+ }
183
+
184
+ /**
185
+ * Runs a manual solver expression against the dynamic view marshal destination or the application data.
186
+ *
187
+ * @param {string} pSolverExpression - The solver expression to run.
188
+ * @param {boolean} [pSilent=false] - Whether to suppress debug logging output.
189
+ * @returns {any} - The result of the solver expression.
190
+ */
191
+ runSolver(pSolverExpression, pSilent = false)
82
192
  {
83
193
  let tmpViewMarshalDestinationObject = this.pict.resolveStateFromAddress(this.pict.views.PictFormMetacontroller.viewMarshalDestination);
84
194
 
@@ -95,7 +205,10 @@ class PictDynamicSolver extends libPictProvider
95
205
  delete tmpResultsObject.fable;
96
206
  }
97
207
 
98
- this.pict.log.trace(`Manual solve executed for expression: ${pSolverExpression}`, tmpResultsObject);
208
+ if (!pSilent)
209
+ {
210
+ this.pict.log.trace(`Manual solve executed for expression: ${pSolverExpression}`, tmpResultsObject);
211
+ }
99
212
 
100
213
  return tmpSolutionValue;
101
214
  }
@@ -147,11 +260,13 @@ class PictDynamicSolver extends libPictProvider
147
260
  *
148
261
  * @param {array} pGroupSolverArray - An array of Solvers from the groups to solve.
149
262
  * @param {number} pOrdinal - The ordinal value to filter to. Optional.
263
+ * @param {Object} pSolverResultsMap - The solver results map.
150
264
  */
151
- executeGroupSolvers(pGroupSolverArray, pOrdinal)
265
+ executeGroupSolvers(pGroupSolverArray, pOrdinal, pSolverResultsMap)
152
266
  {
153
267
  // This is purely for readability of the code below ... uglify optimizes it out.
154
268
  let tmpFiltered = (typeof(pOrdinal) === 'undefined') ? false : true;
269
+ let tmpSolverReultsMap = this.prepareSolverResultsMap(pSolverResultsMap);
155
270
 
156
271
  // Solve the group RecordSet solvers first
157
272
  for (let j = 0; j < pGroupSolverArray.length; j++)
@@ -201,6 +316,7 @@ class PictDynamicSolver extends libPictProvider
201
316
  }
202
317
  }
203
318
  }
319
+ tmpSolverReultsMap.ExecutedSolvers.push(tmpSolver);
204
320
  tmpSolver.EndTimeStamp = Date.now();
205
321
  }
206
322
  }
@@ -210,10 +326,12 @@ class PictDynamicSolver extends libPictProvider
210
326
  *
211
327
  * @param {Array} pViewSectionSolverArray - The array of view section solvers.
212
328
  * @param {number} pOrdinal - The ordinal value.
329
+ * @param {Object} pSolverResultsMap - The solver results map.
213
330
  */
214
- executeSectionSolvers(pViewSectionSolverArray, pOrdinal)
331
+ executeSectionSolvers(pViewSectionSolverArray, pOrdinal, pSolverResultsMap)
215
332
  {
216
333
  let tmpFiltered = (typeof(pOrdinal) === 'undefined') ? false : true;
334
+ let tmpSolverReultsMap = this.prepareSolverResultsMap(pSolverResultsMap);
217
335
 
218
336
  for (let i = 0; i < pViewSectionSolverArray.length; i++)
219
337
  {
@@ -234,11 +352,11 @@ class PictDynamicSolver extends libPictProvider
234
352
  }
235
353
  tmpSolver.ResultsObject = {};
236
354
  let tmpSolutionValue = tmpView.fable.ExpressionParser.solve(tmpSolver.Expression, tmpView.getMarshalDestinationObject(), tmpSolver.ResultsObject, this.pict.manifest, tmpView.getMarshalDestinationObject());
237
- //let tmpSolutionValue = tmpView.fable.ExpressionParser.solve(tmpSolver.Expression, tmpView.getMarshalDestinationObject(), tmpSolver.ResultsObject, tmpView.sectionManifest, tmpView.getMarshalDestinationObject());
238
355
  if (this.pict.LogNoisiness > 1)
239
356
  {
240
357
  tmpView.log.trace(`[${tmpSolver.Expression}] result was ${tmpSolutionValue}`);
241
358
  }
359
+ tmpSolverReultsMap.ExecutedSolvers.push(tmpSolver);
242
360
  tmpSolver.EndTimeStamp = +new Date();
243
361
  }
244
362
  }
@@ -248,10 +366,12 @@ class PictDynamicSolver extends libPictProvider
248
366
  *
249
367
  * @param {Array} pViewSolverArray - The array of view solvers to execute.
250
368
  * @param {number} pOrdinal - The ordinal value.
369
+ * @param {Object} pSolverResultsMap - The solver results map.
251
370
  */
252
- executeViewSolvers(pViewSolverArray, pOrdinal)
371
+ executeViewSolvers(pViewSolverArray, pOrdinal, pSolverResultsMap)
253
372
  {
254
373
  let tmpFiltered = (typeof(pOrdinal) === 'undefined') ? false : true;
374
+ let tmpSolverReultsMap = this.prepareSolverResultsMap(pSolverResultsMap);
255
375
 
256
376
  for (let i = 0; i < pViewSolverArray.length; i++)
257
377
  {
@@ -269,6 +389,7 @@ class PictDynamicSolver extends libPictProvider
269
389
  }
270
390
  // Solve with the normal view solve() pipeline
271
391
  tmpView.solve();
392
+ tmpSolverReultsMap.ExecutedSolvers.push(tmpSolver);
272
393
  tmpSolver.EndTimeStamp = +new Date();
273
394
  }
274
395
  }
@@ -319,6 +440,7 @@ class PictDynamicSolver extends libPictProvider
319
440
  let tmpViewHashes = Array.isArray(pViewHashes) ? pViewHashes : Object.keys(this.fable.views);
320
441
 
321
442
  let tmpSolveOutcome = {};
443
+ tmpSolveOutcome.SolverResultsMap = {};
322
444
  tmpSolveOutcome.StartTimeStamp = +new Date();
323
445
  tmpSolveOutcome.ViewHashes = tmpViewHashes;
324
446
 
@@ -387,9 +509,9 @@ class PictDynamicSolver extends libPictProvider
387
509
  this.log.trace(`DynamicSolver [${this.UUID}]::[${this.Hash}] Solving ordinal ${tmpOrdinalKeys[i]}`);
388
510
  }
389
511
  let tmpOrdinalContainer = tmpOrdinalsToSolve[tmpOrdinalKeys[i]];
390
- this.executeGroupSolvers(tmpOrdinalContainer.GroupSolvers, Number(tmpOrdinalKeys[i]));
391
- this.executeSectionSolvers(tmpOrdinalContainer.SectionSolvers, Number(tmpOrdinalKeys[i]));
392
- this.executeViewSolvers(tmpOrdinalContainer.ViewSolvers, Number(tmpOrdinalKeys[i]));
512
+ this.executeGroupSolvers(tmpOrdinalContainer.GroupSolvers, Number(tmpOrdinalKeys[i]), tmpSolveOutcome.SolverResultsMap);
513
+ this.executeSectionSolvers(tmpOrdinalContainer.SectionSolvers, Number(tmpOrdinalKeys[i]), tmpSolveOutcome.SolverResultsMap);
514
+ this.executeViewSolvers(tmpOrdinalContainer.ViewSolvers, Number(tmpOrdinalKeys[i]), tmpSolveOutcome.SolverResultsMap);
393
515
  }
394
516
 
395
517
  // Now regenerate the metalists .. after the solve has happened.
@@ -78,7 +78,7 @@ class DynamicTabularData extends libPictProvider
78
78
 
79
79
  if (!tmpGroup)
80
80
  {
81
- this.log.warn(`PICT View Metatemplate Helper getTabularRowData ${pGroupIndex} was not a valid group.`);
81
+ this.log.warn(`PICT View Metatemplate Helper getTabularRecordInput ${pGroupIndex} was not a valid group.`);
82
82
  return false;
83
83
  }
84
84
 
@@ -88,6 +88,45 @@ class DynamicTabularData extends libPictProvider
88
88
  return tmpGroup.supportingManifest.elementDescriptors[tmpSupportingManifestHash];
89
89
  }
90
90
 
91
+ /**
92
+ * Retrieves the tabular record input from the specified view, group, and input indexes.
93
+ *
94
+ * @param {Object} pView - The view object.
95
+ * @param {number} pGroupHash - The index of the group.
96
+ * @param {number} pInputHash - The index of the input.
97
+ * @returns {ElementDescriptor|boolean} The tabular record input or false if the group is invalid.
98
+ */
99
+ getTabularRecordInputByHash(pView, pGroupHash, pInputHash)
100
+ {
101
+ // The neat thing about how the tabular groups work is that we can make it clever about whether it's an object or an array.
102
+ let tmpGroup = pView.getGroups().find((pGroup) => pGroup.Hash === pGroupHash);
103
+
104
+ if (!tmpGroup)
105
+ {
106
+ this.log.warn(`PICT View Metatemplate Helper getTabularRecordInputByHash ${pGroupHash} was not a valid group.`);
107
+ return false;
108
+ }
109
+
110
+ if (!tmpGroup.supportingManifest)
111
+ {
112
+ this.log.warn(`PICT View Metatemplate Helper getTabularRecordInputByHash ${pGroupHash} s not a tabular group.`);
113
+ return false;
114
+ }
115
+
116
+ // Now get the supporting manifest and the input element
117
+ // This needs more guards
118
+ for (const tmpDescriptor of Object.values(tmpGroup.supportingManifest.elementDescriptors))
119
+ {
120
+ if (tmpDescriptor.Hash === pInputHash)
121
+ {
122
+ return tmpDescriptor;
123
+ }
124
+ }
125
+
126
+ this.log.warn(`PICT View Metatemplate Helper getTabularRecordInputByHash ${pGroupHash} could not find input ${pInputHash}.`);
127
+ return false;
128
+ }
129
+
91
130
  /**
92
131
  * Retrieves tabular record data based on the provided parameters.
93
132
  *
@@ -103,7 +142,7 @@ class DynamicTabularData extends libPictProvider
103
142
 
104
143
  if (!tmpGroup)
105
144
  {
106
- this.log.warn(`PICT View Metatemplate Helper getTabularRowData ${pGroupIndex} was not a valid group.`);
145
+ this.log.warn(`PICT View Metatemplate Helper getTabularRecordData ${pGroupIndex} was not a valid group.`);
107
146
  return false;
108
147
  }
109
148
 
@@ -118,7 +157,7 @@ class DynamicTabularData extends libPictProvider
118
157
 
119
158
  if (!tmpRowSourceRecord)
120
159
  {
121
- this.log.warn(`PICT View Metatemplate Helper getTabularRowData ${pGroupIndex} could not find the record set for ${tmpGroup.RecordSetAddress}.`);
160
+ this.log.warn(`PICT View Metatemplate Helper getTabularRecordData ${pGroupIndex} could not find the record set for ${tmpGroup.RecordSetAddress}.`);
122
161
  return false;
123
162
  }
124
163
 
@@ -135,13 +174,13 @@ class DynamicTabularData extends libPictProvider
135
174
  }
136
175
  else
137
176
  {
138
- this.log.warn(`PICT View Metatemplate Helper getTabularRowData ${pGroupIndex} could not determine the type of the record set for ${tmpGroup.RecordSetAddress}.`);
177
+ this.log.warn(`PICT View Metatemplate Helper getTabularRecordData ${pGroupIndex} could not determine the type of the record set for ${tmpGroup.RecordSetAddress}.`);
139
178
  return false;
140
179
  }
141
180
  }
142
181
  catch (pError)
143
182
  {
144
- this.log.error(`PICT View Metatemplate Helper getTabularRowData ${pGroupIndex} encountered an error: ${pError}`);
183
+ this.log.error(`PICT View Metatemplate Helper getTabularRecordData ${pGroupIndex} encountered an error: ${pError}`);
145
184
  return false;
146
185
  }
147
186
  }
@@ -380,7 +380,7 @@ class CustomInputHandler extends libPictSectionInputExtension
380
380
  break;
381
381
  }
382
382
 
383
- let tmpSolvedConfiguration = this.pict.providers.DynamicSolver.runSolver(tmpSolverExpression);
383
+ let tmpSolvedConfiguration = this.pict.providers.DynamicSolver.runSolver(tmpSolverExpression, true);
384
384
 
385
385
  if (tmpParsingConfiguration.ObjectType === 'array')
386
386
  {
@@ -466,7 +466,7 @@ class CustomInputHandler extends libPictSectionInputExtension
466
466
 
467
467
  let tmpSolverLabel = tmpCurrentSolverExpression.Label;
468
468
  let tmpSolverExpression = tmpCurrentSolverExpression.DataSolver;
469
- let tmpSolvedDataSet = this.pict.providers.DynamicSolver.runSolver(tmpSolverExpression);
469
+ let tmpSolvedDataSet = this.pict.providers.DynamicSolver.runSolver(tmpSolverExpression, true);
470
470
 
471
471
  let tmpDataObject = (
472
472
  {
@@ -91,7 +91,7 @@ class CustomInputHandler extends libPictSectionInputExtension
91
91
  */
92
92
  onDataMarshalToFormTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID)
93
93
  {
94
- this.pict.ContentAssignment.assignContent('PRECISE-' + this.getTabularInputHTMLID(pInput.Macro.RawHTMLID, pRowIndex), pValue);
94
+ this.pict.ContentAssignment.assignContent('#PRECISE-' + this.getTabularInputHTMLID(pInput.Macro.RawHTMLID, pRowIndex).substring(1), pValue);
95
95
  this.pict.ContentAssignment.assignContent(this.getTabularInputHTMLID(pInput.Macro.RawHTMLID, pRowIndex), this.roundValue(pInput, pValue));
96
96
  return super.onDataMarshalToFormTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID);
97
97
  }
@@ -875,7 +875,7 @@ class ManifestFactory extends libFableServiceProviderBase
875
875
  {
876
876
  tmpDescriptorManifest.setValueAtAddress(tmpDescriptor, tmpAddress, tmpValue);
877
877
  }
878
- else
878
+ else if (tmpRawValue)
879
879
  {
880
880
  this.log.warn(`Could not parse Boolean value [${tmpRawValue}] for Descriptor Boolean Extension [${tmpKey}] on descriptor [${tmpDescriptor.Hash}]`);
881
881
  }
@@ -1369,6 +1369,21 @@ class PictViewDynamicForm extends libPictViewClass
1369
1369
  return this.pict.providers.DynamicTabularData.getTabularRecordInput(this, pGroupIndex, pInputIndex);
1370
1370
  }
1371
1371
 
1372
+ /**
1373
+ * Get the input object for a specific tabular record group and index.
1374
+ *
1375
+ * Input objects are not distinct among rows.
1376
+ *
1377
+ * @param {string} pGroupHash - The hash of the group.
1378
+ * @param {string} pInputHash - The hash of the input.
1379
+ *
1380
+ * @return {Object} The input object.
1381
+ */
1382
+ getTabularRecordInputByHash(pGroupHash, pInputHash)
1383
+ {
1384
+ return this.pict.providers.DynamicTabularData.getTabularRecordInputByHash(this, pGroupHash, pInputHash);
1385
+ }
1386
+
1372
1387
  /**
1373
1388
  * Get the tabular record object for a particular row in a group.
1374
1389
  *
@@ -178,9 +178,9 @@ class PictFormMetacontroller extends libPictViewClass
178
178
  return super.onSolve();
179
179
  }
180
180
 
181
- runSolver(pExpression)
181
+ runSolver(pExpression, pSilent)
182
182
  {
183
- this.pict.providers.DynamicSolver.runSolver(pExpression);
183
+ this.pict.providers.DynamicSolver.runSolver(pExpression, pSilent);
184
184
  }
185
185
 
186
186
  onBeforeFilterViews(pViewFilterState)
@@ -938,6 +938,9 @@ suite
938
938
  }
939
939
  _Pict.log.info('Loading the Application and associated views.');
940
940
  });
941
+
942
+ // This needs to be explicitly called now that we turned off auto solve
943
+ _Pict.PictApplication.solve();
941
944
  }
942
945
  );
943
946
  }