-
-
Save DonAmit197/08dc16e8dcc88194ed8e500dd56eebf2 to your computer and use it in GitHub Desktop.
promise hell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /**** | |
| * 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