Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pict-section-form

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pict-section-form - npm Package Compare versions

Comparing version 1.0.5 to 1.0.6

doc/code_wasteland/Application-Snippets.md

6

example_applications/postcard_example/Pict-Application-Postcard.js

@@ -47,3 +47,3 @@ const libPictApplication = require('pict-application');

onAfterInitialize()
onAfterInitializeAsync(fCallback)
{

@@ -54,3 +54,7 @@ // Set a custom address for all the views to marshal to.

this.pict.views.PostcardNavigation.render()
this.pict.views.PostcardMainApplication.render();
this.pict.views.PictFormMetacontroller.render();
return super.onAfterInitialize(fCallback);
}

@@ -57,0 +61,0 @@

25

example_applications/postcard_example/providers/PictProvider-Dynamic-Sections-MockServerResponse.json

@@ -25,14 +25,15 @@ {

"Description": "The content and destination for the postcard you would like to send.",
"Groups": [
{
"Name": "Content",
"Hash": "Content",
"Description": "The message and recipient of your postcard."
},
{
"Name": "Delivery Destination",
"Hash": "Destination",
"Description": "The message and recipient of your postcard."
}
]
"Groups":
[
{
"Name": "Content",
"Hash": "Content",
"Description": "The message and recipient of your postcard."
},
{
"Name": "Delivery Destination",
"Hash": "Destination",
"Description": "The message and recipient of your postcard."
}
]
},

@@ -39,0 +40,0 @@ {

@@ -26,3 +26,3 @@ const libPictProvider = require('pict-provider');

return fCallback();
return super.onInitializeAsync(fCallback);
}

@@ -29,0 +29,0 @@ }

