Skip to content
92 changes: 58 additions & 34 deletions mt.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,27 @@ const gAppPref = 'mt-';
const gFldDelim = /(?:\n[ \t]*)(?=\w)/g;
const gRecDelim = /(?:\n[ \t]*){2,}(?=\w)/g;

window.onload = function Merge_Templates() {
// global boolean to indicate if schema is embedded in html
let gHasEmbeddedSchema;

window.onload = function Merge_Templates() {
// loop each container in body. Singlets first, then Collections.

// single recordset templates (not recordset collections)
// write sep fx, then determine what to combine with loopCollSinglets
loopOrphanSinglets();

// collection
const collViewNodes = document.querySelectorAll(
const collContainers = document.querySelectorAll(
gAppPref + 'container[' + gAppPref + 'collection]'
);

// loop and render collection-containers
collViewNodes.forEach(collViewNode => {
makeRecordsetHeaders(collViewNode);
collContainers.forEach((oContainer) => {
makeRecordsetHeaders(oContainer);

// singlets
loopCollRecordsets(collViewNode);
loopCollRecordsets(oContainer);
});
};

Expand All @@ -35,32 +37,31 @@ function loopOrphanSinglets() {
const singletContainers = document.querySelectorAll(
gAppPref + 'container[' + gAppPref + 'records]'
);

// loop and render recordset-containers
singletContainers.forEach(snglContain => {

// get fields from parent attribs before looping
fields = getFields(snglContain);
$("fields", fields )

singletContainers.forEach((snglContain) => {
// get fields from parent attribs before looping
const fields = getFields(snglContain);
$('fields', fields);

// merge records into template
loadMerge(snglContain);
loadMerge(snglContain, fields);
});
}

function loopCollRecordsets(scope) {
// get fields from parent attribs before looping
fields = getFields(scope);
const fields = getFields(scope);

// singlets
const singletContainers = scope.querySelectorAll(
gAppPref + 'container[' + gAppPref + 'records]'
);

// loop and render recordset-containers
singletContainers.forEach(snglContain => {
singletContainers.forEach((snglContain) => {
// merge records into template
loadMerge(snglContain);
loadMerge(snglContain, fields);
});
}

Expand All @@ -74,7 +75,7 @@ function makeRecordsetHeaders(collContainer) {
const collectionRecordsets = getCollectionRecordsets(collContainer);

// loop recordsets. Write merged template for each
collectionRecordsets.forEach(recordset => {
collectionRecordsets.forEach((recordset) => {
makeRecordsetHeader(collContainer, templateHTML, recordset);
});
}
Expand All @@ -87,7 +88,7 @@ function makeRecordsetHeader(collContainer, templateHTML, recordset) {

// replace fields in template with metadata from recordset
const metas = getAppMeta(recordset);
Object.keys(metas).forEach(key => {
Object.keys(metas).forEach((key) => {
recordsetHTML = recordsetHTML.replaceAll(`[[${key}]]`, metas[key].trim());
});

Expand All @@ -114,30 +115,45 @@ function getCollectionRecordsets(collContainer) {
return recordsets;
}

function getFields(viewNode) {
function getFields(oContainer) {
// return fields from mt-fields node, which is the parent of the collection or recordset
// if view-container points to collection, get fieldset-name from collection data-container
// if view-container points to recordset, get fieldset-name from recordset data-container
let sDataContainer = viewNode.getAttribute(gAppPref + 'collection');
if (!sDataContainer)
sDataContainer = viewNode.getAttribute(gAppPref + 'records');
let sRecordset =
oContainer.getAttribute(gAppPref + 'collection') ||
oContainer.getAttribute(gAppPref + 'records');

const dataNode = document.getElementById(sRecordset);

const dataNode = document.getElementById(sDataContainer);
// look for schema in HTML
const schemaName = dataNode.getAttribute(gAppPref + 'fields');
const schemaNode = document.getElementById(schemaName);
const rawFields = schemaNode.innerText.trim();
gHasEmbeddedSchema = !!schemaName;

let rawFields;

if (schemaName) {
// get fieldnames from schema if found in HTML
const schemaNode = document.getElementById(schemaName);
rawFields = schemaNode.innerText.trim();
} else {
// get fieldnames from top of recordset, which look like the first record in the dataset
const rawData = dataNode.innerText.trim();
rawFields = rawData.split(gRecDelim)[0];
}

const fields = rawFields.split(gFldDelim);

return fields;
}

function loadMerge(snglContain) {
function loadMerge(snglContain, fields) {
// load records into template

// get template
const templateHTML = getTemplateHTML(snglContain);

// get data
records = getData(snglContain);
const records = getData(snglContain);

// merge
const mergeHTML = mergeRecords(templateHTML, fields, records);
Expand Down Expand Up @@ -169,14 +185,22 @@ function getRawData(container) {
const dataElement = document.querySelector(`${gAppPref}records#${dataID}`);

// get records contents
const rawData = dataElement.innerText.trim();
let rawData = dataElement.innerText.trim();

// remove field names (first record) if fieldnames embedded in data
if (!gHasEmbeddedSchema) {
const rawRecords = rawData.split(gRecDelim);
rawRecords.shift();
rawData = rawRecords.join('\n\n');
}

return rawData;
}

function getRecords(rawData) {
// load records into array, rows and columns
const aRows = rawData.trim().split(gRecDelim);
const records = aRows.map(sRow => {
const records = aRows.map((sRow) => {
return sRow.split(gFldDelim);
});

Expand All @@ -187,14 +211,14 @@ function mergeRecords(templateHTML, fields, records) {
// make html for each record by merging with temlate
let allRecordsHTML = '';

records.forEach(record => {
records.forEach((record) => {
let recordHTML = mergeRecord(templateHTML, fields, record);
allRecordsHTML += recordHTML;
});
return allRecordsHTML;
}

function mergeRecord(templateHTML, dataFields, record) {
function mergeRecord(templateHTML, fields, record) {
let recordHTML = templateHTML;

// LOOP PLACEHOLDERS in the template
Expand All @@ -205,7 +229,7 @@ function mergeRecord(templateHTML, dataFields, record) {
const templateFields = recordHTML.match(templateFieldsRegex);

// loop placeholders
templateFields.forEach(templFld => {
templateFields.forEach((templFld) => {
// need to find matching value in record by name
// we can use dataFields to get column position, or, make record a key:value set
// need too see trailing underscore (to escape spaces), and with trailing under removed to get value from record
Expand Down Expand Up @@ -234,11 +258,11 @@ function mergeRecord(templateHTML, dataFields, record) {

function strToObj(str) {
// return Object from string. Comma-sep key:value pairs. Just wrap in braces.
const obj = Object.fromEntries(str.split(',').map(i => i.split(':')));
const obj = Object.fromEntries(str.split(',').map((i) => i.split(':')));
return obj;
}

function $(text1, text2) {
console.log(text1);
console.log(text2);
}
}