Skip to content

Instantly share code, notes, and snippets.

@DonAmit197
Last active July 3, 2023 00:25
Show Gist options
  • Select an option

  • Save DonAmit197/08dc16e8dcc88194ed8e500dd56eebf2 to your computer and use it in GitHub Desktop.

Select an option

Save DonAmit197/08dc16e8dcc88194ed8e500dd56eebf2 to your computer and use it in GitHub Desktop.
promise hell
/****
* Server side PDF generation plugin.
*Scenario:
* Promise based
* It fetches the HTML content on a button click
* htmlComponentCreate method : Instatiating the Promise API
* It fetches the value of the user input from the form.submission JSON for "textfield", "select", "day","number", "textarea","datetime","currency","phoneNumber"
* For nzPost address: When it finds the custom property data_zapostAddress === "true" in the form JSON as a custom property
* then method : Method when the Promise is resolved or rejected, if the form is validated
* you can also use a callback function inside the then method
**/
/*Way to use: */
//var myMethod = new RenderEachFormComponent(form,pyActivity,dom)
//myMethod.then((resolve){/* Your functions on resolved state */})
//(error)=>{/* Show your error messages */},
/* RenderEachFormComponent Class generates each component to HTML with response values */
function getFormComponentValues(form, dom){
var _flatten = flatten(form.submission.data);
//console.log("Flat1", _flatten)
return new Promise(function(resolve, reject){
try{
setTimeout(function(){
form.everyComponent((component) => {
//console.log("Flat2", _flatten)
/*console.log("Component",component)*/
var COMPONENT_ELEM = component.element;
var COMPONENT_PATH = component["path"];
var COMPONENT_TYPE = component.type;
//console.log("Component: ", component)
for(const [key, value] of Object.entries(_flatten)) {
if (key === COMPONENT_PATH) {
//console.log("Val",value);
//console.log("Comp Type", COMPONENT_TYPE);
//console.log("Comp zElem:", COMPONENT_ELEM);
//var parentNodeOfComponent = COMPONENT_ELEM.parentNode;
//console.log("Flat:", _flatten);
//console.log("Parent",parentNodeOfComponent )
//Check all component type
var permittedComponentTypes = [
"textfield",
"select",
"day",
"number",
"textarea",
"datetime",
"currency",
"phoneNumber",
"email",
];
if (permittedComponentTypes.includes(COMPONENT_TYPE)) {
console.warn(
"Types included on this plugin:",
_L.toString(permittedComponentTypes)
);
var createDiv = document.createElement("span");
createDiv.setAttribute("data-value", value);
var $value = value ? value : "--";
createDiv.textContent = $value;
if (COMPONENT_TYPE === "email") {
//console.log("Email value", value);
}
if (COMPONENT_TYPE === "currency") {
if (value) {
$value = value ? value : "--";
createDiv.textContent = `$${$value}`;
}
}
if (COMPONENT_TYPE === "datetime") {
if (value) {
$value = value ? value : "--";
createDiv.textContent = moment($value).format("LLL");
}
}
//var spanElem = COMPONENT_ELEM.querySelector("span[data-value]");
if (COMPONENT_ELEM && !COMPONENT_ELEM.contains(createDiv)) {
COMPONENT_ELEM.appendChild(createDiv);
}
}
if (COMPONENT_TYPE === "signature") {
//console.log("sign value", value);
//console.log("sign key", key);
var createSignatureElem = document.createElement("img");
createSignatureElem.setAttribute("data-value", "");
createSignatureElem.setAttribute("src", value);
if (COMPONENT_ELEM) {
var imgElem = COMPONENT_ELEM.querySelector("img[data-value]");
if (!imgElem) {
COMPONENT_ELEM.appendChild(createSignatureElem);
}
}
}
} //key === COMPONENT_PATH
}; //_flatten,function(value,key)
/** Address Component **/
//Component API must have custom property data_zapostAddress = true
var componentComponentType = component.component.type;
if (
componentComponentType === "address" &&
component.component.key.startsWith( "address")
) {
//console.log("This address comp:",component)
//console.log("This address key: ", component.component.key);
console.log("This address comp path:", component.path);
try {
for( const [key,value] of Object.entries(_flatten)) {
//console.log("Key", key);
//1st Filter component Display Property must have full_address
//Get the flatten submission key ends with full_address
if (key.endsWith("full_address")) {
//console.log("fuull add val", value);
// Back-trach: Split the full_address from right down and get the left top key names
const splitKey = key.split(".");
const desiredKey = splitKey.slice(0, -1).join(".");
//console.log("Desired Key", desiredKey);
// If splitted right down value matches with the component path
if (
desiredKey.includes( component.path) ||
COMPONENT_PATH === desiredKey
) {
/*console.log(component)*/
//console.log("Component Add",component)
//console.log("Address Value", value)
//console.log("Address compo Key", component.component.key)
var desiredComponentElem = component.element;
//console.log(desiredComponentElem)
if (desiredComponentElem) {
var existingSpan =
desiredComponentElem.querySelector("span[data-value]");
if (!existingSpan) {
var createDiv2 = document.createElement("span");
createDiv2.setAttribute("data-value", value);
var $value = value ? value : "--";
createDiv2.textContent = $value;
desiredComponentElem.appendChild(createDiv2);
desiredComponentElem.classList.add("address-modified-pdf");
}
}
} // includes desiredKey
}
/******
* If manual mode is enabled in address
*******/
if (key.includes( component.component.key)) {
//console.log("KKEy",key)
if (key.includes(key, "mode")) {
//console.log("Mode Key", value)
if (value === "manual") {
if (component.element !== undefined) {
//console.log("Address Manual",component.element)
component.element.classList.add("has-manual-enabled");
}
}
}
} //_L.includes(key, component.component.key)
}; //_forIn
} catch (error) {
console.error(
"Please add data_zapostAddress inside formio Custom Address component, to solve: ",
error
);
}
}
/** Address Component Ends **/
if(component === form.components[form.components.length - 1]){
resolve()
}
}); //everyComponent
},500)
}
catch(error){
console.log("Error on attaching the component values from the submission json object",error);
reject(error);
}
})
}
/*****
* FormToHtmlForPDF class fetaches each component and generates a PDF frendly HTML
******/
class FormToHtmlForPDF {
constructor(form, dom) {
this.form = form;
this.dom = dom;
}
/* HTML on resolved state */
getHTML(runPegaActivityfn) {
// new Promise for HTML Code generation
var DOM = this.dom;
var form = this.form;
//get the components
getFormComponentValues(form,DOM);
return new Promise(function (resolve, reject) {
setTimeout(function () {
const styles = document.querySelector("#pdfStyles").textContent;
const pdfStyle = `<style>${styles}</style>`;
const htmlStyle = `
.approvalHTMLMainWrapper{
background:#fff;
width:800px !important;
overflow:auto;
padding:24px;
top:0;
right:0;
transform:translateY(174px);
height:calc(100vh - 180px);
position:absolute;
z-index:-1 !important;
}
.approvalHTMLMainWrapper [ref="element"]{
display:none !important;
}
.approvalHTMLMainWrapper .choices{
display:none !important;
}
.approvalHTMLMainWrapper .govuk-error-message, .approvalHTMLMainWrapper.govuk-date-input, .approvalHTMLMainWrapper .address-autocomplete-container{
display:none !important;
}
`;
var clonedHTMLStyle = `<style>${htmlStyle}</style>`;
var $innerHTML = document.querySelector(DOM).innerHTML;
var HTMLCLONE = document.createElement("div");
var innerElement = document.createElement("div");
var styleElement = document.createElement("span");
styleElement.innerHTML = `${clonedHTMLStyle}${pdfStyle}`;
HTMLCLONE.classList.add("approvalHTMLMainWrapper");
HTMLCLONE.appendChild(styleElement);
HTMLCLONE.appendChild(innerElement);
innerElement.classList.add("approvalHTMLWrapper");
innerElement.setAttribute("data-ef_pdf", "");
innerElement.innerHTML = `${$innerHTML}`;
if(document.querySelector(DOM)){
document.querySelector(DOM).closest("body").appendChild(HTMLCLONE);
pega.u.d.gDirtyOverride = false;
}
/* Remove elements from the PDF Wrapper */
var pdfWrapperNode = document.querySelector(".approvalHTMLWrapper");
var pdfStaticFooter = pdfWrapperNode.querySelector(
".expressform-static_page-footer"
);
if (pdfStaticFooter) {
pdfStaticFooter.remove();
}
/**************************************
* Remove form inputs from the PDF HTML
***************************************/
var refElementsOfFormInputs =
pdfWrapperNode.querySelectorAll(`[ref="element"]`);
var refElementSelctDropdown =
pdfWrapperNode.querySelectorAll(".choices");
var errorMessageDOM = pdfWrapperNode.querySelectorAll(
".govuk-error-message"
);
var dateInput = pdfWrapperNode.querySelectorAll(".govuk-date-input");
var addressAutoCompleteContainer = pdfWrapperNode.querySelectorAll(
".address-autocomplete-container"
);
var pdfDOMArraysToRemove = [
refElementsOfFormInputs,
refElementSelctDropdown,
errorMessageDOM,
dateInput,
addressAutoCompleteContainer,
];
if (pdfDOMArraysToRemove.length > 0) {
Array.from(pdfDOMArraysToRemove).map((refElem) => {
//console.log("Ref El",refElem)
if (refElem) {
refElem.forEach( function (el) {
el.classList.add("hide-in-pdf");
});
}
});
}
/* Remove data-value from the formIO DOM */
var dataValueinUI = document
.querySelector(DOM)
.querySelectorAll("[data-value]");
if (dataValueinUI.length > 0) {
Array.from(dataValueinUI).map(function (el) {
//console.log("data-value in Dom", el)
el.remove();
});
}
var appendedCheckbox = document
.querySelector(".approvalHTMLWrapper")
.querySelectorAll(".formio-component-checkbox");
Array.from(appendedCheckbox).map(function (el) {
var inputCheck = el.querySelector("input.govuk-checkboxes__input");
var isCheckInputStyles = `
width: 32px !important;
height: 32px !important;
display: inline-block !important;
vertical-align: middle !important;
margin-right: 8px !important;
`;
if (inputCheck && inputCheck.checked) {
el.closest(".formio-component-checkbox").style.display = "block";
el.closest(".formio-component-checkbox").classList.add("isChecked");
//Add inline style to the checkbox input
inputCheck.style.cssText = isCheckInputStyles;
}
});
resolve(HTMLCLONE);
}, 1000);
})
.then(function (htmlNode) {
/***
* Since we are exporting the serialized HTML output from the form
* we are minifying the HTML output for better performance
* Generate the outer Content
****/
var minify = require("html-minifier").minify;
const minifiedHTML = minify(htmlNode.innerHTML, {
collapseWhitespace: true,
removeComments: true,
minifyCSS: true,
removeAttributeQuotes: true,
});
const htmlToPDFNode = minifiedHTML;
//console.log(htmlToPDFNode);
//localStorage.setItem("htmlData",htmlToPDFNode)
return htmlToPDFNode;
})
.then(function (htmlToPDFNode) {
return runPegaActivityfn(htmlToPDFNode);
})
.catch(function (error) {
console.log("Error at getHTML method: ", error);
});
} // getHTML
}
/**********
* PegaActivityforFormToPDF class for activating Pega Activity for HTML Submission to clipboard
***********/
class PegaActivityforFormToPDF {
constructor(htmlNode, form, pyActivity, isDownloadButtonForTest) {
this.htmlNode = htmlNode;
this.form = form;
this.pyActivity = pyActivity;
this.isDownloadButtonForTest = isDownloadButtonForTest;
}
set(testpyActivity) {
const ISDOWNLOAD_BTN_FOR_TEST = this.isDownloadButtonForTest;
const FORM = this.form;
const PY_ACTIVITY = this.pyActivity;
const HTML_NODE = this.htmlNode;
//console.log(HTML_NODE)
/*
* Approval Utility method
* Write all Pega functions
*/
/****************************
* If isDownloadButtonForTest is true the case will not be submitted as approved on clicking the "Approve" button
* Developer can click the "Download Summary" button in the header
* and iteratively test the PDF styling.
* This magic is only for the developers
*****************************/
switch (ISDOWNLOAD_BTN_FOR_TEST) {
case true:
var safeURL = new SafeURL();
safeURL.put("pzActivity", "pzRunActionWrapper");
safeURL.put("pyActivity", testpyActivity);
safeURL.put("ExpressFormPDFData", HTML_NODE);
pega.u.d.asyncRequest("POST", SafeURL_createFromURL(safeURL.toURL()));
var appendHTMLNode = document.querySelector(".approvalHTMLMainWrapper");
appendHTMLNode.style.display = "block";
alert(
"Happy coding! This is on developers mode to test the PDF styles. Now click the Download Summary button at top to view your changes."
);
FORM.submission = FORM._submission;
wizardform.expressFormFooter();
pega.u.d.gDirtyOverride = false;
break;
/****************************
* If isDownloadButtonForTest is false the case
* will be submitted as approved.
*****************************/
case false:
var whtNxtHTMLContent = "";
if (FORM.getComponent("form_whatHappensNext")) {
var whtNxtData = FORM.getComponent("form_whatHappensNext");
whtNxtHTMLContent = whtNxtData.component.html;
}
var formSubmission = FORM._submission;
var jsonString = JSON.stringify(formSubmission);
var safeURL = new SafeURL();
safeURL.put("pzActivity", "pzRunActionWrapper");
safeURL.put("pyActivity", "FinishAssignment");
safeURL.put("ExpressFormPDFData", HTML_NODE);
safeURL.put("WHNString", whtNxtHTMLContent);
safeURL.put("JSONString", jsonString);
var appendHTMLNode = document.querySelector(".approvalHTMLMainWrapper");
appendHTMLNode.style.display = "none";
pega.u.d.submit(safeURL, this, "", event);
FORM.submission = FORM._submission;
wizardform.expressFormFooter();
pega.u.d.gDirtyOverride = false;
} //switch
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment