diff --git a/blocks/forms/formHelper.js b/blocks/forms/formHelper.js index f99e23b50..77dae2c62 100644 --- a/blocks/forms/formHelper.js +++ b/blocks/forms/formHelper.js @@ -1,4 +1,5 @@ import { input } from '../../scripts/dom-helpers.js'; +import { getCookie } from '../../scripts/scripts.js'; /* Helper functions */ export const RESOURCEKEYS = ['heading', 'region', 'portalId', 'formId', 'redirectUrl', 'productFamily', 'productPrimaryApplication', 'cmp']; @@ -103,7 +104,7 @@ export function createSalesforceForm(hubspotForm, formConfig) { }); /* qdc */ - const qdcCall = hubspotForm.querySelector('input[name="requested_a_salesperson_to_call__c"]').checked; + const qdcCall = hubspotForm.querySelector('input[name="requested_a_salesperson_to_call__c"]'); let qdc = ''; if (qdcCall) { @@ -174,3 +175,40 @@ export function createSalesforceForm(hubspotForm, formConfig) { setTimeout(() => { window.top.location.href = returnURL; }, 200); } } + +/* get form ready */ +export function getFormFieldValues(formConfig) { + // Get the `cmp` parameters from URL or cookie + const params = new Proxy(new URLSearchParams(window.location.search), { + get: (searchParams, prop) => searchParams.get(prop), + }); + const cmpCookieValue = getCookie('cmp'); + const valuecmp = params.cmp || cmpCookieValue; + + return { + product_family__c: formConfig.productFamily, + research_area: formConfig.researchArea, + product_primary_application__c: formConfig.productPrimaryApplication, + requested_qdc_discussion__c: formConfig.qdc, + cmp: valuecmp || formConfig.cmp, + return_url: formConfig.redirectUrl, + product_selection__c: formConfig.productSelection, + google_analytics_medium__c: formConfig.googleAnalyticsMedium, + google_analytics_source__c: formConfig.googleAnalyticsSource, + keyword_ppc__c: formConfig.keywordPPC, + gclid__c: formConfig.gclid, + product_image: formConfig.productImage, + product_bundle_image: formConfig.productBundleImage, + product_bundle: formConfig.productBundle, + qdc: formConfig.qdc, + }; +} + +// Function to update multiple form fields +export function updateFormFields(form, fieldValues) { + Object.entries(fieldValues).forEach(([fieldName, value]) => { + if (value && form.querySelector(`input[name="${fieldName}"]`)) { + form.querySelector(`input[name="${fieldName}"]`).value = value; + } + }); +} diff --git a/blocks/forms/forms.css b/blocks/forms/forms.css index 2cb8e88a3..959107ebe 100644 --- a/blocks/forms/forms.css +++ b/blocks/forms/forms.css @@ -30,7 +30,7 @@ height: 40px; line-height: 1.4286; outline: none; - padding: 5px; + padding: 5px 15px; max-width: 100%; width: 100%; margin-bottom: 0; @@ -133,6 +133,7 @@ label.privacy { font-weight: 400; line-height: 1.4286; margin-bottom: 0; + display: block; } .hs-fieldtype-booleancheckbox .input { @@ -158,6 +159,7 @@ label.privacy { line-height: 1.5; margin: 0; width: 100%; + text-align: left; } .hs-error-msgs.inputs-list { @@ -169,10 +171,6 @@ label.privacy { margin-top: 0; } -.form-columns-2 + .form-columns-1 .hs-form-field:first-child { - padding-top: 15px; -} - .form-columns-1 .hs-form-field.hs-subscribe:first-child { margin-top: 9px; } @@ -226,10 +224,15 @@ label.privacy { } /* hubspot form */ +main form fieldset[class*='form-columns'] .input { + margin-right: 0 !important; +} + .hubspot-form form { display: flex; flex-direction: column; line-height: 16px; + text-align: left; } .hubspot-form form .hs-submit { @@ -269,8 +272,15 @@ input[type="submit"] { text-decoration: none !important; } +@media only screen and (min-width: 768px) { + main form fieldset.form-columns-2 { + display: flex; + gap: 15px; + } +} + @media only screen and (max-width: 400px) { .hbspt-form { padding-bottom: 110px; } -} \ No newline at end of file +} diff --git a/blocks/forms/forms.js b/blocks/forms/forms.js index 7c886ed26..6c2d562c1 100644 --- a/blocks/forms/forms.js +++ b/blocks/forms/forms.js @@ -1,22 +1,12 @@ import { - button, div, h3, input, + a, button, div, h3, label, } from '../../scripts/dom-helpers.js'; -import { toCamelCase, toClassName } from '../../scripts/lib-franklin.js'; -import { getCookie, loadScript } from '../../scripts/scripts.js'; +import { loadCSS, toCamelCase, toClassName } from '../../scripts/lib-franklin.js'; +import { loadScript } from '../../scripts/scripts.js'; import { - fieldsObj, getDefaultForKey, marketingOptin, OID, prodPrimApp, QDCRrequest, RESOURCEKEYS, + createSalesforceForm, getDefaultForKey, getFormFieldValues, RESOURCEKEYS, updateFormFields, } from './formHelper.js'; -/* custom form fields */ -function createCustomField(hubspotFormData, fieldName, newName) { - const fieldVal = hubspotFormData.get(fieldName); - if (fieldVal && fieldVal !== undefined && fieldVal !== '') { - const elementCompany = input({ name: newName, value: fieldVal, type: 'hidden' }); - return elementCompany; - } - return 0; -} - /* extract data from table */ async function extractFormData(block) { const blockData = {}; @@ -35,53 +25,19 @@ async function extractFormData(block) { } /* create hubspot form */ -function createHubSpotForm(formConfig, target) { +export function createHubSpotForm(formConfig, target) { try { hbspt.forms.create({ // eslint-disable-line - region: formConfig.region, - portalId: formConfig.portalId, + region: formConfig.region || 'na1', + portalId: formConfig.portalId || '20222769', formId: formConfig.formId, target: `#${target}`, onFormReady: (form) => { // Handle Salesforce hidden fields via message event listener window.addEventListener('message', (event) => { if (event.data.type === 'hsFormCallback' && event.data.eventName === 'onFormReady') { - // Get the cmp parameters - const params = new Proxy(new URLSearchParams(window.location.search), { - get: (searchParams, prop) => searchParams.get(prop), - }); - const cmpCookieValue = getCookie('cmp'); - const valuecmp = params.cmp || cmpCookieValue; - - // Salesforce form fields - const mProductFamily = formConfig.productFamily; - const mResearchArea = formConfig.researchArea; - const mPrimaryApplication = formConfig.productPrimaryApplication; - const mRequestedQdcDiscussionC = formConfig.qdc; - const mCmp = valuecmp || formConfig.cmp; - const mReturnUrl = formConfig.redirectUrl; - - // Update the form with SFDC values if they exist - if (form.querySelector('input[name="return_url"]') && mReturnUrl !== '') { - form.querySelector('input[name="return_url"]').value = mReturnUrl; - } - if (form.querySelector('input[name="product_family__c"]') && mProductFamily !== '') { - form.querySelector('input[name="product_family__c"]').value = mProductFamily; - } - if (form.querySelector('input[name="research_area"]') && mResearchArea !== '') { - form.querySelector('input[name="research_area"]').value = mResearchArea; - } - - if (form.querySelector('input[name="product_primary_application__c"]') && mPrimaryApplication !== '') { - form.querySelector('input[name="product_primary_application__c"]').value = mPrimaryApplication; - } - if (form.querySelector('input[name="requested_qdc_discussion__c"]') && mRequestedQdcDiscussionC !== '') { - form.querySelector('input[name="requested_qdc_discussion__c"]').value = mRequestedQdcDiscussionC; - } - - if (form.querySelector('input[name="cmp"]') && mCmp) { - form.querySelector('input[name="cmp"]').value = mCmp; - } + const fieldValues = getFormFieldValues(formConfig); + updateFormFields(form, fieldValues); // Customize the submit button const submitInput = form.querySelector('input[type="submit"]'); @@ -92,103 +48,26 @@ function createHubSpotForm(formConfig, target) { }, submitInput.value || 'Submit'); submitInput.replaceWith(submitButton); } + + const privacy = document.querySelector('label.privacy'); + if (!privacy) { + const privacyMsg = label({ class: 'privacy' }, + 'By submitting your details, you confirm that you have reviewed and agree with the Molecular Devices ', + a({ + href: 'https://www.moleculardevices.com/privacy', title: 'Privacy Policy', target: '_blank', rel: 'noopener', + }, 'Privacy Policy'), + ', and that you understand your privacy choices as they pertain to your personal data as provided in the ', + a({ + href: 'https://www.moleculardevices.com/privacy', title: 'Privacy Policy', target: '_blank', rel: 'noopener', + }, 'Privacy Policy'), + ' under “Your Privacy Choices”.'); + form.appendChild(privacyMsg); + } } }); }, onFormSubmit: (hubspotForm) => { - setTimeout(() => { - const hubspotFormData = new FormData(hubspotForm); - const form = document.createElement('form'); - form.method = 'POST'; - form.action = 'https://webto.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8'; - - // Your org ID - const elementOID = input({ name: 'oid', value: OID, type: 'hidden' }); - form.appendChild(elementOID); - - // generate a form from Customize | Leads | Web-to-Lead to figure out more - fieldsObj.forEach(({ newName, fieldName }) => { - const inputField = createCustomField(hubspotFormData, fieldName, newName); - if (inputField && inputField !== 0) { - form.appendChild(inputField); - } - }); - - /* qdc */ // test case - const qdcCall = hubspotForm.querySelector('input[name="requested_a_salesperson_to_call__c"]').checked; - let qdc = ''; - - if (qdcCall) { - qdc = 'Call'; - } else { - qdc = hubspotFormData.get('requested_qdc_discussion__c') || ''; // test case - } - if (qdc === '') { - qdc = formConfig.qdc || ''; - } - - const elementqdcrequest = input({ name: QDCRrequest, value: qdc, type: 'hidden' }); - form.appendChild(elementqdcrequest); - - /* subscribe */ - let subscribe = hubspotForm.querySelector('input[name="subscribe"]').checked; - if (!subscribe) { subscribe = 'false'; } - const elementmarketingoptin = input({ name: marketingOptin, value: subscribe, type: 'hidden' }); - form.appendChild(elementmarketingoptin); - - // SFDC redirects to returnURL in the response to the form post - let returnURL = hubspotFormData.get('return_url'); - if (!returnURL) { - returnURL = formConfig.redirectUrl; - } - - if (returnURL) { - const hsmduri = returnURL; - const hsmdkey = 'rfq'; - const hsmdvalue = qdc; - - const re = new RegExp(`([?&])${hsmdkey}=.*?(&|$)`, 'i'); - const separator = hsmduri.indexOf('?') !== -1 ? '&' : '?'; - - if (hsmduri.match(re)) { - returnURL = hsmduri.replace(re, `$1${hsmdkey}=${hsmdvalue}$2`); - } else { - returnURL = `${hsmduri}${separator}${hsmdkey}=${hsmdvalue}`; - } - - returnURL = `${returnURL}&subscribe=${subscribe}`; - } - const elementRetURL = input({ name: 'retURL', value: returnURL, type: 'hidden' }); - form.appendChild(elementRetURL); - - // test case - const primaryApplicationText = hubspotFormData.get('product_primary_application__c'); - const productAndPrimaryFtype = hubspotFormData.get('product_and_primary_application_na___service_contracts'); - let primaryApplication = ''; - if (productAndPrimaryFtype) { - const checkboxes = hubspotForm.getElementsByName('product_and_primary_application_na___service_contracts'); - for (let i = 0; i < checkboxes.length; i += 1) { - if (checkboxes[i].checked) { - primaryApplication += `${checkboxes[i].value} , `; - } - } - } else if (primaryApplicationText !== '' && primaryApplicationText !== undefined) { - primaryApplication = primaryApplicationText; - } - const elementprodprimapp = input({ name: prodPrimApp, value: primaryApplication, type: 'hidden' }); - form.appendChild(elementprodprimapp); - - // Append the form to the body - document.body.appendChild(form); - - const allowedValues = ['Call', 'Demo', 'Quote']; - if (allowedValues.includes(qdc)) { - form.submit(); - } else { - setTimeout(() => { window.top.location.href = returnURL; }, 200); - } - /* END */ - }, 1000); + createSalesforceForm(hubspotForm, formConfig); }, }); } catch (e) { @@ -199,7 +78,8 @@ function createHubSpotForm(formConfig, target) { } /* load hubspot script */ -function loadHubSpotScript(callback) { +export function loadHubSpotScript(callback) { + loadCSS('/blocks/forms/forms.css'); loadScript(`https://js.hsforms.net/forms/v2.js?v=${new Date().getTime()}`, callback); } diff --git a/blocks/quote-request/quote-request.css b/blocks/quote-request/quote-request.css index 50fe5b32d..7f86fb75a 100644 --- a/blocks/quote-request/quote-request.css +++ b/blocks/quote-request/quote-request.css @@ -42,16 +42,12 @@ main div.section.quote-request-container + .section.wave { color: var(--text-white); margin: auto; max-width: 100%; - padding: 50px 50px 100px; + padding: 50px 50px 80px; position: relative; text-align: center; width: 100%; } -.rfq-product-wrapper.request-quote-form { - padding-bottom: 0; -} - .quote-request-wrapper .quote-request { padding-bottom: 100px; } @@ -101,7 +97,7 @@ main div.section.quote-request-container + .section.wave { } .rfq-icon-link:hover { - background: url('images/hover-bg.png'); + background: url("images/hover-bg.png"); background-position: center; background-repeat: no-repeat; background-size: cover; @@ -237,7 +233,7 @@ main div.section.quote-request-container + .section.wave { } .progress { - background-image: url('images/progress-bar_resized.png'); + background-image: url("images/progress-bar_resized.png"); background-size: contain; border: 0; border-radius: 20px !important; @@ -246,6 +242,58 @@ main div.section.quote-request-container + .section.wave { width: 0; } +/* rfq form block changes */ +main .contact-quote-request form fieldset { + max-width: 100%; + text-align: left; +} + +main .contact-quote-request .hs-dependent-field, +main .contact-quote-request .hs-form-field { + padding-top: 0; +} + +main .contact-quote-request .hs-form-field .hs-field-desc { + color: #e2e2e2; + font-size: 13px; + font-weight: 100; + letter-spacing: 0.5px; + line-height: 1em; + width: 94% !important; +} + +main .contact-quote-request .hs-form-field textarea.hs-input { + height: 70px; +} + +main .contact-quote-request .actions { + margin-top: 40px; + margin-bottom: 20px; +} + +main .contact-quote-request .hs-submit .actions button { + transition: all 0.2s; + background: linear-gradient(to bottom, #00748d 0%, #0190ac 52%, #00748d 100%, #00748d 100%); + background-color: #298da9; + border: none; + border-radius: 20px; + color: #fff; + font-size: 20px; + line-height: 25px; + padding: 14px 18px; + width: 100%; +} + +main .contact-quote-request .privacy { + color: #999; + line-height: 1.4em; + margin: 0 auto; + padding: 0 2px 2px 30px; + font-size: 13px; + text-align: left; + max-width: 70%; +} + @media only screen and (min-width: 768px) { .rfq-product-wrapper { max-width: 90%; @@ -270,11 +318,7 @@ main div.section.quote-request-container + .section.wave { @media only screen and (max-width: 767px) { .rfq-product-wrapper { - padding: 30px 5px 100px; - } - - .rfq-product-wrapper.request-quote-form { - padding-bottom: 50px; + padding: 30px 5px 80px; } .rfq-thankyou-msg h2 { @@ -306,4 +350,4 @@ main div.section.quote-request-container + .section.wave { margin: 12px auto; margin-bottom: 30px; } -} \ No newline at end of file +} diff --git a/blocks/quote-request/quote-request.js b/blocks/quote-request/quote-request.js index c34027a46..871ecd19b 100644 --- a/blocks/quote-request/quote-request.js +++ b/blocks/quote-request/quote-request.js @@ -3,11 +3,11 @@ import { loadScript, getCookie, fetchFragment, } from '../../scripts/scripts.js'; import { - div, h3, ul, li, img, a, span, i, iframe, button, + div, h3, ul, li, img, a, span, i, button, p, } from '../../scripts/dom-helpers.js'; import { sampleRUM } from '../../scripts/lib-franklin.js'; -import { iframeResizeHandler } from '../../templates/landing-page/landing-page.js'; +import { createHubSpotForm, loadHubSpotScript } from '../forms/forms.js'; const PREVIEW_DOMAIN = '.aem.page'; @@ -148,7 +148,7 @@ function prepImageUrl(thumbImage) { async function loadIframeForm(data, type) { loadScript('../../scripts/iframeResizer.min.js'); - const formUrl = 'https://info.moleculardevices.com/rfq'; + // const formUrl = 'https://info.moleculardevices.com/rfq'; const root = document.getElementById('step-3'); const rfqRUM = { source: 'global' }; root.innerHTML = ''; @@ -231,19 +231,20 @@ async function loadIframeForm(data, type) { const requestTypeParam = queryParams && queryParams.get('request_type'); const hubSpotQuery = { - product_family__c: sfdcProductFamily, - product_selection__c: sfdcProductSelection, - product_primary_application__c: sfdcPrimaryApplication, + formId: '09ad331d-27c6-470a-86d4-7d6c4b141bc8', + productFamily: sfdcProductFamily, + productSelection: sfdcProductSelection, + productPrimaryApplication: sfdcPrimaryApplication, cmp: cmpValue, - google_analytics_medium__c: getCookie('utm_medium') ? getCookie('utm_medium') : '', - google_analytics_source__c: getCookie('utm_source') ? getCookie('utm_source') : '', - keyword_ppc__c: getCookie('utm_keyword') ? getCookie('utm_keyword') : '', - gclid__c: getCookie('gclid') ? getCookie('gclid') : '', - product_image: productImage || 'NA', - product_bundle_image: bundleThumbnail || 'NA', - product_bundle: productBundle, - requested_qdc_discussion__c: requestTypeParam || 'Quote', - return_url: data.familyID + googleAnalyticsMedium: getCookie('utm_medium') ? getCookie('utm_medium') : '', + googleAnalyticsSource: getCookie('utm_source') ? getCookie('utm_source') : '', + keywordPPC: getCookie('utm_keyword') ? getCookie('utm_keyword') : '', + gclid: getCookie('gclid') ? getCookie('gclid') : '', + productImage: productImage || 'NA', + productBundleImage: bundleThumbnail || 'NA', + productBundle, + qdc: requestTypeParam || 'Quote', + redirectUrl: data.familyID ? `https://www.moleculardevices.com/quote-request-success?cat=${data.familyID}` : 'https://www.moleculardevices.com/quote-request-success', }; @@ -252,22 +253,21 @@ async function loadIframeForm(data, type) { hubSpotQuery.website = `https://www.moleculardevices.com${data.path}`; } - root.appendChild( - div( - h3('Request Quote or Information for:'), - h3(tab), - p('To ensure the best solution for your application, please complete the form in full. This will enable us to initiate a conversation about your requirements and provide an accurate quote.'), - iframe({ - class: 'contact-quote-request', - id: 'contactQuoteRequest', - src: `${formUrl}?${new URLSearchParams(hubSpotQuery).toString()}`, - }), - ), + const contactQuoteRequestID = 'contactQuoteRequest'; + const formWrapper = div( + h3('Request Quote or Information for:'), + h3(tab), + p('To ensure the best solution for your application, please complete the form in full. This will enable us to initiate a conversation about your requirements and provide an accurate quote.'), + div({ + class: 'contact-quote-request', + id: contactQuoteRequestID, + }), ); + loadHubSpotScript(createHubSpotForm.bind(null, hubSpotQuery, contactQuoteRequestID)); + root.appendChild(formWrapper); root.appendChild(createBackBtn('step-3')); rfqRUM.type = hubSpotQuery.requested_qdc_discussion__c; sampleRUM('rfq', rfqRUM); - iframeResizeHandler('contactQuoteRequest'); } /* step one */ diff --git a/styles/styles.css b/styles/styles.css index 7344d97cf..60b2f66a4 100644 --- a/styles/styles.css +++ b/styles/styles.css @@ -539,22 +539,33 @@ button.secondary:focus { box-shadow: 0 0 10px 1px rgb(0 0 0 / 20%); } -main input { - font-size: 1.25rem; - width: 100%; - max-width: 50rem; +main input:not([type='radio'], [type='checkbox']), +main textarea, +main select { display: block; - margin-bottom: 1rem; - padding: 0.75rem 0.6rem; - border-radius: 0.25rem; + padding: 5px 15px; box-sizing: border-box; - border: 1px solid var(--text-color); - color: var(--text-color); background-color: var(--background-color); + border: 1px solid #bebebe; + border-radius: 0; + box-shadow: none; + color: #565656; + font-size: 15px; + height: 40px; + line-height: 1.4286; + outline: none; + width: 100% !important; + max-width: 100% !important; + font-family: inherit; +} + +main form fieldset .hs-form-field { + line-height: 1.4em; + margin-bottom: 12px; } -main input:hover { - border: 1px solid var(--text-color); +main textarea { + height: 100px; } main pre { @@ -1442,7 +1453,7 @@ main div.section.wave.wavecarousel.bluegreen:not(.no-margin-top) { margin-top: 30px; } -main div.section.no-margin-bottom{ +main div.section.no-margin-bottom { margin-bottom: 0 !important; }