pict-section-form 1.0.169 → 1.0.171

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 (34) hide show
  1. package/example_applications/postcard_example/providers/PictProvider-BestPostcardTheme.js +1 -1
  2. package/example_applications/postcard_example/providers/PictProvider-Dynamic-Sections.js +0 -1
  3. package/example_applications/simple_distill/Simple-Form-Application.js +26 -3
  4. package/package.json +3 -3
  5. package/source/providers/Pict-Provider-DynamicFormSolverBehaviors.js +6 -0
  6. package/source/providers/Pict-Provider-DynamicInputEvents.js +0 -3
  7. package/source/providers/Pict-Provider-DynamicSolver.js +146 -8
  8. package/source/providers/Pict-Provider-MetatemplateGenerator.js +0 -1
  9. package/source/providers/dynamictemplates/Pict-DynamicTemplates-DefaultFormTemplates.js +20 -0
  10. package/source/providers/inputs/Pict-Provider-Input-AutofillTriggerGroup.js +32 -0
  11. package/source/providers/inputs/Pict-Provider-Input-EntityBundleRequest.js +20 -42
  12. package/source/providers/inputs/Pict-Provider-Input-Templated.js +255 -0
  13. package/source/providers/inputs/Pict-Provider-Input-TemplatedEntityLookup.js +62 -19
  14. package/source/services/ManifestFactory.js +105 -0
  15. package/source/views/Pict-View-DynamicForm.js +1 -6
  16. package/source/views/Pict-View-Form-Metacontroller.js +0 -2
  17. package/types/source/providers/Pict-Provider-DynamicFormSolverBehaviors.d.ts +1 -0
  18. package/types/source/providers/Pict-Provider-DynamicFormSolverBehaviors.d.ts.map +1 -1
  19. package/types/source/providers/Pict-Provider-DynamicInputEvents.d.ts.map +1 -1
  20. package/types/source/providers/Pict-Provider-DynamicSolver.d.ts +39 -3
  21. package/types/source/providers/Pict-Provider-DynamicSolver.d.ts.map +1 -1
  22. package/types/source/providers/Pict-Provider-MetatemplateGenerator.d.ts.map +1 -1
  23. package/types/source/providers/inputs/Pict-Provider-Input-AutofillTriggerGroup.d.ts.map +1 -1
  24. package/types/source/providers/inputs/Pict-Provider-Input-EntityBundleRequest.d.ts +0 -38
  25. package/types/source/providers/inputs/Pict-Provider-Input-EntityBundleRequest.d.ts.map +1 -1
  26. package/types/source/providers/inputs/Pict-Provider-Input-Templated.d.ts +131 -0
  27. package/types/source/providers/inputs/Pict-Provider-Input-Templated.d.ts.map +1 -0
  28. package/types/source/providers/inputs/Pict-Provider-Input-TemplatedEntityLookup.d.ts +0 -26
  29. package/types/source/providers/inputs/Pict-Provider-Input-TemplatedEntityLookup.d.ts.map +1 -1
  30. package/types/source/services/ManifestFactory.d.ts +1 -0
  31. package/types/source/services/ManifestFactory.d.ts.map +1 -1
  32. package/types/source/views/Pict-View-DynamicForm.d.ts +1 -1
  33. package/types/source/views/Pict-View-DynamicForm.d.ts.map +1 -1
  34. package/types/source/views/Pict-View-Form-Metacontroller.d.ts.map +1 -1
@@ -94,7 +94,7 @@ Glug glug CUSTOMIZED glug Oo... -->
94
94
  "Template": /*HTML*/`
95
95
  <div class="pure-u-1 pure-u-md-1-3">
96
96
  <label {~D:Record.Macro.HTMLForID~}>{~D:Record.Name~}:</label>
97
- <input type="number" {~D:Record.Macro.HTMLID~} {~D:Record.Macro.InputFullProperties~} class="pure-u-23-24" />
97
+ <input type="number" {~D:Record.Macro.HTMLID~} {~D:Record.Macro.InputFullProperties~} {~D:Record.Macro.InputChangeHandler~} class="pure-u-23-24" />
98
98
  </div>
99
99
  `
100
100
  },
@@ -25,7 +25,6 @@ class PostcardDynamicSectionProvider extends libPictProvider
25
25
  "Name": "Custom Dynamic Inputs",
26
26
  "ViewHash": "MyDynamicView",
27
27
 
28
- "AutoMarshalDataOnSolve": true,
29
28
  "IncludeInMetatemplateSectionGeneration": false,
30
29
 
31
30
  "Manifests": {
@@ -59,6 +59,7 @@ module.exports.default_configuration.pict_configuration = (
59
59
 
60
60
  "Solvers":
61
61
  [
62
+ 'runSolvers()'
62
63
  ],
63
64
  "MetaTemplates":
64
65
  [
@@ -109,7 +110,25 @@ module.exports.default_configuration.pict_configuration = (
109
110
  "Destination": "AppData.AuthorSchema"
110
111
  }
111
112
  ],
112
- EntityBundleTriggerGroup: "BookTriggerGroup"
113
+ EntityBundleTriggerGroup: "BookTriggerGroup",
114
+ EntityBundleTriggerOnInitialize: true
115
+ }
116
+ },
117
+ "TemplatedInput": {
118
+ Name: "Templated Input",
119
+ Hash: "TemplatedInput",
120
+ DataType: "String",
121
+ PictForm:
122
+ {
123
+ InputType: 'Templated',
124
+ Section: "Book", Group: "Author", Row: 2,
125
+ TriggerGroupHash: "BookTriggerGroup",
126
+ Template: "<div>{~T:AuthorInfo~}</div><div>{~TS:BookInfo:AppData.Books~}</div>",
127
+ Templates:
128
+ {
129
+ "AuthorInfo": "{~D:AppData.CurrentAuthor.IDAuthor~} :: {~D:AppData.CurrentAuthor.Name~}",
130
+ "BookInfo": "<div><img src=\"{~D:Record.ImageURL~}\" />{~D:Record.IDBook~} :: {~D:Record.Title~}</div>"
131
+ }
113
132
  }
114
133
  },
115
134
  "Author.Name": {
@@ -124,7 +143,9 @@ module.exports.default_configuration.pict_configuration = (
124
143
  {
125
144
  TriggerGroupHash: "BookTriggerGroup",
126
145
  TriggerAddress: "AppData.CurrentAuthor.Name",
127
- MarshalEmptyValues: true
146
+ MarshalEmptyValues: true,
147
+ PreSolvers: [ 'NumBooks = getvalue("AppData.BookAuthorJoins.length")' ],
148
+ PostSolvers: [ 'runSolvers()' ],
128
149
  }
129
150
  }
130
151
  },
@@ -168,6 +189,8 @@ module.exports.default_configuration.pict_configuration = (
168
189
  {
169
190
  Template: "Record GUIDBookAuthorJoin {~D:AppData.CurrentBookAuthorJoinForDisplayTemplate.GUIDBookAuthorJoin~} IDBook {~D:AppData.CurrentBookAuthorJoinForDisplayTemplate.IDBook~} is the first book for IDAuthor {~D:AppData.CurrentAuthor.IDAuthor~} AuthorName [{~D:AppData.CurrentAuthor.Name~}]",
170
191
 
192
+ TriggerGroupHash: "BookTriggerGroup",
193
+
171
194
  EmptyValueTestList: ["AppData.CurrentBookAuthorJoinForDisplayTemplate"],
172
195
  EmptyValueTemplate: "No BookAuthorJoin Found",
173
196
 
@@ -181,7 +204,7 @@ module.exports.default_configuration.pict_configuration = (
181
204
  }]
182
205
  }
183
206
  }
184
- }
207
+ },
185
208
  }
186
209
  }
187
210
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pict-section-form",
3
- "version": "1.0.169",
3
+ "version": "1.0.171",
4
4
  "description": "Pict dynamic form sections",
5
5
  "main": "source/Pict-Section-Form.js",
6
6
  "directories": {
@@ -34,8 +34,8 @@
34
34
  "browser-env": "^3.3.0",
35
35
  "eslint": "^9.39.1",
36
36
  "jquery": "^3.7.1",
37
- "pict": "^1.0.342",
38
- "pict-application": "^1.0.29",
37
+ "pict": "^1.0.343",
38
+ "pict-application": "^1.0.30",
39
39
  "pict-service-commandlineutility": "^1.0.16",
40
40
  "quackage": "^1.0.45",
41
41
  "tui-grid": "^4.21.22",
@@ -72,6 +72,11 @@ class PictDynamicFormsSolverBehaviors extends libPictProvider
72
72
  });
73
73
  }
74
74
 
75
+ runSolvers()
76
+ {
77
+ return this.pict.providers.DynamicSolver.solveViews(undefined, true);
78
+ }
79
+
75
80
  injectBehaviors(pExpressionParser)
76
81
  {
77
82
  // Wire up the solver functions.
@@ -92,6 +97,7 @@ class PictDynamicFormsSolverBehaviors extends libPictProvider
92
97
  this.addSolverFunction(pExpressionParser, 'disablesolverordinall', 'fable.providers.DynamicFormSolverBehaviors.disableSolverOrdinal', 'Disables a solver ordinal so that it will not run.');
93
98
 
94
99
  this.addSolverFunction(pExpressionParser, 'settabularrowlength', 'fable.providers.DynamicFormSolverBehaviors.setTabularRowLength', 'Sets the length of a tabular data set.');
100
+ this.addSolverFunction(pExpressionParser, 'runsolvers', 'fable.providers.DynamicFormSolverBehaviors.runSolvers', 'Solves all views.');
95
101
 
96
102
  return false;
97
103
  }
@@ -217,9 +217,6 @@ class PictDynamicInputEvents extends libPictProvider
217
217
  // pView is what is called whenever a hash is changed. We could marshal from view, solve and remarshal to view.
218
218
  pView.marshalFromView();
219
219
  }
220
- // Run any dynamic input providers for the input hash.
221
- pView.pict.PictApplication.solve();
222
- pView.marshalToView();
223
220
  }
224
221
 
225
222
  /**
@@ -13,6 +13,7 @@ const libInputEntityBundleRequest = require('./inputs/Pict-Provider-Input-Entity
13
13
  const libInputAutofillTriggerGroup = require('./inputs/Pict-Provider-Input-AutofillTriggerGroup.js');
14
14
  const libInputMarkdown = require('./inputs/Pict-Provider-Input-Markdown.js');
15
15
  const libInputHTML = require('./inputs/Pict-Provider-Input-HTML.js');
16
+ const libInputTemplated = require('./inputs/Pict-Provider-Input-Templated.js');
16
17
  const libInputPreciseNumber = require('./inputs/Pict-Provider-Input-PreciseNumber.js');
17
18
  const libInputLink = require('./inputs/Pict-Provider-Input-Link.js');
18
19
  const libInputTemplatedEntityLookup = require('./inputs/Pict-Provider-Input-TemplatedEntityLookup.js');
@@ -57,10 +58,11 @@ class PictDynamicSolver extends libPictProvider
57
58
  /** @type {string} */
58
59
  this.Hash;
59
60
 
61
+ this._RunSolversRegex = /\brunsolvers\b/gi;
62
+
60
63
  // Initialize the solver service if it isn't up
61
64
  this.fable.instantiateServiceProviderIfNotExists('ExpressionParser');
62
65
 
63
-
64
66
  this.pict.addProviderSingleton('DynamicFormSolverBehaviors', libDynamicFormSolverBehaviors.default_configuration, libDynamicFormSolverBehaviors);
65
67
  this.pict.providers.DynamicFormSolverBehaviors.injectBehaviors(this.fable.ExpressionParser);
66
68
  this.pict.addProviderSingleton('DynamicMetaLists', libDynamicMetaLists.default_configuration, libDynamicMetaLists);
@@ -73,6 +75,7 @@ class PictDynamicSolver extends libPictProvider
73
75
  this.pict.addProviderSingleton('Pict-Input-AutofillTriggerGroup', libInputAutofillTriggerGroup.default_configuration, libInputAutofillTriggerGroup);
74
76
  this.pict.addProviderSingleton('Pict-Input-Markdown', libInputMarkdown.default_configuration, libInputMarkdown);
75
77
  this.pict.addProviderSingleton('Pict-Input-HTML', libInputHTML.default_configuration, libInputHTML);
78
+ this.pict.addProviderSingleton('Pict-Input-Templated', libInputTemplated.default_configuration, libInputTemplated);
76
79
  this.pict.addProviderSingleton('Pict-Input-PreciseNumber', libInputPreciseNumber.default_configuration, libInputPreciseNumber);
77
80
  this.pict.addProviderSingleton('Pict-Input-TemplatedEntityLookup', libInputTemplatedEntityLookup.default_configuration, libInputTemplatedEntityLookup);
78
81
  this.pict.addProviderSingleton('Pict-Input-Link', libInputLink.default_configuration, libInputLink);
@@ -175,7 +178,6 @@ class PictDynamicSolver extends libPictProvider
175
178
  }
176
179
  }
177
180
  }
178
-
179
181
  }
180
182
  }
181
183
 
@@ -254,6 +256,119 @@ class PictDynamicSolver extends libPictProvider
254
256
  return tmpSolver;
255
257
  }
256
258
 