@@ -7,3 +7,3 @@ {

"RenderOnLoad": false,
"AutoRender": false,

@@ -10,0 +10,0 @@ "Templates": [

@@ -7,3 +7,3 @@ {

"RenderOnLoad": false,
"AutoRender": false,

@@ -10,0 +10,0 @@ "Templates": [

@@ -10,3 +10,3 @@ const libPictView = require('pict-view');

RenderOnLoad: true,
AutoRender: true,

@@ -46,2 +46,8 @@ CSS: ".PostcardControls { margin-top: 2em; background-color: #fff5f5; }",

onAfterInitialize()
{
this.pict.views.PostcardNavigation.render()
return super.onAfterInitialize();
}
onAfterRender()

@@ -52,2 +58,4 @@ {

this.pict.PictApplication.marshalDataFromAppDataToView();
return super.onAfterRender();
//return super.onAfterRenderAsync(fCallback);
}

@@ -54,0 +62,0 @@ }

@@ -7,3 +7,3 @@ {

"RenderOnLoad": true,
"AutoRender": true,

@@ -10,0 +10,0 @@ "CSS": ".PostcardNavigation { background-color: #fff5f5; }",

@@ -9,3 +9,3 @@ const libPictSectionForm = require('../../source/Pict-Section-Form.js');

{
"Product": "PictDefaultFormsApp",
"Product": "Simple",
"DefaultFormManifest":

@@ -59,3 +59,4 @@ {

"Hash":"Name",
"DataType":"Number"
"DataType":"Number",
"Default": 100
,"PictForm": { "Section":"Area", "Row":2, "Width":1 }

@@ -67,3 +68,4 @@ },

"Hash":"Type",
"DataType":"Number"
"DataType":"Number",
"Default": 100
,"PictForm": { "Section":"Area", "Row":2, "Width":1 }

@@ -81,3 +83,3 @@ },

{
"Name":"Area of Width Cubed",
"Name":"Area of Height Cubed",
"Hash":"HeightCubeArea",

@@ -84,0 +86,0 @@ "DataType":"String"

{
"name": "pict-section-form",
"version": "1.0.5",
"version": "1.0.6",
"description": "Pict dynamic form sections",

@@ -28,10 +28,10 @@ "main": "source/Pict-Section-Form.js",

"browser-env": "^3.3.0",
"pict": "^1.0.178",
"pict-application": "^1.0.15",
"jquery": "^3.7.1",
"pict": "^1.0.183",
"pict-application": "^1.0.17",
"quackage": "^1.0.29"
},
"dependencies": {
"informary": "^2.0.21",
"pict-provider": "^1.0.2",
"pict-view": "^1.0.45"
"pict-view": "^1.0.46"
},

@@ -38,0 +38,0 @@ "mocha": {

@@ -30,2 +30,4 @@ # PICT Forms Section

A tooltip, hover or other kinds of embedded content/help on an input element.
8. Macro:
A small bit of template that's preprocessed and usable by the template partials.

@@ -32,0 +34,0 @@

@@ -61,7 +61,3 @@ const libPictViewClass = require('pict-view');

// Right now this doesn't work with async templates and is intentionally so
// We don't want heavy loading/lifting in the forms controls; if a use case comes up this can change
this.render();
return super.onAfterInitialize(fCallback);
return super.onAfterInitializeAsync(fCallback);
}

@@ -71,4 +67,8 @@

{
this.regenerateAllFormSectionTemplates();
this.renderAllFormSections();
if (this.options.AutoPopulateAfterRender)
{
this.regenerateAllFormSectionTemplates();
this.renderAllFormSections();
this.marshalToView();
}

@@ -190,8 +190,8 @@ return super.onAfterRender();

bootstrapPictFormViewsFromManifest(pManifest)
bootstrapPictFormViewsFromManifest(pManifestDescription)
{
let tmpManifest = pManifest;
let tmpManifestDescription = (typeof(pManifestDescription) === 'object') ? pManifestDescription : false;
let tmpSectionList = [];
if (typeof(tmpManifest) != 'object')
if (typeof(tmpManifestDescription) != 'object')
{

@@ -203,3 +203,3 @@ // Check and see if there is a DefaultFormManifest in the settings

{
tmpManifest = this.fable.settings.DefaultFormManifest;
tmpManifestDescription = this.fable.settings.DefaultFormManifest;
}

@@ -213,8 +213,20 @@ else

let tmpManifest = this.fable.instantiateServiceProviderWithoutRegistration('Manifest', tmpManifestDescription);
if (this.options.AutoPopulateDefaultObject)
{
// Fill out the defaults at the marshal location if it doesn't exist
let tmpMarshalDestinationObject = tmpManifest.getValueAtAddress(this, this.viewMarshalDestination);
if (typeof(tmpMarshalDestinationObject) === 'object')
{
tmpManifest.populateDefaults(tmpMarshalDestinationObject);
}
}
// Get the list of Explicitly Defined section hashes from the Sections property of the manifest
if (tmpManifest.hasOwnProperty('Sections') && Array.isArray(tmpManifest.Sections))
if (tmpManifestDescription.hasOwnProperty('Sections') && Array.isArray(tmpManifestDescription.Sections))
{
for (let i = 0; i < tmpManifest.Sections.length; i++)
for (let i = 0; i < tmpManifestDescription.Sections.length; i++)
{
let tmpSectionDefinition = this.getSectionDefinition(tmpManifest.Sections[i]);
let tmpSectionDefinition = this.getSectionDefinition(tmpManifestDescription.Sections[i]);

@@ -228,40 +240,36 @@ if (tmpSectionDefinition)

// Check if there are any implicitly defined section hashes in the manifest descriptors
if (tmpManifest.hasOwnProperty('Descriptors') && typeof(tmpManifest.Descriptors) == 'object')
let tmpImplicitSectionHashes = {};
let tmpDescriptorKeys = Object.keys(tmpManifest.elementDescriptors);
for (let i = 0; i < tmpDescriptorKeys.length; i++)
{
let tmpImplicitSectionHashes = {};
let tmpDescriptor = tmpManifest.elementDescriptors[tmpDescriptorKeys[i]];
let tmpDescriptorKeys = Object.keys(tmpManifest.Descriptors);
for (let i = 0; i < tmpDescriptorKeys.length; i++)
if (
// If there is an object in the descriptor
typeof(tmpDescriptor) == 'object' &&
// AND it has a PictForm property
tmpDescriptor.hasOwnProperty('PictForm') &&
// AND the PictForm property is an object
typeof(tmpDescriptor.PictForm) == 'object' &&
// AND the PictForm object has a Section property
tmpDescriptor.PictForm.hasOwnProperty('Section') &&
// AND the Section property is a string
typeof(tmpDescriptor.PictForm.Section) == 'string'
)
{
let tmpDescriptor = tmpManifest.Descriptors[tmpDescriptorKeys[i]];
if (
// If there is an obect in the descriptor
typeof(tmpDescriptor) == 'object' &&
// AND it has a PictForm property
tmpDescriptor.hasOwnProperty('PictForm') &&
// AND the PictForm property is an object
typeof(tmpDescriptor.PictForm) == 'object' &&
// AND the PictForm object has a Section property
tmpDescriptor.PictForm.hasOwnProperty('Section') &&
// AND the Section property is a string
typeof(tmpDescriptor.PictForm.Section) == 'string'
)
{
tmpImplicitSectionHashes[tmpDescriptor.PictForm.Section] = true;
}
tmpImplicitSectionHashes[tmpDescriptor.PictForm.Section] = true;
}
}
let tmpImplicitSectionKeys = Object.keys(tmpImplicitSectionHashes);
let tmpImplicitSectionKeys = Object.keys(tmpImplicitSectionHashes);
for (let i = 0; i < tmpImplicitSectionKeys.length; i++)
for (let i = 0; i < tmpImplicitSectionKeys.length; i++)
{
let tmpExistingSection = tmpSectionList.find((pSection) => { return pSection.Hash == tmpImplicitSectionKeys[i]; });
if (!tmpExistingSection)
{
let tmpExistingSection = tmpSectionList.find((pSection) => { return pSection.Hash == tmpImplicitSectionKeys[i]; });
if (!tmpExistingSection)
{
tmpSectionList.push(this.getSectionDefinition({Hash: tmpImplicitSectionKeys[i]}));
}
tmpSectionList.push(this.getSectionDefinition({Hash: tmpImplicitSectionKeys[i]}));
}

@@ -285,3 +293,3 @@ }

}
tmpViewConfiguration.Manifests.Section = tmpManifest;
tmpViewConfiguration.Manifests.Section = tmpManifestDescription;
tmpViewConfiguration.AutoMarshalDataOnSolve = this.options.AutoMarshalDataOnSolve;

@@ -296,2 +304,29 @@ this.fable.addView(tmpViewHash, tmpViewConfiguration, require('./Pict-Section-Form-View.js'));

module.exports = PictFormMetacontroller;
module.exports.default_configuration = require('./Pict-Form-Metacontroller-DefaultConfiguration.json');
module.exports.default_configuration = (
{
"AutoRender": true,
"AutoPopulateDefaultObject": true,
"AutoPopulateAfterRender": true,
"DefaultRenderable": "Pict-Forms-Metacontainer",
"DefaultDestinationAddress": "#Pict-Form-Container",
"AutoMarshalDataOnSolve": true,
"MetaTemplateHash": "Pict-Forms-Metatemplate",
"Templates": [
{
"Hash": "Pict-Forms-Metatemplate",
"Template": "<!-- Pict-Forms-Metatemplate HAS NOT BEEN GENERATED; call pict.views.PictFormsMetatemplate.generateMetatemplate() to build the containers -->"
}
],
"Renderables": [
{
"RenderableHash": "Pict-Forms-Metacontainer",
"TemplateHash": "Pict-Forms-Metatemplate",
"DestinationAddress": "#Pict-Form-Container"
}
]
});

@@ -6,2 +6,7 @@ module.exports = (

"Templates":[
/*
*
* [ Metacontroller Templates ]
*
*/
// -Form-Container-Header

@@ -19,5 +24,5 @@ {

Glug glug glug
Glug glug glug Oo...
-->
<div id="Pict-{~D:Context[0].UUID~}-FormContainer~}" class="pict-form">`
<div id="Pict-{~D:Context[0].UUID~}-FormContainer" class="pict-form">`
},

@@ -30,5 +35,6 @@

<!-- Pict Form Metacontroller container [{~D:Context[0].UUID~}] -->
<div id="Pict-{~D:Context[0].UUID~}-FormContainer~}" class="pict-form">`
<div id="Pict-{~D:Context[0].UUID~}-FormContainer" class="pict-form">`
},
// -Form-Container
// This is the DIV each section (view) renders into.
{

@@ -52,2 +58,7 @@ "HashPostfix": "-Template-Form-Container",

/*
*
* [ Section Wrap Templates ]
*
*/
// -Form-Template-Wrap-Prefix

@@ -88,2 +99,7 @@ {

/*
*
* [ Group and Row Templates (default) ]
*
*/
// -Form-Template-Group-Prefix

@@ -95,13 +111,5 @@ {

<h3>Group: {~D:Record.Name~}</h3>
<div>
`
},
// -Form-Template-Group-Postfix
{
"HashPostfix": "-Template-Group-Postfix",
"Template": /*HTML*/`
</div>
<!-- Form Template Group Prefix [{~D:Context[0].UUID~}]::[{~D:Context[0].Hash~}] {~D:Record.Hash~}::{~D:Record.Name~} -->
`
},
// -Form-Template-Row-Prefix

@@ -115,3 +123,3 @@ {

},
// -Form-Template-Group-Postfix
// -Form-Template-Row-Postfix
{

@@ -124,3 +132,17 @@ "HashPostfix": "-Template-Row-Postfix",

},
// -Form-Template-Group-Postfix
{
"HashPostfix": "-Template-Group-Postfix",
"Template": /*HTML*/`
</div>
<!-- Form Template Group Prefix [{~D:Context[0].UUID~}]::[{~D:Context[0].Hash~}] {~D:Record.Hash~}::{~D:Record.Name~} -->
`
},
/*
*
* [ Input Templates (Default) ]
*
*/
// -Form-Template-Input

@@ -130,4 +152,4 @@ {

"Template": /*HTML*/`
<!-- Input {~"D:Record.Hash~} {~D:Record.DataType~} -->
<span style="background-color:#fffdfd;">{~D:Record.Name~}:</span> <input type="text" {~D:Record.PictForm.HTMLInputFullProperties~} value="">
<!-- DEFAULT Input {~"D:Record.Hash~} {~D:Record.DataType~} -->
<span>{~D:Record.Name~}:</span> <input type="text" {~D:Record.Macro.InputFullProperties~} value="">
`

@@ -140,3 +162,3 @@ },

<!-- DataType Number {~D:Record.Hash~} {~D:Record.DataType~} -->
<span>{~D:Record.Name~}:</span> <input type="text" {~D:Record.PictForm.HTMLInputFullProperties~} value="">
<span>{~D:Record.Name~}:</span> <input type="text" {~D:Record.Macro.InputFullProperties~} value="">
`

@@ -149,3 +171,3 @@ },

<!-- DataType Number {~D:Record.Hash~} {~D:Record.DataType~} -->
<span>{~D:Record.Name~}:</span> <input type="Number" {~D:Record.PictForm.HTMLInputFullProperties~} value="">
<span>{~D:Record.Name~}:</span> <input type="Number" {~D:Record.Macro.InputFullProperties~} {~D:Record.Macro.InputChangeHandler~} value="">
`

@@ -158,6 +180,161 @@ },

<!-- InputType TextArea {~D:Record.Hash~} {~D:Record.DataType~} -->
<span>{~D:Record.Name~}:</span> <textarea {~D:Record.PictForm.HTMLInputFullProperties~}></textarea>
<span>{~D:Record.Name~}:</span> <textarea {~D:Record.Macro.InputFullProperties~}></textarea>
`
},
/*
*
* [ Tabular Templates ]
*
*/
{
"HashPostfix": "-TabularTemplate-Group-Prefix",
"Template": /*HTML*/`
<div>
<table>
<tbody>
<!-- Form Template Group Prefix [{~D:Context[0].UUID~}]::[{~D:Context[0].Hash~}] {~D:Record.Hash~}::{~D:Record.Name~} -->
`
},
// These templates are meant to be an easily overridable "add buttons to the row" template.
{
"HashPostfix": "-TabularTemplate-RowHeader-ExtraPrefix",
"Template": /*HTML*/`<!-- TabularTemplateRowHeader-ExtraPrefix -->`
},
{
"HashPostfix": "-TabularTemplate-Row-ExtraPrefix",
"Template": /*HTML*/`<!-- TabularTemplateRow-ExtraPrefix -->`
},
{
"HashPostfix": "-TabularTemplate-RowHeader-ExtraPostfix",
"Template": /*HTML*/`<!-- TabularTemplateRowHeader-ExtraPostfix -->`
},
{
"HashPostfix": "-TabularTemplate-Row-ExtraPostfix",
"Template": /*HTML*/`<!-- TabularTemplateRow-ExtraPostfix -->`
},
{
"HashPostfix": "-TabularTemplate-RowHeader-Prefix",
"Template": /*HTML*/`
<thead>
<tr>{~T:TabularTemplateRowHeader-ExtraPrefix~}
`
},
{
"HashPostfix": "-TabularTemplate-HeaderCell",
"Template": /*HTML*/`
<!-- Descriptor {~D:Record.Name~} [{~D:Record.Hash~}] -> {~D:Record.Address~} -->
<th>{~D:Record.Name~}</th>
`
},
{
"HashPostfix": "-TabularTemplate-RowHeader-Postfix",
"Template": /*HTML*/`
{~T:TabularTemplateRowHeader-ExtraPostfix~}</tr>
</thead>
<tbody>
`
},
/*
*
* BEGINNING of the Tabular TemplateSet metatemplate entries
*
*/
{
"HashPostfix": "-TabularTemplate-Row-Prefix",
"Template": /*HTML*/`
<tr>{~T:TabularTemplateRow-ExtraPrefix~}
`
},
{
"HashPostfix": "-TabularTemplate-Cell-Prefix",
"Template": /*HTML*/`
<td><!-- {~D:Record.Name~} -->
`
},
{
"HashPostfix": "-TabularTemplate-Cell-Postfix",
"Template": /*HTML*/`
</td>
`
},
{
"HashPostfix": "-TabularTemplate-Row-Postfix",
"Template": /*HTML*/`
{~T:TabularTemplateRow-ExtraPostfix~}</tr>`
},
/*
*
* END of the above Tabular TemplateSet metatemplate entries
*
*/
{
"HashPostfix": "-TabularTemplate-Group-Postfix",
"Template": /*HTML*/`
</tbody>
</table>
</div>
<!-- Form Template Group Prefix [{~D:Context[0].UUID~}]::[{~D:Context[0].Hash~}] {~D:Record.Hash~}::{~D:Record.Name~} -->
`
},
/*
*
* Input Templates (tabular)
*
*/
{
"HashPostfix": "-TabularTemplate-Begin-Input",
"Template": /*HTML*/`
<!-- DEFAULT Input {~"D:Record.Hash~} {~D:Record.DataType~} -->
<input type="text" {~D:Record.Macro.HTMLName~} {~D:Record.Macro.InformaryTabular~} `
},
{
"HashPostfix": "-TabularTemplate-End-Input",
"Template": /*HTML*/` value="">`
},
{
"HashPostfix": "-TabularTemplate-Begin-Input-DataType-String",
"Template": /*HTML*/`
<!-- DataType Number {~D:Record.Hash~} {~D:Record.DataType~} -->
<input type="text" {~D:Record.Macro.HTMLName~} {~D:Record.Macro.InformaryTabular~} `
},
{
"HashPostfix": "-TabularTemplate-End-Input-DataType-String",
"Template": /*HTML*/` value="">`
},
{
"HashPostfix": "-TabularTemplate-Begin-Input-DataType-Number",
"Template": /*HTML*/`
<!-- DataType Number {~D:Record.Hash~} {~D:Record.DataType~} -->
<input type="Number" {~D:Record.Macro.HTMLName~} {~D:Record.Macro.InformaryTabular~} `
},
{
"HashPostfix": "-TabularTemplate-End-Input-DataType-Number",
"Template": /*HTML*/` {~D:Record.Macro.InputChangeHandler~} value="">
`
},
{
"HashPostfix": "-TabularTemplate-Begin-Input-InputType-TextArea",
"Template": /*HTML*/`
<!-- InputType TextArea {~D:Record.Hash~} {~D:Record.DataType~} -->
<textarea {~D:Record.Macro.HTMLName~} {~D:Record.Macro.InformaryTabular~} `
},
{
"HashPostfix": "-TabularTemplate-End-Input-InputType-TextArea",
"Template": /*HTML*/`></textarea>
`
}
]
});
const libPictProvider = require('pict-provider');
const defaultFormTemplates = require('./Pict-Section-Form-Provider-Templates-DefaultFormTemplates.js');
const _DefaultFormTemplates = require('./Pict-Section-Form-Provider-Templates-DefaultFormTemplates.js');
const _DefaultProviderConfiguration = (
{
"ProviderIdentifier": "Pict-Section-Form-Provider-Templates-Basic",
"AutoInitialize": true,
"AutoInitializeOrdinal": 0,
"AutoSolveWithApp": false
});
class PictSectionFormTemplateProvider extends libPictProvider

@@ -9,3 +18,3 @@ {

{
let tmpOptions = Object.assign({}, JSON.parse(JSON.stringify(require('./Pict-Section-Form-Provider-Templates-DefaultConfiguration.json'))), pOptions);
let tmpOptions = Object.assign({}, JSON.parse(JSON.stringify(_DefaultProviderConfiguration)), pOptions);

@@ -15,3 +24,3 @@ // This is all you're expected to overload in this provider

{
tmpOptions.MetaTemplateSet = JSON.parse(JSON.stringify(defaultFormTemplates));
tmpOptions.MetaTemplateSet = JSON.parse(JSON.stringify(_DefaultFormTemplates));
}

@@ -27,3 +36,3 @@

// The default template prefix is 'Pict-Forms-Basic'
this.formsTemplateSetPrefix = defaultFormTemplates.TemplatePrefix;
this.formsTemplateSetPrefix = _DefaultFormTemplates.TemplatePrefix;
}

@@ -56,5 +65,5 @@ else if (!this.options.MetaTemplateSet.hasOwnProperty('TemplatePrefix') && (this.options.ProviderIdentifier != 'Pict-Section-Form-Provider-Templates-Basic'))

for (let i = 0; i < defaultFormTemplates.Templates.length; i++)
for (let i = 0; i < _DefaultFormTemplates.Templates.length; i++)
{
let tmpTemplate = defaultFormTemplates.Templates[i];
let tmpTemplate = _DefaultFormTemplates.Templates[i];
let tmpTemplateHash = `${this.formsTemplateSetPrefix}${tmpTemplate.HashPostfix}`;

@@ -82,4 +91,2 @@ // Only load default templates if they are not already defined in the options

module.exports = PictSectionFormTemplateProvider;
module.exports.default_configuration = require('./Pict-Section-Form-Provider-Templates-DefaultConfiguration.json');
module.exports.default_configuration = _DefaultProviderConfiguration;
{
"RenderOnLoad": false,
"AutoRender": false,

@@ -11,3 +11,22 @@ "DefaultRenderable": "Form-Main",

"MacroTemplates": {
"Section": {
"HTMLID": " id=\"Section-{~D:Context[0].UUID~}\" "
},
"Group": {
"HTMLID": " id=\"Group-{~D:Context[0].UUID~}\" "
},
"Input": {
"Informary": " data-i-form=\"{~D:Context[0].formID~}\" data-i-datum=\"{~D:Record.PictForm.InformaryDataAddress~}\" ",
"InformaryTabular": " data-i-form=\"{~D:Context[0].formID~}\" data-i-datum=\"{~D:Record.PictForm.InformaryDataAddress~}\" data-i-container=\"{~D:Record.PictForm.InformaryContainerAddress~}\" ",
"HTMLName": " name=\"{~D:Record.Name~}\" ",
"HTMLID": " id=\"{~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~}')\" "
}
},
"TargetElementAddress": "#Form-Container-Div"
}
const libPictViewClass = require('pict-view');
const libInformary = require('informary');
const libInformary = require('./Pict-Service-Informary.js');
const libFormsTemplateProvider = require('./Pict-Section-Form-Provider-Templates.js');
class PictSectionForm extends libPictViewClass
class PictSectionFormView extends libPictViewClass
{

@@ -39,2 +38,6 @@ constructor(pFable, pOptions, pServiceHash)

}
if (!tmpOptions.SectionTabularRowTemplateHash)
{
tmpOptions.SectionTabularRowTemplateHash = `Pict-Form-Template-TabularRow-${tmpOptions.Hash}`;
}

@@ -65,4 +68,15 @@ if (tmpOptions.Renderables.length < 1)

}
if (!this.pict.providers.Informary)
{
let tmpInformary = this.pict.addProvider('Informary', libInformary.default_configuration, libInformary);
tmpInformary.initialize();
}
// This is for if we decide to abstract metatemplates into a separate provider for code simplification
// if (!this.pict.providers.PictFormSectionMetatemplateGenerator)
// {
// let tmpMetatemplateGenerator = this.pict.addProvider('PictFormSectionMetatemplateGenerator', libFormsMetatemplateGenerator.default_configuration, libFormsMetatemplateGenerator);
// tmpMetatemplateGenerator.initialize();
// }
// Load any form-specific templates
// Load any view section-specific templates
this.formsTemplateSetPrefix = `PFT-${this.Hash}-${this.UUID}`;

@@ -86,6 +100,9 @@ if (this.options.hasOwnProperty('MetaTemplates') && Array.isArray(this.options.MetaTemplates))

}
// The default template prefix
this.defaultTemplatePrefix = 'Pict-Forms-Basic';
this.formID = `Pict-Form-${this.Hash}-${this.UUID}`;
this.informary = new libInformary({ Form:this.formID })
// Informary is very old and requires jquery.
// TODO: Refactor informary to be a pict service, eliminating this need entirely.

@@ -98,4 +115,30 @@ this.viewMarshalDestination = false;

this.initializeFormGroups();
this.rebuildMacros();
}
dataChanged(pInputHash)
{
// 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();
this.pict.PictApplication.solve();
this.marshalToView();
}
getMarshalDestinationAddress()
{
if (this.viewMarshalDestination)
{
return this.viewMarshalDestination;
}
else if (this.pict.views.PictFormMetacontroller && this.pict.views.PictFormMetacontroller.viewMarshalDestination)
{
return this.pict.views.PictFormMetacontroller.viewMarshalDestination;
}
else
{
return 'AppData';
}
}
getMarshalDestinationObject()

@@ -138,10 +181,3 @@ {

this.informary.marshalDataToForm(tmpMarshalDestinationObject,
function(pError)
{
if (pError)
{
this.log.error(`Error marshaling data to view: ${pError}`);
}
});
this.pict.providers.Informary.marshalDataToForm(tmpMarshalDestinationObject, this.formID);
}

@@ -162,16 +198,3 @@ catch (pError)

if (typeof(tmpMarshalDestinationObject) != 'object')
{
this.log.error(`Marshal destination object is not an object; if you initialize the view yourself you must set the viewMarshalDestination property to a valid address within the view. Falling back to AppData.`);
tmpMarshalDestinationObject = this.pict.AppData;
}
this.informary.marshalFormToData(tmpMarshalDestinationObject,
function(pError)
{
if (pError)
{
this.log.error(`Error marshaling data from view: ${pError}`);
}
});
this.pict.providers.Informary.marshalFormToData(tmpMarshalDestinationObject, this.formID);
}

@@ -220,2 +243,3 @@ catch (pError)

{
// TODO: Change this to use the parsed sectionManifest rather than parsing the manifest itself
let tmpDescriptor = this.options.Manifests.Section.Descriptors[tmpDescriptorKeys[i]];

@@ -252,2 +276,50 @@

// Check the Group type and get the manifest if it is a RECORDSET-based group.
// The three built-in set groups (Record, Tabular, Columnar) will do this or the
// developer can set a property on Group called "GroupType" to "RecordSet" for
// custom layouts.
if (((tmpGroup.Layout === 'Tabular') || (tmpGroup.Layout === 'Tabular') || (tmpGroup.Layout === 'Tabular')) ||
(tmpGroup.GroupType === 'RecordSet'))
{
// Check for the supporting manifest
if (!tmpGroup.hasOwnProperty('RecordManifest'))
{
this.pict.log.error(`Dynamic View [${this.UUID}]::[${this.Hash}] Group ${tmpGroup.Hash} is classified as a RecordSet group but thee Group does not contain a RecordManifest property.`);
tmpGroup.supportingManifest = this.fable.instantiateServiceProviderWithoutRegistration('Manifest');
}
else if (!this.options.Manifests.Section.hasOwnProperty('ReferenceManifests'))
{
this.pict.log.error(`Dynamic View [${this.UUID}]::[${this.Hash}] Group ${tmpGroup.Hash} is classified as a RecordSet group but there are no ReferenceManifests in the Section description Manifest.`);
tmpGroup.supportingManifest = this.fable.instantiateServiceProviderWithoutRegistration('Manifest');
}
else if (!this.options.Manifests.Section.ReferenceManifests.hasOwnProperty(tmpGroup.RecordManifest))
{
this.pict.log.error(`Dynamic View [${this.UUID}]::[${this.Hash}] Group ${tmpGroup.Hash} is classified as a RecordSet group and has a RecordManifest of [${tmpGroup.RecordManifest}] but the Section.ReferenceManifests object does not contain the referred to manifest.`);
tmpGroup.supportingManifest = this.fable.instantiateServiceProviderWithoutRegistration('Manifest');
}
else
{
tmpGroup.supportingManifest = this.fable.instantiateServiceProviderWithoutRegistration('Manifest', this.options.Manifests.Section.ReferenceManifests[tmpGroup.RecordManifest]);
}
}
if (tmpGroup.supportingManifest && (typeof(tmpGroup.RecordSetAddress) == 'string'))
{
let tmpSupportingManifestDescriptorKeys = Object.keys(tmpGroup.supportingManifest.elementDescriptors);
for (let k = 0; k < tmpSupportingManifestDescriptorKeys.length; k++)
{
let tmpInput = tmpGroup.supportingManifest.elementDescriptors[tmpSupportingManifestDescriptorKeys[k]];
if (!tmpInput.hasOwnProperty('PictForm'))
{
tmpInput.PictForm = {};
}
tmpInput.PictForm.InformaryDataAddress = tmpSupportingManifestDescriptorKeys[k];
tmpInput.PictForm.InformaryContainerAddress = tmpGroup.RecordSetAddress;
tmpInput.RowIdentifierTemplateHash = '{~D:Record.RowID~}';
}
}
let tmpRowHash = (typeof(tmpDescriptor.PictForm.Row) == 'string') ? tmpDescriptor.PictForm.Row :

@@ -275,26 +347,215 @@ (typeof(tmpDescriptor.PictForm.Row) == 'number') ? `Row_${tmpDescriptor.PictForm.Row.toString()}` :

rebuildCustomTemplate()
rebuildMacros()
{
let tmpTemplate = ``;
let tmpFormTemplatePrefix = 'Pict-Forms-Basic';
if (!this.options.hasOwnProperty('MacroTemplates'))
{
return false;
}
if (this.pict.views.PictFormMetacontroller)
// Section macros
let tmpSectionMacroKeys = Object.keys(this.options.MacroTemplates.Section);
if (typeof(this.sectionDefinition.Macro) !== 'object')
{
if (this.pict.views.PictFormMetacontroller.hasOwnProperty('formTemplatePrefix'))
this.sectionDefinition.Macro = {};
}
for (let n = 0; n < tmpSectionMacroKeys.length; n++)
{
this.sectionDefinition.Macro[tmpSectionMacroKeys[n]] = this.pict.parseTemplate (this.options.MacroTemplates.Section[tmpSectionMacroKeys[n]], this.sectionDefinition, null, [this]);
}
for (let i = 0; i < this.sectionDefinition.Groups.length; i++)
{
let tmpGroup = this.sectionDefinition.Groups[i];
// Group Macros
let tmpGroupMacroKeys = Object.keys(this.options.MacroTemplates.Group);
if (!tmpGroup.hasOwnProperty('Macro'))
{
tmpFormTemplatePrefix = this.pict.views.PictFormMetacontroller.formTemplatePrefix;
tmpGroup.Macro = {};
}
for (let n = 0; n < tmpGroupMacroKeys.length; n++)
{
tmpGroup.Macro[tmpGroupMacroKeys[n]] = this.pict.parseTemplate (this.options.MacroTemplates.Group[tmpGroupMacroKeys[n]], tmpGroup, null, [this]);
}
if (!Array.isArray(tmpGroup.Rows))
{
continue;
}
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];
// Input Macros
let tmpInputMacroKeys = Object.keys(this.options.MacroTemplates.Input);
if (!tmpInput.hasOwnProperty('Macro'))
{
tmpInput.Macro = {};
}
for (let n = 0; n < tmpInputMacroKeys.length; n++)
{
tmpInput.Macro[tmpInputMacroKeys[n]] = this.pict.parseTemplate (this.options.MacroTemplates.Input[tmpInputMacroKeys[n]], tmpInput, null, [this]);
}
}
}
if (tmpGroup.supportingManifest)
{
let tmpSupportingManifestDescriptorKeys = Object.keys(tmpGroup.supportingManifest.elementDescriptors);
for (let k = 0; k < tmpSupportingManifestDescriptorKeys.length; k++)
{
let tmpInput = tmpGroup.supportingManifest.elementDescriptors[tmpSupportingManifestDescriptorKeys[k]];
// Input Macros
let tmpInputMacroKeys = Object.keys(this.options.MacroTemplates.Input);
if (!tmpInput.hasOwnProperty('Macro'))
{
tmpInput.Macro = {};
}
for (let n = 0; n < tmpInputMacroKeys.length; n++)
{
tmpInput.Macro[tmpInputMacroKeys[n]] = this.pict.parseTemplate (this.options.MacroTemplates.Input[tmpInputMacroKeys[n]], tmpInput, null, [this]);
}
}
}
}
}
// Add the Form Prefix stuff
if (this.pict.TemplateProvider.getTemplate(`${this.formsTemplateSetPrefix}-Template-Wrap-Prefix`))
checkViewSpecificTemplate(pTemplatePostfix)
{
// This is here to cut down on complex guards, and, so we can optimize/extend it later if we need to.
return this.pict.TemplateProvider.templates.hasOwnProperty(`${this.formsTemplateSetPrefix}${pTemplatePostfix}`)
}
checkThemeSpecificTemplate(pTemplatePostfix)
{
// This is here to cut down on complex guards, and, so we can optimize/extend it later if we need to.
return this.pict.TemplateProvider.templates.hasOwnProperty(`${this.defaultTemplatePrefix}${pTemplatePostfix}`)
}
getMetatemplateTemplateReference(pTemplatePostfix, pViewDataAddress)
{
/* This is to abstract the logic of checking for section-specific templates on the metatemplate generation lines.
* This code replace tons of blocks like this:
if (this.pict.TemplateProvider.getTemplate(`${this.formsTemplateSetPrefix}-Template-Wrap-Prefix`))
{
tmpTemplate += `{~T:${this.formsTemplateSetPrefix}-Template-Wrap-Prefix:Pict.views["${this.Hash}"].sectionDefinition~}`;
}
else
{
tmpTemplate += `{~T:${this.defaultTemplatePrefix}-Template-Wrap-Prefix:Pict.views["${this.Hash}"].sectionDefinition~}`;
}
*/
// 1. Check if there is a section-specific template loaded
if (this.checkViewSpecificTemplate(pTemplatePostfix))
{
tmpTemplate += `{~T:${this.formsTemplateSetPrefix}-Template-Wrap-Prefix:Pict.views["${this.Hash}"].sectionDefinition~}`;
return `\n{~T:${this.formsTemplateSetPrefix}${pTemplatePostfix}:Pict.views["${this.Hash}"].${pViewDataAddress}~}`
}
// 2. Check if there is a theme-specific template loaded for this postfix
else if (this.checkThemeSpecificTemplate(pTemplatePostfix))
{
return `\n{~T:${this.defaultTemplatePrefix}${pTemplatePostfix}:Pict.views["${this.Hash}"].${pViewDataAddress}~}`
}
// 3. This shouldn't happen if the template is based on the base class.
else
{
tmpTemplate += `{~T:${tmpFormTemplatePrefix}-Template-Wrap-Prefix:Pict.views["${this.Hash}"].sectionDefinition~}`;
return false;
}
tmpTemplate += `\n{~T:${tmpFormTemplatePrefix}-Template-Section-Prefix:Pict.views["${this.Hash}"].sectionDefinition~}`;
}
getInputMetatemplateTemplateReference(pDataType, pInputType, pViewDataAddress)
{
// Input types are customizable -- there could be 30 different input types for the string data type with special handling and templates
let tmpTemplateInputTypePostfix = `-Template-Input-InputType-${pInputType}`;
// Data types are not customizable; they are a fixed list based on what is available in Manyfest
let tmpTemplateDataTypePostfix = `-Template-Input-DataType-${pDataType}`;
// First check if there is an "input type" template available in either the section-specific configuration or in the general
if (pInputType)
{
let tmpTemplate = this.getMetatemplateTemplateReference(tmpTemplateInputTypePostfix, pViewDataAddress);
if (tmpTemplate)
{
return tmpTemplate;
}
}
// If we didn't find the template for the "input type", check for the "data type"
let tmpTemplate = this.getMetatemplateTemplateReference(tmpTemplateDataTypePostfix, pViewDataAddress);
if (tmpTemplate)
{
return tmpTemplate;
}
// There wasn't an input type specific or data type specific template, so fall back to the generic input template.
return this.getMetatemplateTemplateReference('-Template-Input', pViewDataAddress);
}
getTabularInputMetatemplateTemplateReference(pDataType, pInputType, pViewDataAddress, pRecordSubAddress)
{
// 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 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 tmpTemplateEndDataTypePostfix = `-TabularTemplate-End-Input-DataType-${pDataType}`;
// Tabular inputs are done in three parts -- the "begin", the "address" of the data and the "end".
// This means it is easily extensible to work on JSON objects as well as arrays.
// TODO: (when we update informary to be a pict plugin, make the data-i-index stuff support data-i-key for objects)
//let tmpAddressTemplate = ` data-i-index="ArrayIndex_${pRecordSubAddress.toString()}" `;
let tmpAddressTemplate = ` data-i-index="{~D:Record.Index~}" `;
// First check if there is an "input type" template available in either the section-specific configuration or in the general
if (pInputType)
{
let tmpBeginTemplate = this.getMetatemplateTemplateReference(tmpTemplateBeginInputTypePostfix, pViewDataAddress);
let tmpEndTemplate = this.getMetatemplateTemplateReference(tmpTemplateEndInputTypePostfix, pViewDataAddress);
if (tmpBeginTemplate && tmpEndTemplate)
{
return tmpBeginTemplate + tmpAddressTemplate + tmpEndTemplate;
}
}
// If we didn't find the template for the "input type", check for the "data type"
let tmpBeginTemplate = this.getMetatemplateTemplateReference(tmpTemplateBeginDataTypePostfix, pViewDataAddress);
let tmpEndTemplate = this.getMetatemplateTemplateReference(tmpTemplateEndDataTypePostfix, pViewDataAddress);
if (tmpBeginTemplate && tmpEndTemplate)
{
return tmpBeginTemplate + tmpAddressTemplate + tmpEndTemplate;
}
// If we didn't find the template for the "input type", or the "data type", fall back to the default
tmpBeginTemplate = this.getMetatemplateTemplateReference('TabularTemplate-Begin-Input', pViewDataAddress);
tmpEndTemplate = this.getMetatemplateTemplateReference('TabularTemplate-End-Input', pViewDataAddress);
if (tmpBeginTemplate && tmpEndTemplate)
{
return tmpBeginTemplate + tmpAddressTemplate + tmpEndTemplate;
}
// There wasn't some k ind 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}}.`)
return '';
}
rebuildCustomTemplate()
{
let tmpTemplate = ``;
if (this.pict.views.PictFormMetacontroller)
{
if (this.pict.views.PictFormMetacontroller.hasOwnProperty('formTemplatePrefix'))
{
this.defaultTemplatePrefix = this.pict.views.PictFormMetacontroller.formTemplatePrefix;
}
}
tmpTemplate += this.getMetatemplateTemplateReference(`-Template-Wrap-Prefix`, `sectionDefinition`);
tmpTemplate += this.getMetatemplateTemplateReference(`-Template-Section-Prefix`, `sectionDefinition`);
for (let i = 0; i < this.sectionDefinition.Groups.length; i++)

@@ -304,3 +565,11 @@ {

tmpTemplate += `\n{~T:${tmpFormTemplatePrefix}-Template-Group-Prefix:Pict.views["${this.Hash}"].sectionDefinition.Groups[${i}]~}`;
// Group layouts are customizable
// The three basic group layouts:
// 1. Record (default) - Render the whole address as a singleton record
// placing inputs into rows based on configuration.
// 2. Tabular - Expect either an Array of objects or a POJO to
// be rendered one record per row.
let tmpGroupLayout = (typeof(tmpGroup.Layout) === 'string') ? tmpGroup.Layout :
(typeof(this.sectionDefinition.DefaultGroupLayout) === 'string') ? this.sectionDefinition.DefaultGroupLayout :
'Record';

@@ -312,53 +581,82 @@ if (!Array.isArray(tmpGroup.Rows))

for (let j = 0; j < tmpGroup.Rows.length; j++)
switch(tmpGroupLayout)
{
tmpTemplate += `\n{~T:${tmpFormTemplatePrefix}-Template-Row-Prefix:Pict.views["${this.Hash}"].sectionDefinition.Groups[${i}]~}`;
for (let k = 0; k < tmpGroup.Rows[j].Inputs.length; k++)
{
let tmpTemplateInputScope = '-Template-Input';
case 'Tabular':
// Tabular layout
let tmpTemplateSetRecordRowTemplate = '';
tmpTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-Group-Prefix`, `getGroup("${i}")`);
// Tabular templates only have one "row" for the header in the standard template, and then a row for each record.
// The row for each record happens as a TemplateSet.
tmpTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-RowHeader-Prefix`, `getGroup("${i}")`);
tmpGroup.Rows[j].Inputs[k].PictForm.HTMLInformaryProperties = ` data-i-form="${this.formID}" data-i-datum="${tmpGroup.Rows[j].Inputs[k].PictForm.InformaryDataAddress}" `;
tmpGroup.Rows[j].Inputs[k].PictForm.HTMLInputName = ` name="${tmpGroup.Rows[j].Inputs[k].Name}" `;
tmpGroup.Rows[j].Inputs[k].PictForm.HTMLInputID = ` id="${this.UUID}-FormInput-${tmpGroup.Rows[j].Inputs[k].Hash}" `;
tmpTemplateSetRecordRowTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-Row-Prefix`, `getGroup("${i}")`);
for (let j = 0; j < tmpGroup.Rows.length; j++)
{
tmpGroup.Rows[j].Inputs[k].PictForm.HTMLInputFullProperties = `${tmpGroup.Rows[j].Inputs[k].PictForm.HTMLInputID}${tmpGroup.Rows[j].Inputs[k].PictForm.HTMLInputName}${tmpGroup.Rows[j].Inputs[k].PictForm.HTMLInformaryProperties}`;
let tmpRow = tmpGroup.Rows[j];
// Tabular are odd in that they have a header row and then a meta TemplateSet for the rows()
// Check for view-specific control/datatype templates
if (this.pict.TemplateProvider.getTemplate(`${this.formsTemplateSetPrefix}${tmpTemplateInputScope}-InputType-${tmpGroup.Rows[j].Inputs[k].PictForm.InputType}`))
{
tmpTemplateInputScope += `-InputType-${tmpGroup.Rows[j].Inputs[k].PictForm.InputType}`;
tmpTemplate += `\n{~T:${this.formsTemplateSetPrefix}${tmpTemplateInputScope}:Pict.views["${this.Hash}"].sectionDefinition.Groups[${i}].Rows[${j}].Inputs[${k}]~}`;
// In this case we are going to load the descriptors from the supportingManifests
if (!tmpGroup.supportingManifest)
{
this.log.error(`PICT Form [${this.UUID}]::[${this.Hash}] error generating tabular metatemplate: missing group manifest ${tmpGroup.RecordManifest} from supportingManifests.`);
continue;
}
// TODO: Keyed objects as the entries
for (let k = 0; k < tmpGroup.supportingManifest.elementAddresses.length; k++)
{
let tmpSupportingManifestHash = tmpGroup.supportingManifest.elementAddresses[k];
let tmpInput = tmpGroup.supportingManifest.elementDescriptors[tmpSupportingManifestHash];
tmpTemplate += this.getMetatemplateTemplateReference('-TabularTemplate-HeaderCell', `getTabularRecordInput("${i}","${k}")`);
tmpTemplateSetRecordRowTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-Cell-Prefix`, `getTabularRecordInput("${i}","${k}")`);
let tmpInputType = (tmpInput.hasOwnProperty('PictForm')) ? tmpInput.PictForm.InputType : 'Default';
// Right now the address is just the array element for the record.
tmpTemplateSetRecordRowTemplate += this.getTabularInputMetatemplateTemplateReference(tmpInput.DataType, tmpInputType, `getTabularRecordInput("${i}","${k}")`, k);
// Accidentally did the next part of resolution a step early in the chain
//tmpTemplateSetRecordRowTemplate += this.getTabularInputMetatemplateTemplateReference(tmpInput.DataType, tmpInputType, `getTabularRecordInput("${i}","${tmpSupportingManifestHash}")`);
tmpTemplateSetRecordRowTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-Cell-Postfix`, `getTabularRecordInput("${i}","${k}")`);
}
}
else if (this.pict.TemplateProvider.getTemplate(`${this.formsTemplateSetPrefix}${tmpTemplateInputScope}-DataType-${tmpGroup.Rows[j].Inputs[k].DataType}`))
{
tmpTemplateInputScope += `-DataType-${tmpGroup.Rows[j].Inputs[k].DataType}`;
tmpTemplate += `\n{~T:${this.formsTemplateSetPrefix}${tmpTemplateInputScope}:Pict.views["${this.Hash}"].sectionDefinition.Groups[${i}].Rows[${j}].Inputs[${k}]~}`;
}
tmpTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-RowHeader-Postfix`, `getGroup("${i}")`);
// Check for theme-specific control/datatype templates
else if (this.pict.TemplateProvider.getTemplate(`${tmpFormTemplatePrefix}${tmpTemplateInputScope}-InputType-${tmpGroup.Rows[j].Inputs[k].PictForm.InputType}`))
// This is the template by which the tabular template includes the rows.
// The recursion here is difficult to envision without drawing it.
// TODO: Consider making this function available in manyfest in some fashion it seems dope.
tmpTemplate += `\n\n{~TS:${this.options.SectionTabularRowTemplateHash}:Context[0].tabularKeys(${this.getMarshalDestinationAddress()}.${tmpGroup.RecordSetAddress})~}\n`;
tmpTemplateSetRecordRowTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-Row-Postfix`, `getGroup("${i}")`);
tmpTemplate += this.getMetatemplateTemplateReference(`-TabularTemplate-Group-Postfix`, `getGroup("${i}")`);
// Add the TemplateSetTemplate
this.pict.TemplateProvider.addTemplate(this.options.SectionTabularRowTemplateHash, tmpTemplateSetRecordRowTemplate);
break;
case 'Record':
default:
tmpTemplate += this.getMetatemplateTemplateReference(`-Template-Group-Prefix`, `getGroup("${i}")`);
for (let j = 0; j < tmpGroup.Rows.length; j++)
{
tmpTemplateInputScope += `-InputType-${tmpGroup.Rows[j].Inputs[k].PictForm.InputType}`;
tmpTemplate += `\n{~T:${tmpFormTemplatePrefix}${tmpTemplateInputScope}:Pict.views["${this.Hash}"].sectionDefinition.Groups[${i}].Rows[${j}].Inputs[${k}]~}`;
}
else if (this.pict.TemplateProvider.getTemplate(`${tmpFormTemplatePrefix}${tmpTemplateInputScope}-DataType-${tmpGroup.Rows[j].Inputs[k].DataType}`))
{
tmpTemplateInputScope += `-DataType-${tmpGroup.Rows[j].Inputs[k].DataType}`;
tmpTemplate += `\n{~T:${tmpFormTemplatePrefix}${tmpTemplateInputScope}:Pict.views["${this.Hash}"].sectionDefinition.Groups[${i}].Rows[${j}].Inputs[${k}]~}`;
}
let tmpRow = tmpGroup.Rows[j];
// Fall back on the default control/datatype template
else
{
tmpTemplate += `\n{~T:${tmpFormTemplatePrefix}${tmpTemplateInputScope}:Pict.views["${this.Hash}"].sectionDefinition.Groups[${i}].Rows[${j}].Inputs[${k}]~}`;
tmpTemplate += this.getMetatemplateTemplateReference(`-Template-Row-Prefix`, `getGroup("${i}")`);
// There are three row layouts: Record, Tabular and Columnar
for (let k = 0; k < tmpRow.Inputs.length; k++)
{
let tmpInput = tmpRow.Inputs[k];
tmpTemplate += this.getInputMetatemplateTemplateReference(tmpInput.DataType, tmpInput.PictForm.InputType, `getInput("${i}","${j}","${k}")`);
}
tmpTemplate += this.getMetatemplateTemplateReference(`-Template-Row-Postfix`, `getGroup("${i}")`);
}
}
tmpTemplate += `\n{~T:${tmpFormTemplatePrefix}-Template-Row-Postfix:Pict.views["${this.Hash}"].sectionDefinition.Groups[${i}]~}`;
tmpTemplate += this.getMetatemplateTemplateReference(`-Template-Group-Postfix`, `getGroup("${i}")`);
break;
}
tmpTemplate += `\n{~T:${tmpFormTemplatePrefix}-Template-Group-Postfix:Pict.views["${this.Hash}"].sectionDefinition.Groups[${i}]~}`;
}
tmpTemplate += `\n{~T:${tmpFormTemplatePrefix}-Template-Section-Postfix:Pict.views["${this.Hash}"].sectionDefinition~}`;
tmpTemplate += `\n{~T:${tmpFormTemplatePrefix}-Template-Wrap-Postfix:Pict.views["${this.Hash}"].sectionDefinition~}`;
tmpTemplate += this.getMetatemplateTemplateReference(`-Template-Section-Postfix`, `sectionDefinition`);
tmpTemplate += this.getMetatemplateTemplateReference(`-Template-Wrap-Postfix`, `sectionDefinition`);

@@ -368,2 +666,159 @@ this.pict.TemplateProvider.addTemplate(this.options.SectionTemplateHash, tmpTemplate);

// Metatemplate Helper Functions
getTabularRecordInput(pGroupIndex, pInputIndex)
{
// 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.
let tmpGroup = this.getGroup(pGroupIndex);
if (!tmpGroup)
{
this.log.warn(`PICT View Metatemplate Helper getTabularRowData ${pGroupIndex} was not a valid group.`);
return false;
}
// Now get the supporting manifest and the input element
// This needs more guards
let tmpSupportingManifestHash = tmpGroup.supportingManifest.elementAddresses[pInputIndex];
return tmpGroup.supportingManifest.elementDescriptors[tmpSupportingManifestHash];
}
getTabularRecordData(pGroupIndex, pRowIdentifier)
{
// 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.
let tmpGroup = this.getGroup(pGroupIndex);
if (!tmpGroup)
{
this.log.warn(`PICT View Metatemplate Helper getTabularRowData ${pGroupIndex} was not a valid group.`);
return false;
}
// Now identify the group
let tmpRowSourceRecord = this.sectionManifest.getValueByHash(this.getMarshalDestinationObject(), tmpGroup.RecordSetAddress);
if (!tmpRowSourceRecord)
{
// Try the address
tmpRowSourceRecord = this.sectionManifest.getValueAtAddress(this.getMarshalDestinationObject(), tmpGroup.RecordSetAddress);
}
if (!tmpRowSourceRecord)
{
this.log.warn(`PICT View Metatemplate Helper getTabularRowData ${pGroupIndex} could not find the record set for ${tmpGroup.RecordSetAddress}.`);
return false;
}
// Now we have the source record let's see what it is
try
{
if (Array.isArray(tmpRowSourceRecord))
{
return tmpRowSourceRecord[pRowIdentifier];
}
else if (typeof(tmpRowSourceRecord) === 'object')
{
return tmpRowSourceRecord[pRowIdentifier];
}
else
{
this.log.warn(`PICT View Metatemplate Helper getTabularRowData ${pGroupIndex} could not determine the type of the record set for ${tmpGroup.RecordSetAddress}.`);
return false;
}
}
catch (pError)
{
this.log.error(`PICT View Metatemplate Helper getTabularRowData ${pGroupIndex} encountered an error: ${pError}`);
return false;
}
}
getGroup(pGroupIndex)
{
if (isNaN(pGroupIndex))
{
this.log.warn(`PICT View Metatemplate Helper getGroup ${pGroupIndex} was expecting a number.`);
return false;
}
if (pGroupIndex > this.sectionDefinition.Groups.length)
{
this.log.warn(`PICT View Metatemplate Helper getGroup ${pGroupIndex} was out of bounds.`);
return false;
}
return this.sectionDefinition.Groups[pGroupIndex];
}
getRow(pGroupIndex, pRowIndex)
{
let tmpGroup = this.getGroup(pGroupIndex);
if (tmpGroup)
{
if (isNaN(pRowIndex))
{
this.log.warn(`PICT View Metatemplate Helper getRow ${pRowIndex} was expecting a number.`);
return false;
}
if (pRowIndex > tmpGroup.Rows.length)
{
this.log.warn(`PICT View Metatemplate Helper getRow ${pRowIndex} was out of bounds.`);
return false;
}
return tmpGroup.Rows[pRowIndex];
}
else
{
return false;
}
}
getInput(pGroupIndex, pRowIndex, pInputIndex)
{
let tmpRow = this.getRow(pGroupIndex, pRowIndex);
if (tmpRow)
{
if (isNaN(pInputIndex))
{
this.log.warn(`PICT View Metatemplate Helper getInput ${pInputIndex} was expecting a number.`);
return false;
}
if (pInputIndex > tmpRow.Inputs.length)
{
this.log.warn(`PICT View Metatemplate Helper getInput ${pInputIndex} was out of bounds.`);
return false;
}
return tmpRow.Inputs[pInputIndex];
}
else
{
return false;
}
}
tabularKeys (pDataObject)
{
// Take an address (or a hash) and get the tabular keys for it
let tmpDataObject = this.getMarshalDestinationObject;
if (!pDataObject)
{
return [];
}
if (Array.isArray(pDataObject))
{
return pDataObject.map((pValue, pIndex) => { return { Index: pIndex }; });
}
else if (typeof(pDataObject) === 'object')
{
return Object.keys(pDataObject);
}
else
{
return [];
}
}
get isPictSectionForm()

@@ -375,2 +830,2 @@ {

module.exports = PictSectionForm;
module.exports = PictSectionFormView;

@@ -10,5 +10,10 @@ // The container for all the Pict-Section-Form related code.

// The metatemplate generator provider
// (if we decide to abstract this out from the view class)
// module.exports.PictFormMetatemplateGenerator = require('./Pict-Section-Form-MetatemplateGenerator.js');
// The metacontroller view
module.exports.PictFormMetacontroller = require('./Pict-Form-Metacontroller.js');
// The application container
module.exports.PictFormApplication = require('./Pict-Section-Form-Application.js');

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc