pict-section-form
Advanced tools
Comparing version 1.0.15 to 1.0.16
const libPictSectionForm = require('../../source/Pict-Section-Form.js'); | ||
module.exports = libPictSectionForm.PictFormApplication; | ||
const libCustomDataProvider = require('./Complex-Tabular-CustomDataProvider.js'); | ||
module.exports.default_configuration = libPictSectionForm.PictFormApplication.default_configuration; | ||
module.exports.default_configuration.pict_configuration = ( | ||
class ComplexTabularApplication extends libPictSectionForm.PictFormApplication | ||
{ | ||
constructor(pFable, pOptions, pServiceHash) | ||
{ | ||
"Product": "SimpleTable", | ||
"DefaultAppData": require('./FruitData.json'), | ||
super(pFable, pOptions, pServiceHash); | ||
"DefaultFormManifest": | ||
{ | ||
"Scope": "SuperSimpleTabularForm", | ||
this.pict.addProvider('CustomDataProvider', libCustomDataProvider.default_configuration, libCustomDataProvider); | ||
} | ||
} | ||
"Sections": [ | ||
{ | ||
"Hash": "Recipe", | ||
"Name": "Fruit-based Recipe", | ||
module.exports = ComplexTabularApplication; | ||
module.exports.default_configuration = libPictSectionForm.PictFormApplication.default_configuration; | ||
module.exports.default_configuration.pict_configuration = { | ||
Product: "SimpleTable", | ||
"Solvers": | ||
[ | ||
"TotalFruitCalories = SUM(FruitNutritionCalories)", | ||
"AverageFruitCalories = MEAN(FruitNutritionCalories)", | ||
{ "Ordinal": 99, "Expression": "AverageFatPercent = MEAN(FruitPercentTotalFat)"}, | ||
"RecipeCounterSurfaceArea = RecipeCounterWidth * RecipeCounterDepth", | ||
"RecipeCounterVolume = RecipeCounterSurfaceArea * RecipeVerticalClearance", | ||
], | ||
DefaultAppData: require("./FruitData.json"), | ||
"Groups": [ | ||
{ | ||
"Hash": "Recipe", | ||
"Name": "Recipe", | ||
}, | ||
{ | ||
"Hash": "Statistics", | ||
"Name": "Statistics", | ||
}, | ||
{ | ||
"Hash": "FruitStatistics", | ||
"Name": "Statistics About the Fruit", | ||
} | ||
] | ||
}, | ||
{ | ||
"Hash": "FruitGrid", | ||
"Name": "Fruits of the World", | ||
"Groups": [ | ||
{ | ||
DefaultFormManifest: { | ||
Scope: "SuperSimpleTabularForm", | ||
"Hash": "FruitGrid", | ||
"Name": "FruitGrid", | ||
Sections: [ | ||
{ | ||
Hash: "Recipe", | ||
Name: "Fruit-based Recipe", | ||
"Layout": "Tabular", | ||
Solvers: | ||
[ | ||
"TotalFruitCalories = SUM(FruitNutritionCalories)", | ||
"AverageFruitCalories = MEAN(FruitNutritionCalories)", | ||
{ | ||
Ordinal: 99, | ||
Expression: "AverageFatPercent = MEAN(FruitPercentTotalFat)", | ||
}, | ||
"RecipeCounterSurfaceArea = RecipeCounterWidth * RecipeCounterDepth", | ||
"RecipeCounterVolume = RecipeCounterSurfaceArea * RecipeVerticalClearance", | ||
], | ||
"RecordSetSolvers": [ | ||
{"Ordinal": 0, "Expression": "PercentTotalFat = (Fat * 9) / Calories"} | ||
], | ||
"RecordSetAddress": "FruitData.FruityVice", | ||
"RecordManifest": "FruitEditor" | ||
} | ||
] | ||
}, | ||
], | ||
MetaTemplates: | ||
[ | ||
{ | ||
//onclick="{~D:Record.Macro.DataRequestFunction~}" | ||
"HashPostfix": "-Template-Wrap-Prefix", | ||
"Template": "<h1>Rectangular Area Solver Micro-app</h1><div><a href=\"#\" onclick=\"_Pict.PictApplication.solve()\">[ solve ]</a></div><hr />" | ||
} | ||
], | ||
"Descriptors": | ||
PickLists: | ||
[ | ||
{ | ||
Hash: "Families", | ||
ListAddress: "AppData.FruitMetaLists.Families", | ||
ListSourceAddress: "FruitData.FruityVice[]", | ||
TextTemplate: "{~D:Record.family~}", | ||
IDTemplate: "{~D:Record.family~}", | ||
Unique: true, | ||
Sorted: true, | ||
UpdateFrequency: "Once", | ||
}, | ||
{ | ||
Hash: "Orders", | ||
ListAddress: "AppData.FruitMetaLists.Orders", | ||
ListSourceAddress: "FruitData.FruityVice[]", | ||
TextTemplate: "{~D:Record.order~}", | ||
IDTemplate: "{~D:Record.order~}", | ||
Unique: true, | ||
UpdateFrequency: "Once", | ||
}, | ||
{ | ||
Hash: "Genuses", | ||
ListAddress: "AppData.FruitMetaLists.Genuses", | ||
ListSourceAddress: "FruitData.FruityVice[]", | ||
TextTemplate: "{~D:Record.genus~}", | ||
IDTemplate: "{~D:Record.genus~}", | ||
Sorted: true, | ||
UpdateFrequency: "Always", | ||
}, | ||
], | ||
Groups: [ | ||
{ | ||
Hash: "Recipe", | ||
Name: "Recipe", | ||
}, | ||
{ | ||
Hash: "Statistics", | ||
Name: "Statistics", | ||
}, | ||
{ | ||
Hash: "FruitStatistics", | ||
Name: "Statistics About the Fruit", | ||
}, | ||
], | ||
}, | ||
{ | ||
"RecipeName": { "Name": "Recipe Name", "Hash": "RecipeName", "DataType": "String", "PictForm": { "Section": "Recipe", "Group": "Recipe" } }, | ||
"RecipeType": { "Name": "Recipe Type", "Hash": "RecipeType", "DataType": "String", "PictForm": { "Section": "Recipe", "Group": "Recipe" } }, | ||
"RecipeDescription": { "Name": "Description", "Hash": "RecipeDescription", "DataType": "String", "PictForm": { "Section": "Recipe", "Group": "Recipe" } }, | ||
"Inventor": { "Name": "Inventor", "Hash": "Inventor", "DataType": "String", "PictForm": { "Section": "Recipe", "Group": "Recipe" } }, | ||
Hash: "FruitGrid", | ||
Name: "Fruits of the World", | ||
Groups: [ | ||
{ | ||
Hash: "FruitGrid", | ||
Name: "FruitGrid", | ||
"Recipe.Feeds": { | ||
"Name": "Feeds", "Hash": "RecipeFeeds", "DataType": "PreciseNumber", "Default": "1", | ||
"PictForm": { "Section": "Recipe", "Group": "Statistics", "Row": 1, "Width": 1 } | ||
}, | ||
"Recipe.TotalCalories": { | ||
"Name": "Calories in the Fruits", "Hash": "RecipeCalories", "DataType": "PreciseNumber", "Default": "1", | ||
"PictForm": { "Section": "Recipe", "Group": "Statistics", "Row": 1, "Width": 1 } | ||
}, | ||
Layout: "Tabular", | ||
"Recipe.CounterWidth": { | ||
"Name": "Counter Prep Width Requirements", "Hash": "RecipeCounterWidth", "DataType": "PreciseNumber", "Default": "10", | ||
"PictForm": { "Section": "Recipe", "Group": "Statistics", "Row": 2, "Width": 1 } | ||
}, | ||
"Recipe.CounterDepth": { | ||
"Name": "Counter Prep Depth Requirements", "Hash": "RecipeCounterDepth", "DataType": "PreciseNumber", "Default": "5", | ||
"PictForm": { "Section": "Recipe", "Group": "Statistics", "Row": 2, "Width": 1 } | ||
}, | ||
"Recipe.CounterSurfaceArea": { | ||
"Name": "Required Counter Surface Area", "Hash": "RecipeCounterSurfaceArea", "DataType": "PreciseNumber", | ||
"PictForm": { "Section": "Recipe", "Group": "Statistics", "Row": 2, "Width": 1 } | ||
}, | ||
RecordSetSolvers: [ | ||
{ | ||
Ordinal: 0, | ||
Expression: "PercentTotalFat = (Fat * 9) / Calories", | ||
}, | ||
], | ||
RecordSetAddress: "FruitData.FruityVice", | ||
RecordManifest: "FruitEditor", | ||
}, | ||
], | ||
}, | ||
], | ||
"Recipe.VerticalClearance": { | ||
"Name": "Prep Vertical Clearance", "Hash": "RecipeVerticalClearance", "DataType": "PreciseNumber", "Default": "12", | ||
"PictForm": { "Section": "Recipe", "Group": "Statistics", "Row": 3, "Width": 1 } | ||
Descriptors: { | ||
RecipeName: { | ||
Name: "Recipe Name", | ||
Hash: "RecipeName", | ||
DataType: "String", | ||
PictForm: { Section: "Recipe", Group: "Recipe", Row: 1 }, | ||
}, | ||
RecipeType: { | ||
Name: "Recipe Type", | ||
Hash: "RecipeType", | ||
DataType: "String", | ||
PictForm: | ||
{ | ||
Section:"Recipe", | ||
Group:"Recipe", | ||
Row: 1, | ||
"InputType":"Combo", | ||
"Entries": | ||
[ | ||
"Smoothie", "Salad", "Dessert", "Main Course", "Side Dish", "Snack" | ||
] | ||
}, | ||
}, | ||
RecipeDescription: { | ||
Name: "Description", | ||
Hash: "RecipeDescription", | ||
DataType: "String", | ||
PictForm: { Section: "Recipe", Group: "Recipe", Row: 2 }, | ||
}, | ||
Inventor: { | ||
Name: "Inventor", | ||
Hash: "Inventor", | ||
DataType: "String", | ||
PictForm: { Section: "Recipe", Group: "Recipe", Row: 3 }, | ||
}, | ||
"MetaFruit.Information.FavoriteGenus": { | ||
Name: "Favorite Genus", | ||
Hash: "FavoriteGenus", | ||
DataType: "String", | ||
PictForm: { Section: "Recipe", Group: "Recipe", Row: 4 }, | ||
}, | ||
"Recipe.Feeds": { | ||
Name: "Feeds", | ||
Hash: "RecipeFeeds", | ||
DataType: "PreciseNumber", | ||
Default: "1", | ||
PictForm: { Section: "Recipe", Group: "Statistics", Row: 1, Width: 1, | ||
"InputType":"Option", | ||
"Providers": ["CustomDataProvider", "Pict-Input-Select"], | ||
"SelectOptions": [{"id":"few", "text":"Few"}, {"id":"some", "text":"Some"}, {"id":"many", "text":"Many"}] | ||
}, | ||
"Recipe.PrepVolume": { | ||
"Name": "Preparation Volume Requirements", "Hash": "RecipeCounterVolume", "DataType": "PreciseNumber", | ||
"PictForm": { "Section": "Recipe", "Group": "Statistics", "Row": 3, "Width": 1 } | ||
}, | ||
"Recipe.MoistureContent": { | ||
"Name": "Required Moisture Content", "Hash": "RecipeMoistureContent", "DataType": "PreciseNumber", | ||
"PictForm": { "Section": "Recipe", "Group": "Statistics", "Row": 3, "Width": 1 } | ||
}, | ||
}, | ||
"Recipe.TotalCalories": { | ||
Name: "Calories in the Fruits", | ||
Hash: "RecipeCalories", | ||
DataType: "PreciseNumber", | ||
Default: "1", | ||
PictForm: { Section: "Recipe", Group: "Statistics", Row: 1, Width: 1 }, | ||
}, | ||
"FruitStats.TotalCalories": { | ||
"Name": "Total Calories in All Fruits", "Hash": "TotalFruitCalories", "DataType": "PreciseNumber", | ||
"PictForm": { "Section": "Recipe", "Group": "FruitStatistics", "Row": 1, "Width": 1 } | ||
"Recipe.CounterWidth": { | ||
Name: "Counter Prep Width Requirements", | ||
Hash: "RecipeCounterWidth", | ||
DataType: "PreciseNumber", | ||
Default: "10", | ||
PictForm: { Section: "Recipe", Group: "Statistics", Row: 2, Width: 1 }, | ||
}, | ||
"Recipe.CounterDepth": { | ||
Name: "Counter Prep Depth Requirements", | ||
Hash: "RecipeCounterDepth", | ||
DataType: "PreciseNumber", | ||
Default: "5", | ||
PictForm: { Section: "Recipe", Group: "Statistics", Row: 2, Width: 1 }, | ||
}, | ||
"Recipe.CounterSurfaceArea": { | ||
Name: "Required Counter Surface Area", | ||
Hash: "RecipeCounterSurfaceArea", | ||
DataType: "PreciseNumber", | ||
PictForm: { Section: "Recipe", Group: "Statistics", Row: 2, Width: 1 }, | ||
}, | ||
"Recipe.VerticalClearance": { | ||
Name: "Prep Vertical Clearance", | ||
Hash: "RecipeVerticalClearance", | ||
DataType: "PreciseNumber", | ||
Default: "12", | ||
PictForm: { Section: "Recipe", Group: "Statistics", Row: 3, Width: 1 }, | ||
}, | ||
"Recipe.PrepVolume": { | ||
Name: "Preparation Volume Requirements", | ||
Hash: "RecipeCounterVolume", | ||
DataType: "PreciseNumber", | ||
PictForm: { Section: "Recipe", Group: "Statistics", Row: 3, Width: 1 }, | ||
}, | ||
"Recipe.MoistureContent": { | ||
Name: "Required Moisture Content", | ||
Hash: "RecipeMoistureContent", | ||
DataType: "PreciseNumber", | ||
PictForm: { Section: "Recipe", Group: "Statistics", Row: 3, Width: 1 }, | ||
}, | ||
"FruitStats.TotalCalories": { | ||
Name: "Total Calories in All Fruits", | ||
Hash: "TotalFruitCalories", | ||
DataType: "PreciseNumber", | ||
PictForm: { | ||
Section: "Recipe", | ||
Group: "FruitStatistics", | ||
Row: 1, | ||
Width: 1, | ||
}, | ||
"FruitStats.AverageCalories": { | ||
"Name": "Average (mean) Calories in All Fruits", "Hash": "AverageFruitCalories", "DataType": "PreciseNumber", | ||
"PictForm": { "Section": "Recipe", "Group": "FruitStatistics", "Row": 1, "Width": 1 } | ||
}, | ||
"FruitStats.AverageCalories": { | ||
Name: "Average (mean) Calories in All Fruits", | ||
Hash: "AverageFruitCalories", | ||
DataType: "PreciseNumber", | ||
PictForm: { | ||
Section: "Recipe", | ||
Group: "FruitStatistics", | ||
Row: 1, | ||
Width: 1, | ||
}, | ||
"FruitStats.AverageFatPercent": { | ||
"Name": "Average (mean) Fat Percentage in All Fruits", "Hash": "AverageFatPercent", "DataType": "PreciseNumber", | ||
"PictForm": { "Section": "Recipe", "Group": "FruitStatistics", "Row": 1, "Width": 1 } | ||
}, | ||
"FruitStats.AverageFatPercent": { | ||
Name: "Average (mean) Fat Percentage in All Fruits", | ||
Hash: "AverageFatPercent", | ||
DataType: "PreciseNumber", | ||
PictForm: { | ||
Section: "Recipe", | ||
Group: "FruitStatistics", | ||
Row: 1, | ||
Width: 1, | ||
}, | ||
}, | ||
"FruitData.FruityVice": { | ||
Name: "Fruits of the Earth", | ||
Hash: "FruitGrid", | ||
DataType: "Array", | ||
Default: [], | ||
PictForm: { Section: "FruitGrid", Group: "FruitGrid" }, | ||
}, | ||
"FruitData.FruityVice[].nutritions.calories": { | ||
Hash: "FruitNutritionCalories", | ||
}, | ||
"FruitData.FruityVice[].nutritions.percent_total_fat": { | ||
Hash: "FruitPercentTotalFat", | ||
}, | ||
}, | ||
"FruitData.FruityVice": | ||
{ | ||
"Name": "Fruits of the Earth", | ||
"Hash": "FruitGrid", | ||
"DataType": "Array", | ||
"Default": [] | ||
, "PictForm": { "Section": "FruitGrid", "Group": "FruitGrid" } | ||
}, | ||
ReferenceManifests: { | ||
FruitEditor: { | ||
Scope: "FruitEditor", | ||
"FruitData.FruityVice[].nutritions.calories": | ||
{ | ||
"Hash": "FruitNutritionCalories" | ||
Descriptors: { | ||
name: { | ||
Name: "Fruit Name", | ||
Hash: "Name", | ||
DataType: "String", | ||
Default: "(unnamed fruit)", | ||
PictForm: { Section: "FruitGrid", Group: "FruitGrid" }, | ||
}, | ||
family: { | ||
Name: "Family", | ||
Hash: "Family", | ||
DataType: "String", | ||
PictForm: { Section: "FruitGrid", Group: "FruitGrid", "InputType":"Option", | ||
"Providers": ["Pict-Input-Select"], | ||
"SelectOptionsPickList": "Families"} | ||
}, | ||
order: { | ||
Name: "Order", | ||
Hash: "Order", | ||
DataType: "String", | ||
PictForm: { Section: "FruitGrid", Group: "FruitGrid" }, | ||
}, | ||
genus: { | ||
Name: "Genus", | ||
Hash: "Genus", | ||
DataType: "String", | ||
PictForm: { Section: "FruitGrid", Group: "FruitGrid" }, | ||
}, | ||
"nutritions.calories": { | ||
Name: "Calories", | ||
Hash: "Calories", | ||
DataType: "Number", | ||
PictForm: { Section: "FruitGrid", Group: "FruitGrid"}, | ||
}, | ||
"nutritions.fat": { | ||
Name: "Fat", | ||
Hash: "Fat", | ||
DataType: "Number", | ||
PictForm: { Section: "FruitGrid", Group: "FruitGrid" }, | ||
}, | ||
"nutritions.carbohydrates": { | ||
Name: "Carbohydrates", | ||
Hash: "Carbs", | ||
DataType: "Number", | ||
PictForm: { Section: "FruitGrid", Group: "FruitGrid" }, | ||
}, | ||
"nutritions.protein": { | ||
Name: "Protein", | ||
Hash: "Protein", | ||
DataType: "Number", | ||
PictForm: { Section: "FruitGrid", Group: "FruitGrid" }, | ||
}, | ||
"nutritions.percent_total_fat": { | ||
Name: "PercentTotalFat", | ||
Hash: "PercentTotalFat", | ||
DataType: "Number", | ||
PictForm: { Section: "FruitGrid", Group: "FruitGrid" }, | ||
}, | ||
}, | ||
"FruitData.FruityVice[].nutritions.percent_total_fat": | ||
{ | ||
"Hash": "FruitPercentTotalFat" | ||
}, | ||
}, | ||
"ReferenceManifests": | ||
{ | ||
"FruitEditor": | ||
{ | ||
"Scope": "FruitEditor", | ||
"Descriptors": | ||
{ | ||
"name": | ||
{ | ||
"Name": "Fruit Name", | ||
"Hash": "Name", | ||
"DataType": "String", | ||
"Default": "(unnamed fruit)" | ||
, "PictForm": { "Section": "FruitGrid", "Group": "FruitGrid" } | ||
}, | ||
"family": | ||
{ | ||
"Name": "Family", | ||
"Hash": "Family", | ||
"DataType": "String" | ||
, "PictForm": { "Section": "FruitGrid", "Group": "FruitGrid" } | ||
}, | ||
"order": | ||
{ | ||
"Name": "Order", | ||
"Hash": "Order", | ||
"DataType": "String" | ||
, "PictForm": { "Section": "FruitGrid", "Group": "FruitGrid" } | ||
}, | ||
"genus": | ||
{ | ||
"Name": "Genus", | ||
"Hash": "Genus", | ||
"DataType": "String" | ||
, "PictForm": { "Section": "FruitGrid", "Group": "FruitGrid" } | ||
}, | ||
"nutritions.calories": | ||
{ | ||
"Name": "Calories", | ||
"Hash": "Calories", | ||
"DataType": "Number" | ||
, "PictForm": { "Section": "FruitGrid", "Group": "FruitGrid" } | ||
}, | ||
"nutritions.fat": | ||
{ | ||
"Name": "Fat", | ||
"Hash": "Fat", | ||
"DataType": "Number" | ||
, "PictForm": { "Section": "FruitGrid", "Group": "FruitGrid" } | ||
}, | ||
"nutritions.carbohydrates": | ||
{ | ||
"Name": "Carbohydrates", | ||
"Hash": "Carbs", | ||
"DataType": "Number" | ||
, "PictForm": { "Section": "FruitGrid", "Group": "FruitGrid" } | ||
}, | ||
"nutritions.protein": | ||
{ | ||
"Name": "Protein", | ||
"Hash": "Protein", | ||
"DataType": "Number" | ||
, "PictForm": { "Section": "FruitGrid", "Group": "FruitGrid" } | ||
}, | ||
"nutritions.percent_total_fat": | ||
{ | ||
"Name": "PercentTotalFat", | ||
"Hash": "PercentTotalFat", | ||
"DataType": "Number" | ||
, "PictForm": { "Section": "FruitGrid", "Group": "FruitGrid" } | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
}, | ||
}, | ||
}; |
{ | ||
"name": "pict-section-form", | ||
"version": "1.0.15", | ||
"version": "1.0.16", | ||
"description": "Pict dynamic form sections", | ||
@@ -34,3 +34,3 @@ "main": "source/Pict-Section-Form.js", | ||
"jquery": "^3.7.1", | ||
"pict": "^1.0.200", | ||
"pict": "^1.0.201", | ||
"pict-application": "^1.0.18", | ||
@@ -43,3 +43,3 @@ "quackage": "^1.0.30", | ||
"pict-provider": "^1.0.2", | ||
"pict-template": "^1.0.1", | ||
"pict-template": "^1.0.2", | ||
"pict-view": "^1.0.47" | ||
@@ -46,0 +46,0 @@ }, |
@@ -10,2 +10,5 @@ // The container for all the Pict-Section-Form related code. | ||
// The base provider class for Input Extensions | ||
module.exports.PictInputExtensionProvider = require('./providers/Pict-Provider-InputExtension.js'); | ||
// The metacontroller view | ||
@@ -15,2 +18,2 @@ module.exports.PictFormMetacontroller = require('./views/Pict-View-Form-Metacontroller.js'); | ||
// The application container | ||
module.exports.PictFormApplication = require('./application/Pict-Application-Form.js'); | ||
module.exports.PictFormApplication = require('./application/Pict-Application-Form.js'); |
const libPictProvider = require('pict-provider'); | ||
const libDynamicMetaLists = require('./Pict-Provider-MetaLists.js'); | ||
const libInputSelect = require('./inputs/Pict-Provider-Input-Select.js'); | ||
const _DefaultProviderConfiguration = ( | ||
@@ -29,2 +32,16 @@ { | ||
super(pFable, tmpOptions, pServiceHash); | ||
// Initialize the solver service if it isn't up | ||
this.fable.instantiateServiceProviderIfNotExists('ExpressionParser'); | ||
if (!this.pict.providers.DynamicMetaLists) | ||
{ | ||
let tmpDynamicMetaLists = this.pict.addProvider('DynamicMetaLists', libDynamicMetaLists.default_configuration, libDynamicMetaLists); | ||
tmpDynamicMetaLists.initialize(); | ||
} | ||
if (!this.pict.providers['Pict-Input-Select']); | ||
{ | ||
let tmpInputSelectProvider = this.pict.addProvider('Pict-Input-Select', libInputSelect.default_configuration, libInputSelect); | ||
tmpInputSelectProvider.initialize(); | ||
} | ||
} | ||
@@ -316,2 +333,5 @@ | ||
// Now regenerate the metalists .. after the solve has happened. | ||
this.pict.providers.DynamicMetaLists.buildLists(tmpViewHashes); | ||
tmpSolveOutcome.EndTimeStamp = +new Date(); | ||
@@ -318,0 +338,0 @@ |
@@ -158,2 +158,10 @@ module.exports = ( | ||
}, | ||
{ | ||
"HashPostfix": "-Template-Input-InputType-Option", | ||
"Template": /*HTML*/` | ||
<!-- InputType Option {~D:Record.Hash~} {~D:Record.DataType~} --> | ||
<input type="hidden" {~D:Record.Macro.InputFullProperties~} {~D:Record.Macro.InputChangeHandler~} value=""> | ||
<span>{~D:Record.Name~}:</span> <select id="SELECT-FOR-{~D:Record.Macro.RawHTMLID~}" onchange="{~D:Record.Macro.DataRequestFunction~}"></select> | ||
` | ||
}, | ||
/* | ||
@@ -297,8 +305,14 @@ * END Input Templates (default) | ||
}, | ||
{ | ||
"HashPostfix": "-TabularTemplate-End-Input", | ||
"Template": /*HTML*/` {~D:Record.Macro.InputChangeHandler~} value="">` | ||
"HashPostfix": "-TabularTemplate-Mid-Input", | ||
"Template": /*HTML*/` ` | ||
}, | ||
{ | ||
"HashPostfix": "-TabularTemplate-InformaryAddress-Input", | ||
"Template": /*HTML*/` data-i-index="{~D:Context[2].Key~}" data-i-cooooool="cools" onchange="_Pict.views['{~D:Context[0].Hash~}'].dataChangedTabular('{~D:Context[2].Group~}', '{~D:Record.PictForm.InputIndex~}', '{~D:Context[2].Key~}')" ` | ||
}, | ||
{ | ||
"HashPostfix": "-TabularTemplate-Begin-Input-DataType-String", | ||
@@ -311,3 +325,3 @@ "Template": /*HTML*/` | ||
"HashPostfix": "-TabularTemplate-End-Input-DataType-String", | ||
"Template": /*HTML*/` {~D:Record.Macro.InputChangeHandler~} value="">` | ||
"Template": /*HTML*/` value="">` | ||
}, | ||
@@ -323,3 +337,3 @@ | ||
"HashPostfix": "-TabularTemplate-End-Input-DataType-Number", | ||
"Template": /*HTML*/` {~D:Record.Macro.InputChangeHandler~} value=""> | ||
"Template": /*HTML*/` value=""> | ||
` | ||
@@ -335,5 +349,18 @@ }, | ||
"HashPostfix": "-TabularTemplate-End-Input-InputType-TextArea", | ||
"Template": /*HTML*/` {~D:Record.Macro.InputChangeHandler~}></textarea> | ||
"Template": /*HTML*/` ></textarea> | ||
` | ||
} | ||
}, | ||
{ | ||
"HashPostfix": "-TabularTemplate-Begin-Input-InputType-Option", | ||
"Template": /*HTML*/` | ||
<!-- InputType Option {~D:Record.Hash~} {~D:Record.DataType~} --> | ||
<input type="hidden" id="SELECT-TABULAR-DATA-{~D:Record.Macro.RawHTMLID~}-{~D:Context[2].Key~}" {~D:Record.Macro.HTMLName~} {~D:Record.Macro.InformaryTabular~} ` | ||
}, | ||
{ | ||
"HashPostfix": "-TabularTemplate-End-Input-InputType-Option", | ||
"Template": /*HTML*/` value=""> | ||
<select id="SELECT-TABULAR-DROPDOWN-{~D:Record.Macro.RawHTMLID~}-{~D:Context[2].Key~}" data-i-pictselect="SELECT-TABULAR-FOR-{~D:Record.Macro.RawHTMLID~}" onchange="_Pict.views['{~D:Context[0].Hash~}'].inputDataRequestTabular('{~D:Context[2].Group~}', '{~D:Record.PictForm.InputIndex~}', '{~D:Context[2].Key~}')"></select> | ||
` | ||
}, | ||
/* | ||
@@ -340,0 +367,0 @@ * END Tabular Input Templates |
@@ -91,4 +91,6 @@ const libPictProvider = require('pict-provider'); | ||
* @param {object} pManifest - The manifest object used to map form data to the application state data. | ||
* @param {string} pDatum - The datum hash to pull in. If not provided, all data is marshalled. | ||
* @param {number} pRecordIndex - The record index to pull in. If not provided, all data is marshalled. | ||
*/ | ||
marshalFormToData(pAppStateData, pFormHash, pManifest) | ||
marshalFormToData(pAppStateData, pFormHash, pManifest, pDatum, pRecordIndex) | ||
{ | ||
@@ -98,2 +100,6 @@ let tmpManifest = typeof(pManifest) === 'object' ? pManifest : this.genericManifest; | ||
// Optional Filters (so we don't just blindly do the whole form) | ||
let tmpDatum = (typeof(pDatum) === 'undefined') ? false : pDatum; | ||
let tmpRecordIndex = (typeof(pRecordIndex) === 'undefined') ? false : pRecordIndex; | ||
// Enumerate the form elements, and put data in them for each address | ||
@@ -107,2 +113,14 @@ for (let i = 0; i < tmpFormElements.length; i++) | ||
// Process the filters | ||
if (tmpDatum && (tmpDatum !== tmpDatumAddress)) | ||
{ | ||
// Falls outside the filter, continue on | ||
continue; | ||
} | ||
if (tmpIndex && tmpRecordIndex && (tmpRecordIndex !== tmpIndex)) | ||
{ | ||
// Falls outside the filter, continue on | ||
continue; | ||
} | ||
let tmpBrowserValue = this.pict.ContentAssignment.readContent(this.getContentBrowserAddress(pFormHash, tmpDatumAddress, tmpContainerAddress, tmpIndex)); | ||
@@ -141,2 +159,3 @@ | ||
{ | ||
// TODO: Take a list of hashes and/or index addresses to marshal in, preventing OVERMARSHAL from taking control | ||
let tmpManifest = typeof(pManifest) === 'object' ? pManifest : this.genericManifest; | ||
@@ -143,0 +162,0 @@ let tmpFormElements = this.getFormElements(pFormHash); |
@@ -13,3 +13,3 @@ const libPictProvider = require('pict-provider'); | ||
class PictSectionFormMetatemplateGenerator extends libPictProvider | ||
class PictMetatemplateGenerator extends libPictProvider | ||
{ | ||
@@ -24,5 +24,5 @@ constructor(pFable, pOptions, pServiceHash) | ||
module.exports = PictSectionFormMetatemplateGenerator; | ||
module.exports = PictMetatemplateGenerator; | ||
module.exports.default_configuration = _DefaultProviderConfiguration; | ||
@@ -25,3 +25,9 @@ { | ||
"HTMLSelector": "[data-i-form=\"{~D:Context[0].formID~}\"][data-i-datum=\"{~D:Record.PictForm.InformaryDataAddress~}\"]", | ||
"HTMLSelectorTabular": "[data-i-form=\"{~D:Context[0].formID~}\"][data-i-datum=\"{~D:Record.PictForm.InformaryDataAddress~}\"][data-i-container=\"{~D:Record.PictForm.InformaryContainerAddress~}\"]", | ||
"RawHTMLID": "{~D:Context[0].UUID~}-FormInput-{~D:Record.Hash~}", | ||
"HTMLName": " name=\"{~D:Record.Name~}\" ", | ||
"HTMLIDAddress": "#{~D:Context[0].UUID~}-FormInput-{~D:Record.Hash~}", | ||
"HTMLID": " id=\"{~D:Context[0].UUID~}-FormInput-{~D:Record.Hash~}\" ", | ||
@@ -31,3 +37,5 @@ "HTMLForID": " for=\"{~D:Context[0].UUID~}-FormInput-{~D:Record.Hash~}\" ", | ||
"InputFullProperties": " data-i-form=\"{~D:Context[0].formID~}\" data-i-datum=\"{~D:Record.PictForm.InformaryDataAddress~}\" name=\"{~D:Record.Name~}\" ", | ||
"InputChangeHandler": " onchange=\"_Pict.views['{~D:Context[0].Hash~}'].dataChanged('{~D:Record.Hash~}')\" " | ||
"InputChangeHandler": " onchange=\"_Pict.views['{~D:Context[0].Hash~}'].dataChanged('{~D:Record.Hash~}')\" ", | ||
"DataRequestFunction": " _Pict.views['{~D:Context[0].Hash~}'].inputDataRequest('{~D:Record.Hash~}'); " | ||
} | ||
@@ -34,0 +42,0 @@ }, |
@@ -23,3 +23,3 @@ const libPictViewClass = require('pict-view'); | ||
// Set the default destination address to be based on the section hash if it hasn't been overridden by the manifest section definition | ||
if (tmpOptions.DefaultDestinationAddress == '#Pict-Form-Container') | ||
if (tmpOptions.DefaultDestinationAddress === '#Pict-Form-Container') | ||
{ | ||
@@ -29,3 +29,4 @@ tmpOptions.DefaultDestinationAddress = `#Pict-Form-Container-${tmpOptions.Hash}`; | ||
if (tmpOptions.DefaultRenderable == 'Form-Main') | ||
// Set the default renderable to be based on the section hash if it hasn't been overridden by the manifest section definition | ||
if (tmpOptions.DefaultRenderable === 'Form-Main') | ||
{ | ||
@@ -35,2 +36,3 @@ tmpOptions.DefaultRenderable = `Form-${tmpOptions.Hash}`; | ||
// Set the template hash (which is the section-specific template prefix) if it hasn't been overridden by the manifest section definition | ||
if (!tmpOptions.SectionTemplateHash) | ||
@@ -41,2 +43,3 @@ { | ||
// Create a renderable if none exist | ||
if (tmpOptions.Renderables.length < 1) | ||
@@ -48,3 +51,2 @@ { | ||
TemplateHash: tmpOptions.SectionTemplateHash, | ||
// one of append, prepend, replace or append_once | ||
RenderMethod: 'replace' | ||
@@ -54,2 +56,3 @@ }); | ||
// Now construct the view. | ||
super(pFable, tmpOptions, pServiceHash); | ||
@@ -117,26 +120,95 @@ | ||
// Informary is very old and requires jquery. | ||
// TODO: Refactor informary to be a pict service, eliminating this need entirely. | ||
this.viewMarshalDestination = false; | ||
// Initialize the solver service if it isn't up | ||
this.fable.instantiateServiceProviderIfNotExists('ExpressionParser'); | ||
this.initializeFormGroups(); | ||
} | ||
renderToPrimary() | ||
dataChanged(pInputHash) | ||
{ | ||
// Render to the primary view that the | ||
let tmpDefaultDestinationAddress = (this.pict.views.PictFormMetacontroller) ? this.pict.views.PictFormMetacontroller.options.DefaultDestinationAddress : | ||
this.options.DefaultDestinationAddress; | ||
this.render(this.options.DefaultRenderable, tmpDefaultDestinationAddress); | ||
let tmpInput = this.getInputFromHash(pInputHash); | ||
// This is what is called whenever a hash is changed. We could marshal from view, solve and remarshal to view. | ||
// TODO: Make this more specific to the input hash. Should be trivial with new informary. | ||
if (pInputHash) | ||
{ | ||
// The informary stuff doesn't know the resolution of the hash to address, so do it here. | ||
let tmpHashAddress = this.sectionManifest.resolveHashAddress(pInputHash); | ||
try | ||
{ | ||
let tmpMarshalDestinationObject = this.getMarshalDestinationObject(); | ||
this.pict.providers.Informary.marshalFormToData(tmpMarshalDestinationObject, this.formID, this.sectionManifest, tmpHashAddress); | ||
// Now run any providers connected to this input | ||
if (tmpInput && tmpInput.PictForm && ('Providers' in tmpInput.PictForm) && Array.isArray(tmpInput.PictForm.Providers)) | ||
{ | ||
let tmpValue = this.sectionManifest.getValueByHash(tmpMarshalDestinationObject, tmpHashAddress); | ||
for (let i = 0; i < tmpInput.PictForm.Providers.length; i++) | ||
{ | ||
if (this.pict.providers[tmpInput.PictForm.Providers[i]]) | ||
{ | ||
this.pict.providers[tmpInput.PictForm.Providers[i]].onDataChange(this, tmpInput, tmpValue, tmpInput.Macro.HTMLSelector); | ||
} | ||
else | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] cannot find provider [${tmpInput.PictForm.Providers[i]}] for input [${tmpInput.Hash}].`); | ||
} | ||
} | ||
} | ||
} | ||
catch (pError) | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] gross error marshaling specific (${pInputHash}) data from view in dataChanged event: ${pError}`); | ||
} | ||
} | ||
else | ||
{ | ||
this.marshalFromView(); | ||
} | ||
// Run any dynamic input providers for the input hash. | ||
this.pict.PictApplication.solve(); | ||
this.marshalToView(); | ||
} | ||
dataChanged(pInputHash) | ||
dataChangedTabular(pGroupIndex, pInputIndex, pRowIndex) | ||
{ | ||
// This is what is called whenever a hash is changed. We could marshal from view, solve and remarshal to view. | ||
// TODO: Determine best pattern for allowing others to override this without subclassing this. Maybe a registered provider type? | ||
this.marshalFromView(); | ||
let tmpInput = this.getTabularRecordInput(pGroupIndex, pInputIndex); | ||
if (pGroupIndex && pInputIndex && pRowIndex && tmpInput) | ||
{ | ||
// The informary stuff doesn't know the resolution of the hash to address, so do it here. | ||
let tmpHashAddress = tmpInput.Address; | ||
try | ||
{ | ||
let tmpMarshalDestinationObject = this.getMarshalDestinationObject(); | ||
this.pict.providers.Informary.marshalFormToData(tmpMarshalDestinationObject, this.formID, this.sectionManifest, tmpHashAddress, pRowIndex); | ||
// Now run any providers connected to this input | ||
if (tmpInput && tmpInput.PictForm && ('Providers' in tmpInput.PictForm) && Array.isArray(tmpInput.PictForm.Providers)) | ||
{ | ||
// TODO: Can we simplify this? | ||
let tmpValueAddress = this.pict.providers.Informary.getComposedContainerAddress(tmpInput.PictForm.InformaryContainerAddress, pRowIndex, tmpInput.PictForm.InformaryDataAddress); | ||
let tmpValue = this.sectionManifest.getValueByHash(tmpMarshalDestinationObject, tmpValueAddress); | ||
// Each row has a distinct address! | ||
let tmpVirtualInformaryHTMLSelector = tmpInput.Macro.HTMLSelectorTabular+`[data-i-index="${pRowIndex}"]`; | ||
for (let i = 0; i < tmpInput.PictForm.Providers.length; i++) | ||
{ | ||
if (this.pict.providers[tmpInput.PictForm.Providers[i]]) | ||
{ | ||
this.pict.providers[tmpInput.PictForm.Providers[i]].onDataChangeTabular(this, tmpInput, tmpValue, tmpVirtualInformaryHTMLSelector, pRowIndex); | ||
} | ||
else | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] cannot find provider [${tmpInput.PictForm.Providers[i]}] for input [${tmpInput.Hash}] row ${pRowIndex}.`); | ||
} | ||
} | ||
} | ||
} | ||
catch (pError) | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] gross error marshaling specific (${pInputHash}) tabular data for group ${pGroupIndex} row ${pRowIndex} from view in dataChanged event: ${pError}`); | ||
} | ||
} | ||
else | ||
{ | ||
// This is what is called whenever a hash is changed. We could marshal from view, solve and remarshal to view. | ||
this.marshalFromView(); | ||
} | ||
// Run any dynamic input providers for the input hash. | ||
this.pict.PictApplication.solve(); | ||
@@ -195,7 +267,8 @@ this.marshalToView(); | ||
{ | ||
// TODO: Only marshal data that has changed since the last marshal. Thought experiment: who decides what changes happened? | ||
try | ||
{ | ||
let tmpMarshalDestinationObject = this.getMarshalDestinationObject(); | ||
this.pict.providers.Informary.marshalDataToForm(tmpMarshalDestinationObject, this.formID); | ||
this.pict.providers.Informary.marshalDataToForm(tmpMarshalDestinationObject, this.formID, this.sectionManifest); | ||
this.runInputProviderFunctions('onDataMarshalToForm'); | ||
} | ||
@@ -206,3 +279,2 @@ catch (pError) | ||
} | ||
return super.onMarshalToView(); | ||
@@ -216,4 +288,3 @@ } | ||
let tmpMarshalDestinationObject = this.getMarshalDestinationObject(); | ||
this.pict.providers.Informary.marshalFormToData(tmpMarshalDestinationObject, this.formID); | ||
this.pict.providers.Informary.marshalFormToData(tmpMarshalDestinationObject, this.formID, this.sectionManifest); | ||
} | ||
@@ -238,2 +309,121 @@ catch (pError) | ||
onAfterRender() | ||
{ | ||
this.runInputProviderFunctions('onInputInitialize'); | ||
} | ||
runInputProviderFunctions(pFunctionName) | ||
{ | ||
// Check to see if there are any hooks set from the input templates | ||
for (let i = 0; i < this.sectionDefinition.Groups.length; i++) | ||
{ | ||
let tmpGroup = this.sectionDefinition.Groups[i]; | ||
if (Array.isArray(tmpGroup.Rows)) | ||
{ | ||
for (let j = 0; j < tmpGroup.Rows.length; j++) | ||
{ | ||
// TODO: Do we want row macros? Let's be still and find out. | ||
let tmpRow = tmpGroup.Rows[j]; | ||
for (let k = 0; k < tmpRow.Inputs.length; k++) | ||
{ | ||
let tmpInput = tmpRow.Inputs[k]; | ||
// Now run any providers connected to this input | ||
if (tmpInput && tmpInput.PictForm && ('Providers' in tmpInput.PictForm) && Array.isArray(tmpInput.PictForm.Providers)) | ||
{ | ||
for (let i = 0; i < tmpInput.PictForm.Providers.length; i++) | ||
{ | ||
if (this.pict.providers[tmpInput.PictForm.Providers[i]]) | ||
{ | ||
let tmpHashAddress = this.sectionManifest.resolveHashAddress(tmpInput.Hash); | ||
let tmpValue = this.sectionManifest.getValueByHash(this.getMarshalDestinationObject(), tmpHashAddress); | ||
this.pict.providers[tmpInput.PictForm.Providers[i]][pFunctionName](this, tmpGroup, j, tmpInput, tmpValue, tmpInput.Macro.HTMLSelector); | ||
} | ||
else | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] cannot find provider [${tmpInput.PictForm.Providers[i]}] for input [${tmpInput.Hash}].`); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
if (tmpGroup.supportingManifest) | ||
{ | ||
let tmpSupportingManifestDescriptorKeys = Object.keys(tmpGroup.supportingManifest.elementDescriptors); | ||
for (let k = 0; k < tmpSupportingManifestDescriptorKeys.length; k++) | ||
{ | ||
let tmpTabularRecordSet = this.getTabularRecordSet(tmpGroup.GroupIndex); | ||
// No data in the record set, no events to push to providers. | ||
if (!tmpTabularRecordSet) | ||
{ | ||
continue; | ||
} | ||
let tmpTabularRecordSetLength = 0; | ||
if (Array.isArray(tmpTabularRecordSet)) | ||
{ | ||
let tmpInput = tmpGroup.supportingManifest.elementDescriptors[tmpSupportingManifestDescriptorKeys[k]]; | ||
// Now run any providers connected to this input | ||
if (tmpInput && tmpInput.PictForm && ('Providers' in tmpInput.PictForm)) | ||
{ | ||
for (let i = 0; i < tmpInput.PictForm.Providers.length; i++) | ||
{ | ||
for (let r = 0; r < tmpTabularRecordSet.length; r++) | ||
{ | ||
if (this.pict.providers[tmpInput.PictForm.Providers[i]]) | ||
{ | ||
// There is a provider, we have an input and it is supposed to be run through for a record | ||
let tmpValueAddress = this.pict.providers.Informary.getComposedContainerAddress(tmpInput.PictForm.InformaryContainerAddress, r, tmpInput.PictForm.InformaryDataAddress); | ||
let tmpValue = this.sectionManifest.getValueByHash(this.getMarshalDestinationObject(), tmpValueAddress); | ||
this.pict.providers[tmpInput.PictForm.Providers[i]][pFunctionName+'Tabular'](this, tmpGroup, tmpInput, tmpValue, tmpInput.Macro.HTMLSelectorTabular, r); | ||
} | ||
else | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] cannot find provider [${tmpInput.PictForm.Providers[i]}] for input [${tmpInput.Hash}].`); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
else if (typeof(tmpTabularRecordSet) === 'object') | ||
{ | ||
let tmpRecordSetKeys = Object.keys(tmpTabularRecordSet); | ||
let tmpInput = tmpGroup.supportingManifest.elementDescriptors[tmpSupportingManifestDescriptorKeys[k]]; | ||
// Now run any providers connected to this input | ||
if (tmpInput && tmpInput.PictForm && ('Providers' in tmpInput.PictForm)) | ||
{ | ||
for (let i = 0; i < tmpInput.PictForm.Providers.length; i++) | ||
{ | ||
for (let r = 0; r < tmpRecordSetKeys.length; r++) | ||
{ | ||
if (this.pict.providers[tmpInput.PictForm.Providers[i]]) | ||
{ | ||
// There is a provider, we have an input and it is supposed to be run through for a record | ||
let tmpValueAddress = this.pict.providers.Informary.getComposedContainerAddress(tmpInput.PictForm.InformaryContainerAddress, tmpRecordSetKeys[r], tmpInput.PictForm.InformaryDataAddress); | ||
let tmpValue = this.sectionManifest.getValueByHash(this.getMarshalDestinationObject(), tmpValueAddress); | ||
this.pict.providers[tmpInput.PictForm.Providers[i]][pFunctionName+'Tabular'](this, tmpGroup, tmpInput, tmpValue, tmpInput.Macro.HTMLSelectorTabular, tmpRecordSetKeys[r]); | ||
} | ||
else | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] cannot find provider [${tmpInput.PictForm.Providers[i]}] for input [${tmpInput.Hash}].`); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
onAfterMarshalToForm() | ||
{ | ||
// Check to see if there are any hooks set from the input templates | ||
this.runInputProviderFunctions('onAfterMarshalToForm'); | ||
} | ||
initializeFormGroups() | ||
@@ -428,3 +618,3 @@ { | ||
// This is here to cut down on complex guards, and, so we can optimize/extend it later if we need to. | ||
return (`${this.formsTemplateSetPrefix}${pTemplatePostfix}` in this.pict.TemplateProvider.templates) | ||
return (`${this.formsTemplateSetPrefix}${pTemplatePostfix}` in this.pict.TemplateProvider.templates); | ||
} | ||
@@ -435,3 +625,3 @@ | ||
// This is here to cut down on complex guards, and, so we can optimize/extend it later if we need to. | ||
return (`${this.defaultTemplatePrefix}${pTemplatePostfix}` in this.pict.TemplateProvider.templates) | ||
return (`${this.defaultTemplatePrefix}${pTemplatePostfix}` in this.pict.TemplateProvider.templates); | ||
} | ||
@@ -444,3 +634,3 @@ | ||
{ | ||
return `\n{~T:${this.formsTemplateSetPrefix}${pTemplatePostfix}:${pRawTemplateDataAddress}~}` | ||
return `\n{~T:${this.formsTemplateSetPrefix}${pTemplatePostfix}:${pRawTemplateDataAddress}~}`; | ||
} | ||
@@ -450,3 +640,3 @@ // 2. Check if there is a theme-specific template loaded for this postfix | ||
{ | ||
return `\n{~T:${this.defaultTemplatePrefix}${pTemplatePostfix}:${pRawTemplateDataAddress}~}` | ||
return `\n{~T:${this.defaultTemplatePrefix}${pTemplatePostfix}:${pRawTemplateDataAddress}~}`; | ||
} | ||
@@ -493,9 +683,11 @@ // 3. This shouldn't happen if the template is based on the base class. | ||
getTabularInputMetatemplateTemplateReference(pDataType, pInputType, pViewDataAddress, pRecordSubAddress) | ||
getTabularInputMetatemplateTemplateReference(pDataType, pInputType, pViewDataAddress, pGroupIndex, pRowIndex) | ||
{ | ||
// Input types are customizable -- there could be 30 different input types for the string data type with special handling and templates | ||
let tmpTemplateBeginInputTypePostfix = `-TabularTemplate-Begin-Input-InputType-${pInputType}`; | ||
let tmpTemplateMidInputTypePostfix = `-TabularTemplate-Mid-Input-InputType-${pInputType}`; | ||
let tmpTemplateEndInputTypePostfix = `-TabularTemplate-End-Input-InputType-${pInputType}`; | ||
// Data types are not customizable; they are a fixed list based on what is available in Manyfest | ||
let tmpTemplateBeginDataTypePostfix = `-TabularTemplate-Begin-Input-DataType-${pDataType}`; | ||
let tmpTemplateMidDataTypePostfix = `-TabularTemplate-Mid-Input-DataType-${pDataType}`; | ||
let tmpTemplateEndDataTypePostfix = `-TabularTemplate-End-Input-DataType-${pDataType}`; | ||
@@ -506,3 +698,4 @@ | ||
// This means it is easily extensible to work on JSON objects as well as arrays. | ||
let tmpAddressTemplate = ` data-i-index="{~D:Record.Key~}" `; | ||
let tmpMidTemplate = this.getMetatemplateTemplateReference('-TabularTemplate-Mid-Input', pViewDataAddress, pGroupIndex, pRowIndex); | ||
let tmpInformaryDataAddressTemplate = this.getMetatemplateTemplateReference('-TabularTemplate-InformaryAddress-Input', pViewDataAddress, pGroupIndex, pRowIndex); | ||
@@ -514,5 +707,7 @@ // First check if there is an "input type" template available in either the section-specific configuration or in the general | ||
let tmpEndTemplate = this.getMetatemplateTemplateReference(tmpTemplateEndInputTypePostfix, pViewDataAddress); | ||
let tmpCustomMidTemplate = this.getMetatemplateTemplateReference(tmpTemplateMidInputTypePostfix, pViewDataAddress, pGroupIndex, pRowIndex); | ||
tmpMidTemplate = (tmpCustomMidTemplate) ? tmpCustomMidTemplate : tmpMidTemplate; | ||
if (tmpBeginTemplate && tmpEndTemplate) | ||
{ | ||
return tmpBeginTemplate + tmpAddressTemplate + tmpEndTemplate; | ||
return tmpBeginTemplate + tmpMidTemplate + tmpInformaryDataAddressTemplate + tmpEndTemplate; | ||
} | ||
@@ -526,3 +721,5 @@ } | ||
{ | ||
return tmpBeginTemplate + tmpAddressTemplate + tmpEndTemplate; | ||
let tmpCustomMidTemplate = this.getMetatemplateTemplateReference(tmpTemplateMidDataTypePostfix, pViewDataAddress, pGroupIndex, pRowIndex); | ||
tmpMidTemplate = (tmpCustomMidTemplate) ? tmpCustomMidTemplate : tmpMidTemplate; | ||
return tmpBeginTemplate + tmpMidTemplate + tmpInformaryDataAddressTemplate + tmpEndTemplate; | ||
} | ||
@@ -537,7 +734,7 @@ | ||
{ | ||
return tmpBeginTemplate + tmpAddressTemplate + tmpEndTemplate; | ||
return tmpBeginTemplate + tmpMidTemplate + tmpInformaryDataAddressTemplate + tmpEndTemplate; | ||
} | ||
// There was some kind of catastrophic failure -- the above templates should always be loaded. | ||
this.log.error(`PICT Form [${this.UUID}]::[${this.Hash}] catastrophic error generating tabular metatemplate: missing input template for Data Type ${pDataType} and Input Type ${pInputType}, Data Address ${pViewDataAddress} and Record Subaddress ${pRecordSubAddress}}.`) | ||
this.log.error(`PICT Form [${this.UUID}]::[${this.Hash}] catastrophic error generating tabular metatemplate: missing input template for Data Type ${pDataType} and Input Type ${pInputType}, Data Address ${pViewDataAddress}, Group Index ${pGroupIndex} and Record Subaddress ${pRowIndex}}.`) | ||
return ''; | ||
@@ -600,4 +797,2 @@ } | ||
tmpTemplateSetRecordRowTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-Row-Prefix`, `getGroup("${i}")`); | ||
for (let j = 0; j < tmpGroup.Rows.length; j++) | ||
@@ -621,2 +816,5 @@ { | ||
let tmpInput = tmpGroup.supportingManifest.elementDescriptors[tmpSupportingManifestHash]; | ||
// Update the InputIndex to match the current render config | ||
tmpInput.PictForm.InputIndex = k; | ||
tmpInput.PictForm.GroupIndex = tmpGroup.GroupIndex; | ||
@@ -628,6 +826,7 @@ tmpTemplate += this.getMetatemplateTemplateReference('-TabularTemplate-HeaderCell', `getTabularRecordInput("${i}","${k}")`); | ||
let tmpInputType = (('PictForm' in tmpInput) && tmpInput.PictForm.InputType) ? tmpInput.PictForm.InputType : 'Default'; | ||
tmpTemplateSetRecordRowTemplate += this.getTabularInputMetatemplateTemplateReference(tmpInput.DataType, tmpInputType, `getTabularRecordInput("${i}","${k}")`, k); | ||
tmpTemplateSetRecordRowTemplate += this.getTabularInputMetatemplateTemplateReference(tmpInput.DataType, tmpInputType, `getTabularRecordInput("${i}","${k}")`, i, k); | ||
tmpTemplateSetRecordRowTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-Cell-Postfix`, `getTabularRecordInput("${i}","${k}")`); | ||
} | ||
} | ||
tmpTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-RowHeader-ExtraPostfix`, `getGroup("${i}")`); | ||
@@ -640,5 +839,7 @@ tmpTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-RowHeader-Postfix`, `getGroup("${i}")`); | ||
let tmpTemplateSetVirtualRowTemplate = ''; | ||
tmpTemplateSetVirtualRowTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-Row-Prefix`, `getGroup("${i}")`); | ||
tmpTemplateSetVirtualRowTemplate += this.getMetatemplateTemplateReferenceRaw(`-TabularTemplate-Row-ExtraPrefix`, `Record`); | ||
tmpTemplateSetVirtualRowTemplate += `\n\n{~T:${tmpGroup.SectionTabularRowTemplateHash}:Record~}\n`; | ||
tmpTemplateSetVirtualRowTemplate += this.getMetatemplateTemplateReferenceRaw(`-TabularTemplate-Row-ExtraPostfix`, `Record`); | ||
tmpTemplateSetVirtualRowTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-Row-Postfix`, `getGroup("${i}")`); | ||
@@ -666,2 +867,5 @@ // This is a custom template expression | ||
let tmpInput = tmpRow.Inputs[k]; | ||
// Update the InputIndex to match the current render config | ||
tmpInput.PictForm.InputIndex = k; | ||
tmpInput.PictForm.GroupIndex = tmpGroup.GroupIndex; | ||
@@ -961,2 +1165,7 @@ tmpTemplate += this.getInputMetatemplateTemplateReference(tmpInput.DataType, tmpInput.PictForm.InputType, `getInput("${i}","${j}","${k}")`); | ||
getInputFromHash(pInputHash) | ||
{ | ||
return this.sectionManifest.getDescriptorByHash(pInputHash); | ||
} | ||
getInput(pGroupIndex, pRowIndex, pInputIndex) | ||
@@ -986,2 +1195,81 @@ { | ||
inputDataRequest(pInputHash) | ||
{ | ||
let tmpInput = this.getInputFromHash(pInputHash); | ||
if (pInputHash) | ||
{ | ||
let tmpHashAddress = this.sectionManifest.resolveHashAddress(pInputHash); | ||
try | ||
{ | ||
let tmpMarshalDestinationObject = this.getMarshalDestinationObject(); | ||
if (tmpInput && tmpInput.PictForm && ('Providers' in tmpInput.PictForm) && Array.isArray(tmpInput.PictForm.Providers)) | ||
{ | ||
let tmpValue = this.sectionManifest.getValueByHash(tmpMarshalDestinationObject, tmpHashAddress); | ||
for (let i = 0; i < tmpInput.PictForm.Providers.length; i++) | ||
{ | ||
if (this.pict.providers[tmpInput.PictForm.Providers[i]]) | ||
{ | ||
this.pict.providers[tmpInput.PictForm.Providers[i]].onDataRequest(this, tmpInput, tmpValue, tmpInput.Macro.HTMLSelector); | ||
} | ||
else | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] inputDataRequest cannot find provider [${tmpInput.PictForm.Providers[i]}] for input [${tmpInput.Hash}].`); | ||
} | ||
} | ||
} | ||
} | ||
catch (pError) | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] gross error running inputDataRequest specific (${pInputHash}) data from view in dataChanged event: ${pError}`); | ||
} | ||
} | ||
else | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] cannot find input hash [${pInputHash}] for inputDataRequest event.`); | ||
} | ||
} | ||
inputDataRequestTabular(pGroupIndex, pInputIndex, pRowIndex) | ||
{ | ||
let tmpInput = this.getTabularRecordInput(pGroupIndex, pInputIndex); | ||
if (pGroupIndex && pInputIndex && pRowIndex && tmpInput) | ||
{ | ||
try | ||
{ | ||
let tmpMarshalDestinationObject = this.getMarshalDestinationObject(); | ||
if (tmpInput && tmpInput.PictForm && ('Providers' in tmpInput.PictForm) && Array.isArray(tmpInput.PictForm.Providers)) | ||
{ | ||
// TODO: Can we simplify this? | ||
let tmpValueAddress = this.pict.providers.Informary.getComposedContainerAddress(tmpInput.PictForm.InformaryContainerAddress, pRowIndex, tmpInput.PictForm.InformaryDataAddress); | ||
let tmpValue = this.sectionManifest.getValueByHash(tmpMarshalDestinationObject, tmpValueAddress); | ||
let tmpVirtualInformaryHTMLSelector = tmpInput.Macro.HTMLSelectorTabular+`[data-i-index="${pRowIndex}"]`; | ||
for (let i = 0; i < tmpInput.PictForm.Providers.length; i++) | ||
{ | ||
if (this.pict.providers[tmpInput.PictForm.Providers[i]]) | ||
{ | ||
this.pict.providers[tmpInput.PictForm.Providers[i]].onDataRequestTabular(this, tmpInput, tmpValue, tmpVirtualInformaryHTMLSelector, pRowIndex); | ||
} | ||
else | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] cannot find provider [${tmpInput.PictForm.Providers[i]}] for input [${tmpInput.Hash}] row ${pRowIndex}.`); | ||
} | ||
} | ||
} | ||
} | ||
catch (pError) | ||
{ | ||
this.log.error(`Dynamic form [${this.Hash}]::[${this.UUID}] gross error marshaling specific (${pInputHash}) tabular data for group ${pGroupIndex} row ${pRowIndex} from view in dataChanged event: ${pError}`); | ||
} | ||
} | ||
else | ||
{ | ||
// This is what is called whenever a hash is changed. We could marshal from view, solve and remarshal to view. | ||
this.marshalFromView(); | ||
} | ||
// Run any dynamic input providers for the input hash. | ||
this.pict.PictApplication.solve(); | ||
this.marshalToView(); | ||
} | ||
get isPictSectionForm() | ||
@@ -988,0 +1276,0 @@ { |
const libPictViewClass = require('pict-view'); | ||
const libDynamicSolver = require('../providers/Pict-Provider-DynamicSolver.js'); | ||
@@ -73,6 +74,7 @@ | ||
{ | ||
this.regenerateFormSectionTemplates(); | ||
this.renderFormSections(); | ||
if (this.options.AutoPopulateAfterRender) | ||
{ | ||
this.regenerateFormSectionTemplates(); | ||
this.renderFormSections(); | ||
this.marshalToView(); | ||
@@ -79,0 +81,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
6582012
287
93481
Updatedpict-template@^1.0.2