259
+ /** @typedef {{ Ordinal: number, Expression: string } | string} Solver */
260
+
261
+ /**
262
+ * Execute a set of adhoc solvers.
263
+ *
264
+ * @param {import('../views/Pict-View-DynamicForm.js')} pView - The dynamic view to execute the solvers against.
265
+ * @param {Array<Solver>} pSolvers - An array of solvers to execute.
266
+ * @param {string} pReason - The reason for executing the solvers.
267
+ */
268
+ executeSolvers(pView, pSolvers, pReason)
269
+ {
270
+ const tmpSolvers = Array.isArray(pSolvers) ? pSolvers : [];
271
+ let tmpSolveOutcome = {};
272
+ tmpSolveOutcome.SolverResultsMap = {};
273
+ tmpSolveOutcome.StartTimeStamp = +new Date();
274
+
275
+ let tmpOrdinalsToSolve = {};
276
+ tmpSolveOutcome.SolveOrdinals = tmpOrdinalsToSolve;
277
+ for (let i = 0; i < tmpSolvers.length; i++)
278
+ {
279
+ const tmpSolver = this.checkSolver(tmpSolvers[i]);
280
+ if (tmpSolver)
281
+ {
282
+ let tmpOrdinalContainer = this.checkAutoSolveOrdinal(tmpSolver.Ordinal, tmpOrdinalsToSolve);
283
+ tmpOrdinalContainer.AdhocSolvers.push(tmpSolver);
284
+ }
285
+ }
286
+
287
+ // Now sort the ordinal container keys
288
+ let tmpOrdinalKeys = Object.keys(tmpOrdinalsToSolve);
289
+ tmpOrdinalKeys.sort((a, b) =>
290
+ {
291
+ if (isNaN(Number(a)) || isNaN(Number(b)))
292
+ {
293
+ return a.localeCompare(b);
294
+ }
295
+ return Number(a) - Number(b);
296
+ });
297
+
298
+ // Now enumerate the keys and solve each layer of the solution set
299
+ for (let i = 0; i < tmpOrdinalKeys.length; i++)
300
+ {
301
+ if (this.pict.LogNoisiness > 1)
302
+ {
303
+ this.log.trace(`DynamicSolver [${this.UUID}]::[${this.Hash}] [${pReason}] Solving ordinal ${tmpOrdinalKeys[i]}`);
304
+ }
305
+ let tmpOrdinalContainer = tmpOrdinalsToSolve[tmpOrdinalKeys[i]];
306
+ let tmpExecuteOrdinal = this.pict.providers.DynamicFormSolverBehaviors.checkSolverOrdinalEnabled(tmpOrdinalKeys[i]);
307
+ if (tmpExecuteOrdinal)
308
+ {
309
+ this.executeAdhocSolvers(pView, tmpOrdinalContainer.AdhocSolvers, pReason, Number(tmpOrdinalKeys[i]), tmpSolveOutcome.SolverResultsMap);
310
+ }
311
+ }
312
+
313
+ tmpSolveOutcome.EndTimeStamp = +new Date();
314
+
315
+ // It's up to the developer to decide if they want to use this information somewhere.
316
+ this.lastAdhocSolveOutcome = tmpSolveOutcome;
317
+ }
318
+
319
+ /**
320
+ * Runs each Adhoc solver formulae for a dynamic view group at a given ordinal.
321
+ *
322
+ * Or for all ordinals if no ordinal is passed.
323
+ *
324
+ * @param {import('../views/Pict-View-DynamicForm.js')} pView - The dynamic view to execute the solvers against.
325
+ * @param {Array<string>} pAdhocSolverArray - An array of Solvers from the groups to solve.
326
+ * @param {string} pReason - The reason for executing the solvers.
327
+ * @param {number} pOrdinal - The ordinal value to filter to. Optional.
328
+ * @param {Object} pSolverResultsMap - The solver results map.
329
+ * @param {boolean} [pPreventSolverCycles=false] - Whether to prevent solver cycles.
330
+ */
331
+ executeAdhocSolvers(pView, pAdhocSolverArray, pReason, pOrdinal, pSolverResultsMap, pPreventSolverCycles = false)
332
+ {
333
+ let tmpFiltered = (typeof(pOrdinal) === 'undefined') ? false : true;
334
+ let tmpSolverReultsMap = this.prepareSolverResultsMap(pSolverResultsMap);
335
+
336
+ for (let i = 0; i < pAdhocSolverArray.length; i++)
337
+ {
338
+ let tmpSolver = this.checkSolver(pAdhocSolverArray[i], tmpFiltered, pOrdinal);
339
+ if (typeof(tmpSolver) === 'undefined')
340
+ {
341
+ continue;
342
+ }
343
+
344
+ if (pPreventSolverCycles && tmpSolver.Expression.match(this._RunSolversRegex))
345
+ {
346
+ if (this.pict.LogNoisiness > 0)
347
+ {
348
+ pView.log.warn(`Dynamic View [${pView.UUID}]::[${pView.Hash}] [${pReason}] skipping RecordSet ordinal ${tmpSolver.Ordinal} [${tmpSolver.Expression}] due to solver cycle prevention.`);
349
+ }
350
+ continue;
351
+ }
352
+
353
+ tmpSolver.StartTimeStamp = +new Date();
354
+ tmpSolver.Hash = `AdhocSolver-${i}`;
355
+
356
+ // TODO: Precompile the solvers (it's super easy)
357
+ if (this.pict.LogNoisiness > 1)
358
+ {
359
+ this.pict.log.trace(`Dynamic View [${pView.UUID}]::[${pView.Hash}] [${pReason}] solving equation ${i} ordinal ${tmpSolver.Ordinal} [${pView.options.Solvers[i]}]`);
360
+ }
361
+ tmpSolver.ResultsObject = {};
362
+ let tmpSolutionValue = this.fable.ExpressionParser.solve(tmpSolver.Expression, pView.getMarshalDestinationObject(), tmpSolver.ResultsObject, this.pict.manifest, pView.getMarshalDestinationObject());
363
+ if (this.pict.LogNoisiness > 1)
364
+ {
365
+ this.pict.log.trace(`[${tmpSolver.Expression}] [${pReason}] result was ${tmpSolutionValue}`);
366
+ }
367
+ tmpSolverReultsMap.ExecutedSolvers.push(tmpSolver);
368
+ tmpSolver.EndTimeStamp = +new Date();
369
+ }
370
+ }
371
+
257
372
  /**
258
373
  * Runs each RecordSet solver formulae for a dynamic view group at a given ordinal.
259
374
  *
@@ -262,8 +377,9 @@ class PictDynamicSolver extends libPictProvider
262
377
  * @param {array} pGroupSolverArray - An array of Solvers from the groups to solve.
263
378
  * @param {number} pOrdinal - The ordinal value to filter to. Optional.
264
379
  * @param {Object} pSolverResultsMap - The solver results map.
380
+ * @param {boolean} [pPreventSolverCycles=false] - Whether to prevent solver cycles.
265
381
  */
266
- executeGroupSolvers(pGroupSolverArray, pOrdinal, pSolverResultsMap)
382
+ executeGroupSolvers(pGroupSolverArray, pOrdinal, pSolverResultsMap, pPreventSolverCycles = false)
267
383
  {
268
384
  // This is purely for readability of the code below ... uglify optimizes it out.
269
385
  let tmpFiltered = (typeof(pOrdinal) === 'undefined') ? false : true;
@@ -280,6 +396,15 @@ class PictDynamicSolver extends libPictProvider
280
396
  continue;
281
397
  }
282
398
 
399
+ if (pPreventSolverCycles && tmpSolver.Expression.match(this._RunSolversRegex))
400
+ {
401
+ if (this.pict.LogNoisiness > 0)
402
+ {
403
+ tmpView.log.warn(`Dynamic View [${tmpView.UUID}]::[${tmpView.Hash}] skipping RecordSet ordinal ${tmpSolver.Ordinal} [${tmpSolver.Expression}] due to solver cycle prevention.`);
404
+ }
405
+ continue;
406
+ }
407
+
283
408
  tmpSolver.StartTimeStamp = Date.now();
284
409
  tmpSolver.Hash = `${pGroupSolverArray[j].ViewHash}-GroupSolver-${j}`;
285
410
 
@@ -328,8 +453,9 @@ class PictDynamicSolver extends libPictProvider
328
453
  * @param {Array} pViewSectionSolverArray - The array of view section solvers.
329
454
  * @param {number} pOrdinal - The ordinal value.
330
455
  * @param {Object} pSolverResultsMap - The solver results map.
456
+ * @param {boolean} [pPreventSolverCycles=false] - Whether to prevent solver cycles.
331
457
  */
332
- executeSectionSolvers(pViewSectionSolverArray, pOrdinal, pSolverResultsMap)
458
+ executeSectionSolvers(pViewSectionSolverArray, pOrdinal, pSolverResultsMap, pPreventSolverCycles = false)
333
459
  {
334
460
  let tmpFiltered = (typeof(pOrdinal) === 'undefined') ? false : true;
335
461
  let tmpSolverReultsMap = this.prepareSolverResultsMap(pSolverResultsMap);
@@ -343,6 +469,15 @@ class PictDynamicSolver extends libPictProvider
343
469
  continue;
344
470
  }
345
471
 
472
+ if (pPreventSolverCycles && tmpSolver.Expression.match(this._RunSolversRegex))
473
+ {
474
+ if (this.pict.LogNoisiness > 0)
475
+ {
476
+ tmpView.log.warn(`Dynamic View [${tmpView.UUID}]::[${tmpView.Hash}] skipping RecordSet ordinal ${tmpSolver.Ordinal} [${tmpSolver.Expression}] due to solver cycle prevention.`);
477
+ }
478
+ continue;
479
+ }
480
+
346
481
  tmpSolver.StartTimeStamp = +new Date();
347
482
  tmpSolver.Hash = `${pViewSectionSolverArray[i].ViewHash}-SectionSolver-${i}`;
348
483
 
@@ -408,7 +543,7 @@ class PictDynamicSolver extends libPictProvider
408
543
  {
409
544
  if (!(pOrdinal.toString() in pOrdinalSet))
410
545
  {
411
- pOrdinalSet[pOrdinal.toString()] = { ViewSolvers:[], SectionSolvers:[], GroupSolvers:[] };
546
+ pOrdinalSet[pOrdinal.toString()] = { ViewSolvers:[], SectionSolvers:[], GroupSolvers:[], AdhocSolvers:[] };
412
547
  }
413
548
  return pOrdinalSet[pOrdinal];
414
549
  }
@@ -434,11 +569,14 @@ class PictDynamicSolver extends libPictProvider
434
569
  * leaves on the tree.
435
570
 
436
571
  * @param {Array|string[]} [pViewHashes] - An optional array of view hashes to solve. If not provided, all views in the fable will be solved.
572
+ * @param {boolean} [pPreventSolverCycles] - An optional context string for the solve operation.
573
+ * TODO: make sure you can't cycle with the same solve context - new solver method to invoke this
437
574
  */
438
- solveViews(pViewHashes)
575
+ solveViews(pViewHashes, pPreventSolverCycles)
439
576
  {
440
577
  //this.log.trace(`Dynamic View Provider [${this.UUID}]::[${this.Hash}] solving views.`);
441
578
  let tmpViewHashes = Array.isArray(pViewHashes) ? pViewHashes : Object.keys(this.fable.views);
579
+ const tmpPreventSolverCycles = pPreventSolverCycles === true;
442
580
 
443
581
  let tmpSolveOutcome = {};
444
582
  tmpSolveOutcome.SolverResultsMap = {};
@@ -513,8 +651,8 @@ class PictDynamicSolver extends libPictProvider
513
651
  let tmpExecuteOrdinal = this.pict.providers.DynamicFormSolverBehaviors.checkSolverOrdinalEnabled(tmpOrdinalKeys[i]);
514
652
  if (tmpExecuteOrdinal)
515
653
  {
516
- this.executeGroupSolvers(tmpOrdinalContainer.GroupSolvers, Number(tmpOrdinalKeys[i]), tmpSolveOutcome.SolverResultsMap);
517
- this.executeSectionSolvers(tmpOrdinalContainer.SectionSolvers, Number(tmpOrdinalKeys[i]), tmpSolveOutcome.SolverResultsMap);
654
+ this.executeGroupSolvers(tmpOrdinalContainer.GroupSolvers, Number(tmpOrdinalKeys[i]), tmpSolveOutcome.SolverResultsMap, tmpPreventSolverCycles);
655
+ this.executeSectionSolvers(tmpOrdinalContainer.SectionSolvers, Number(tmpOrdinalKeys[i]), tmpSolveOutcome.SolverResultsMap, tmpPreventSolverCycles);
518
656
  this.executeViewSolvers(tmpOrdinalContainer.ViewSolvers, Number(tmpOrdinalKeys[i]), tmpSolveOutcome.SolverResultsMap);
519
657
  }
520
658
  }
@@ -19,7 +19,6 @@ const _DynamicInputViewSection = (
19
19
  "Name": "Dynamic Inputs",
20
20
  "ViewHash": "PictFormMetacontroller-DynamicInputs",
21
21
 
22
- "AutoMarshalDataOnSolve": true,
23
22
  "IncludeInMetatemplateSectionGeneration": false,
24
23
 
25
24
  "Manifests": {
@@ -280,6 +280,15 @@ Glug glug glug Oo... -->
280
280
  <input type="hidden" {~D:Record.Macro.InputFullProperties~} {~D:Record.Macro.InputChangeHandler~} value="">
281
281
  <span>{~D:Record.Name~}:</span>
282
282
  <div id="DISPLAY-FOR-{~D:Record.Macro.RawHTMLID~}" class="pict-section-form-html"></div>
283
+ `
284
+ },
285
+ {
286
+ "HashPostfix": "-Template-Input-InputType-Templated",
287
+ "DefaultInputExtensions": ["Pict-Input-Templated"],
288
+ "Template": /*HTML*/`
289
+ <!-- InputType Templated {~D:Record.Hash~} {~D:Record.DataType~} -->
290
+ <input type="hidden" {~D:Record.Macro.InputFullProperties~} {~D:Record.Macro.InputChangeHandler~} value="">
291
+ <div id="DISPLAY-FOR-{~D:Record.Macro.RawHTMLID~}" class="pict-section-form-templated"></div>
283
292
  `
284
293
  },
285
294
  {
@@ -471,6 +480,17 @@ Glug glug glug Oo... -->
471
480
  <span>{~D:Record.PictForm.ExtraDescription~}</span>
472
481
  <div id="DISPLAY-FOR-{~D:Record.Macro.RawHTMLID~}" class="pict-section-form-html"></div>
473
482
  </div>
483
+ `
484
+ },
485
+ {
486
+ "HashPostfix": "-VerticalTemplate-Input-InputType-Templated",
487
+ "DefaultInputExtensions": ["Pict-Input-Templated"],
488
+ "Template": /*HTML*/`
489
+ <!-- InputType Templated {~D:Record.Hash~} {~D:Record.DataType~} -->
490
+ <div class="pict-form-vertical-input">
491
+ <input type="hidden" {~D:Record.Macro.InputFullProperties~} {~D:Record.Macro.InputChangeHandler~} value="">
492
+ <div id="DISPLAY-FOR-{~D:Record.Macro.RawHTMLID~}" class="pict-section-form-templated"></div>
493
+ </div>
474
494
  `
475
495
  },
476
496
  {
@@ -131,6 +131,17 @@ class CustomInputHandler extends libPictSectionInputExtension
131
131
  const tmpGroupConfig = tmpTriggerGroupConfigurations[i];
132
132
  if (tmpGroupConfig.TriggerAllInputs)
133
133
  {
134
+ if (Array.isArray(tmpGroupConfig.PreSolvers))
135
+ {
136
+ this.pict.providers.DynamicSolver.executeSolvers(pView, tmpGroupConfig.PreSolvers, `AutofillTriggerGroup hash ${tmpGroupConfig.TriggerGroupHash} pre-trigger`);
137
+ }
138
+ pView.registerOnTransactionCompleteCallback(pTransactionGUID, () =>
139
+ {
140
+ if (Array.isArray(tmpGroupConfig.PostSolvers))
141
+ {
142
+ this.pict.providers.DynamicSolver.executeSolvers(pView, tmpGroupConfig.PostSolvers, `AutofillTriggerGroup hash ${tmpGroupConfig.TriggerGroupHash} post-trigger`);
143
+ }
144
+ });
134
145
  this.pict.views.PictFormMetacontroller.triggerGlobalInputEvent(
135
146
  `TriggerGroup:${tmpGroupConfig.TriggerGroupHash}:DataChange:${pInput.Hash || pInput.DataAddress}:${this.pict.getUUID()}`,
136
147
  pTransactionGUID);
@@ -161,6 +172,17 @@ class CustomInputHandler extends libPictSectionInputExtension
161
172
  const tmpGroupConfig = tmpTriggerGroupConfigurations[i];
162
173
  if (tmpGroupConfig.TriggerAllInputs)
163
174
  {
175
+ if (Array.isArray(tmpGroupConfig.PreSolvers))
176
+ {
177
+ this.pict.providers.DynamicSolver.executeSolvers(pView, tmpGroupConfig.PreSolvers, `AutofillTriggerGroup hash ${tmpGroupConfig.TriggerGroupHash} tabular pre-trigger`);
178
+ }
179
+ pView.registerOnTransactionCompleteCallback(pTransactionGUID, () =>
180
+ {
181
+ if (Array.isArray(tmpGroupConfig.PostSolvers))
182
+ {
183
+ this.pict.providers.DynamicSolver.executeSolvers(pView, tmpGroupConfig.PostSolvers, `AutofillTriggerGroup hash ${tmpGroupConfig.TriggerGroupHash} tabular post-trigger`);
184
+ }
185
+ });
164
186
  this.pict.views.PictFormMetacontroller.triggerGlobalInputEvent(
165
187
  `TriggerGroup:${tmpGroupConfig.TriggerGroupHash}:DataChange:${pInput.Hash || pInput.DataAddress}:${this.pict.getUUID()}`,
166
188
  pTransactionGUID);
@@ -207,6 +229,11 @@ class CustomInputHandler extends libPictSectionInputExtension
207
229
  continue;
208
230
  }
209
231
 
232
+ if (Array.isArray(tmpAutoFillTriggerGroup.PreSolvers))
233
+ {
234
+ this.pict.providers.DynamicSolver.executeSolvers(pView, tmpAutoFillTriggerGroup.PreSolvers, `AutofillTriggerGroup hash ${tmpAutoFillTriggerGroup.TriggerGroupHash} pre-autofill`);
235
+ }
236
+
210
237
  //FIXME: why is this check here? revisit
211
238
  if ('TriggerAddress' in tmpAutoFillTriggerGroup)
212
239
  {
@@ -223,6 +250,11 @@ class CustomInputHandler extends libPictSectionInputExtension
223
250
  this.pict.providers['Pict-Input-Select'].refreshSelectList(tmpInputView, tmpInputView.getGroup(pInput.PictForm.GroupIndex), tmpInputView.getRow(pInput.PictForm.GroupIndex, pInput.PictForm.Row), pInput, pValue, pHTMLSelector);
224
251
  tmpInputView.manualMarshalDataToViewByInput(pInput, tmpEventGUID);
225
252
  }
253
+
254
+ if (Array.isArray(tmpAutoFillTriggerGroup.PostSolvers))
255
+ {
256
+ this.pict.providers.DynamicSolver.executeSolvers(pView, tmpAutoFillTriggerGroup.PostSolvers, `AutofillTriggerGroup hash ${tmpAutoFillTriggerGroup.TriggerGroupHash} post-autofill`);
257
+ }
226
258
  }
227
259
 
228
260
  return super.onAfterEventCompletion(pView, pInput, pValue, pHTMLSelector, pEvent, pTransactionGUID);
@@ -311,7 +311,7 @@ class CustomInputHandler extends libPictSectionInputExtension
311
311
  onInputInitialize(pView, pGroup, pRow, pInput, pValue, pHTMLSelector, pTransactionGUID)
312
312
  {
313
313
  // Try to get the input element
314
- if (pValue && pInput.PictForm && pInput.PictForm.EntityBundleTriggerOnInitialize)
314
+ if (pInput.PictForm && (pValue || pInput.PictForm.EntityBundleTriggerWithoutValue) && pInput.PictForm.EntityBundleTriggerOnInitialize)
315
315
  {
316
316
  // This is a request on initial load
317
317
  this.gatherDataFromServer(pView, pInput, pValue, pHTMLSelector, pTransactionGUID);
@@ -334,6 +334,7 @@ class CustomInputHandler extends libPictSectionInputExtension
334
334
  */
335
335
  onInputInitializeTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID)
336
336
  {
337
+ this.log.error(`EntityBundleRequest for input [${pInput.Hash}] Tabular support is intentionally not supported.`);
337
338
  return super.onInputInitializeTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID);
338
339
  }
339
340
 
@@ -349,59 +350,36 @@ class CustomInputHandler extends libPictSectionInputExtension
349
350
  */
350
351
  onDataChange(pView, pInput, pValue, pHTMLSelector, pTransactionGUID)
351
352
  {
352
- this.gatherDataFromServer(pView, pInput, pValue, pHTMLSelector, pTransactionGUID);
353
+ if (pInput.PictForm && (pValue || pInput.PictForm.EntityBundleTriggerWithoutValue) && pInput.PictForm.EntityBundleTriggerOnDataChange !== false)
354
+ {
355
+ this.gatherDataFromServer(pView, pInput, pValue, pHTMLSelector, pTransactionGUID);
356
+ }
353
357
  return super.onDataChange(pView, pInput, pValue, pHTMLSelector, pTransactionGUID);
354
358
  }
355
359
 
356
360
  /**
357
- * Handles the change event for tabular data.
361
+ * This input extension only responds to events
358
362
  *
359
363
  * @param {Object} pView - The view object.
360
364
  * @param {Object} pInput - The input object.
361
- * @param {any} pValue - The new value.
365
+ * @param {any} pValue - The value from AppData.
362
366
  * @param {string} pHTMLSelector - The HTML selector.
363
- * @param {number} pRowIndex - The index of the row.
364
- * @param {string} pTransactionGUID - The transaction GUID for the event dispatch.
365
- * @returns {any} - The result of the super method.
367
+ * @param {string} pEvent - The event hash that is expected to be triggered.
368
+ * @param {string} pTransactionGUID - The transaction GUID, if any.
369
+ * @returns {boolean} - Returns true.
366
370
  */
367
- onDataChangeTabular(pView, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID)
371
+ onAfterEventCompletion(pView, pInput, pValue, pHTMLSelector, pEvent, pTransactionGUID)
368
372
  {
369
- this.gatherDataFromServer(pView, pInput, pValue, pHTMLSelector, pTransactionGUID);
370
- return super.onDataChangeTabular(pView, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID);
371
- }
373
+ const tmpPayload = typeof pEvent === 'string' ? pEvent : '';
374
+ let [ tmpType, tmpGroupHash ] = tmpPayload.split(':');
372
375
 
373
- /**
374
- * Marshals data to the form for the given input.
375
- *
376
- * @param {Object} pView - The view object.
377
- * @param {Object} pGroup - The group object.
378
- * @param {Object} pRow - The row object.
379
- * @param {Object} pInput - The input object.
380
- * @param {any} pValue - The value to be marshaled.
381
- * @param {string} pHTMLSelector - The HTML selector.
382
- * @param {string} pTransactionGUID - The transaction GUID for the event dispatch.
383
- * @returns {boolean} - Returns true if the value is successfully marshaled to the form, otherwise false.
384
- */
385
- onDataMarshalToForm(pView, pGroup, pRow, pInput, pValue, pHTMLSelector, pTransactionGUID)
386
- {
387
- return super.onDataMarshalToForm(pView, pGroup, pRow, pInput, pValue, pHTMLSelector, pTransactionGUID);
388
- }
376
+ if (pInput.PictForm.TriggerGroupHash !== tmpGroupHash)
377
+ {
378
+ return super.onAfterEventCompletion(pView, pInput, pValue, pHTMLSelector, pEvent, pTransactionGUID);
379
+ }
380
+ this.gatherDataFromServer(pView, pInput, pValue, pHTMLSelector, pTransactionGUID);
389
381
 
390
- /**
391
- * Marshals data to a form in tabular format.
392
- *
393
- * @param {Object} pView - The view object.
394
- * @param {Object} pGroup - The group object.
395
- * @param {Object} pInput - The input object.
396
- * @param {any} pValue - The value parameter.
397
- * @param {string} pHTMLSelector - The HTML selector parameter.
398
- * @param {number} pRowIndex - The row index parameter.
399
- * @param {string} pTransactionGUID - The transaction GUID for the event dispatch.
400
- * @returns {any} - The result of the data marshaling.
401
- */
402
- onDataMarshalToFormTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID)
403
- {
404
- return super.onDataMarshalToFormTabular(pView, pGroup, pInput, pValue, pHTMLSelector, pRowIndex, pTransactionGUID);
382
+ return super.onAfterEventCompletion(pView, pInput, pValue, pHTMLSelector, pEvent, pTransactionGUID);
405
383
  }
406
384
  }
407
385