let shadow; class skFormBuilder extends HTMLElement{ connectedCallback() { shadow = this.attachShadow({mode:'closed'}); shadow.appendChild(this.querySelector('style[sk-style]')); shadow.appendChild(this.querySelector('div.sk-form')); } setAssets() { const formDiv = this.querySelector('div.sk-form'); const linkElem = document.createElement("style"); const globalCss = this.querySelector('[sk-global-css]'); if ((this.plan?.billable ? this.plan?.plan !== null : true) && this.customization?.recaptcha_type === 'v3') { this.addRecaptchaScript(); } linkElem.setAttribute('sk-style', true); linkElem.innerHTML = this.generateFormStyles(globalCss); this.appendChild(linkElem); this.appendChild(formDiv); } addRecaptchaScript() { const recaptchaScript = document.createElement("script"); recaptchaScript.id = 'recaptcha-scriptv3'; recaptchaScript.src = `https://www.google.com/recaptcha/api.js?render=${this.customization?.recaptcha_site_key}`; recaptchaScript.setAttribute('async', true); recaptchaScript.setAttribute('defer', true); this.appendChild(recaptchaScript); } generateFormStyles(globalCss) { return ` .sk-form { padding: 0 10px; } .sk-form.blur .row { -webkit-filter: blur(2px); pointer-events: none; } .sk-form-submitting { display: block; position: absolute; top: 50%; right: 50%; z-index: 1; } .sk-form-submitting.hide { display: none; } .sk-form-already-submitted-msg { position: absolute; top: 50%; left: 50%; color: green; border: 2px solid green; padding: 0px 15px; border-radius: 6px; } .sk-success-message p { color: green; border: 2px solid green; padding: 2px 8px; } .sk-error-message p { border: 2px solid red; color: red; padding: 2px 8px; } .sk-success-message, .sk-error-message { margin-bottom: 10px; } .sk-checkbox-required-msg, .sk-rating-required-msg, .sk-required-msg { color: #F00; font-size: 14px; } * { box-sizing: border-box; } .sk-btn-success { --btn-bg: #008060; --btn-border-color: #008060; --btn-color: #FFFFFF; --btn-active-bg: var(--bs-color-primary-800); --btn-active-color: #FFFFFF; --btn-active-border-color: var(--bs-color-primary-800); --btn-hover-bg: #006e52; --btn-hover-color: #FFFFFF; --btn-hover-border-color: #006e52; } .sk-btn { --btn-font-family: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; --btn-font-weight: 400; --btn-font-style: normal; --btn-line-height: 1; --btn-border-radius: 4px; --btn-font-size: 14px; --btn-padding-x: 20px; --btn-padding-y: 12px; --btn-border-style: solid; --btn-border-width: 1px; background-color: var(--btn-bg); font-family: var(--btn-font-family); font-weight: var(--btn-font-weight); font-style: var(--btn-font-style); font-size: var(--btn-font-size); line-height: var(--btn-line-height); color: var(--btn-color); border: var(--btn-border-width) var(--btn-border-style) var(--btn-border-color); border-radius: var(--btn-border-radius); padding: var(--btn-padding-y) var(--btn-padding-x); transition: .25s ease all; cursor: pointer; text-decoration: none; } .sk-btn:active { background-color: var(--btn-active-bg); color: var(--btn-active-color); border-color: var(--btn-active-border-color); } .sk-btn:hover { background-color: var(--btn-hover-bg); color: var(--btn-hover-color); border-color: var(--btn-hover-border-color); } h1,h2,h3,h4,h5,h6 { margin-top: 0; margin-bottom: 1rem; } p { margin-top: 1.2rem; margin-bottom: 0; } p:first-child { margin: 0; } .sk-form-header { margin-bottom: 2.2rem; } .sk-form-main { background-color: var(--formDesignBgColor); width: 100%; max-width: var(--formDesignFormWidth); margin: auto; color: var(--formDesignContentColor); font-family: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; font-weight: 400; line-height: 1.5; } .sk-form a { color: var(--formDesignFormText); } .sk-form label { display: block; margin-bottom: 3px; color: var(--formDesignLabelColor); font-family: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; font-weight: 400; font-size: 14px; line-height: 1.5; } .sk-form input[type="text"], .sk-form input[type="number"], .sk-form input[type="file"], .sk-form input[type="email"], .sk-form input[type="password"], .sk-form input[type="number"], .sk-form input[type="tel"], .sk-form input[type="date"], .sk-form input[type="time"], .sk-form input[type="datetime-local"], .sk-form input[type="url"], .sk-form select, .sk-form textarea { border-radius: var(--formDesignInputRadius); background-color: var(--formDesignInputBackground); color: var(--formDesignFormText); border: 1px solid var(--formDesignInputBorder); padding: var(--formDesignVerticalSpacing) var(--formDesignHorizontalSpacing); width: 100%; font-family:inherit; } .sk-form .sk-form-main, .sk-form label, .sk-form button.sk-btn { font-family:inherit; } .sk-form button { background-color: var(--formDesignSubmitBtnBgColor); color: var(--formDesignSubmitBtnColor); border-color: var(--formDesignSubmitBtnBorderColor); } .sk-form button:hover { background-color: var(--formDesignSubmitBtnBgColorHover); color: var(--formDesignSubmitBtnColorHover); border-color: var(--formDesignSubmitBtnBorderColorHover); } .sk-form input[type="text"]::placeholder, .sk-form input[type="number"]::placeholder, .sk-form input[type="file"]::placeholder, .sk-form input[type="email"]::placeholder, .sk-form input[type="password"]::placeholder, .sk-form input[type="number"]::placeholder, .sk-form input[type="tel"]::placeholder, .sk-form input[type="date"]::placeholder, .sk-form input[type="time"]::placeholder, .sk-form input[type="datetime-local"]::placeholder, .sk-form input[type="url"]::placeholder, .sk-form select::placeholder, .sk-form textarea::placeholder { color: var(--formDesignInputPlaceholder); } .sk-form input[type="range"] { width: 100%; } .sk-form input[type="radio"], .sk-form input[type="checkbox"] { border: 1px solid rgba(0,0,0,.25); -webkit-appearance: none; -moz-appearance: none; appearance: none; -webkit-print-color-adjust: exact; color-adjust: exact; background-repeat: no-repeat; background-position: center; background-size: contain; width: 15px; height: 15px; } .sk-form input[type="radio"] { border-radius: 35px; } .sk-form input[type="checkbox"]:checked { background-color: var(--formDesignFormText); background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e"); } .sk-form input[type="radio"]:checked { background-color: var(--formDesignFormText); background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e"); } .sk-form .radio-wrapper label, .sk-form .checkbox-wrapper label { display: inline; vertical-align: middle; } .sk-form .radio-wrapper label p, .sk-form .checkbox-wrapper label p { display: inline; } .sk-form .radio-wrapper input, .sk-form .checkbox-wrapper input { vertical-align: middle; } .sk-form .sk-input-info { font-size: .75em; color: var(--formDesignInputPlaceholder); margin-top: 3px; } color-picker { display: block; } color-picker input[type="color"] { height: 43px; width: 43px; border-radius: 4px; overflow: hidden; margin-right: 10px; transition: .25s ease all; vertical-align: middle; background: transparent; border: 0; padding: 0; } .sk-btn.sk-btn-success { width: 100%; } .sk-form .mb-3 { margin-bottom: 1.2rem; } .sk-form .row { --bs-gutter-x: 1.5rem; --bs-gutter-y: 0; display: flex; flex-wrap: wrap; margin-right: -15px; margin-left: -15px; } .sk-form .row > * { flex-shrink: 0; width: 100%; max-width: 100%; padding-right: 15px; padding-left: 15px; } .sk-form .col-12 { flex: 0 0 auto; width: 100%; } .sk-align-center { text-align: center; } .d-none { display: none; } .ql-size-small { font-size: 0.75em; } .ql-size-normal { font-size: 1em; } .ql-size-large { font-size: 1.5em; } .ql-size-huge { font-size: 2em; } .ql-font-serif { font-family: Georgia, Times New Roman, serif; } .ql-font-monospace { font-family: Monaco, Courier New, monospace; } .ql-editor strong { font-weight: bold; } .ql-editor em { font-style: italic; } .ql-editor u { text-decoration: underline; } .ql-editor s { text-decoration: line-through; } .ql-editor ol { list-style-type: decimal; } .ql-editor ul { list-style-type: disc; } .ql-editor .ql-indent-1 { padding-left: 3em; } .ql-editor .ql-indent-2 { padding-left: 6em; } .ql-editor .ql-indent-3 { padding-left: 9em; } .ql-editor .ql-bg-black { background-color: #000; } .ql-editor .ql-bg-red { background-color: #e60000; } .ql-editor .ql-bg-orange { background-color: #f90; } .ql-editor .ql-bg-yellow { background-color: #ff0; } .ql-editor .ql-bg-green { background-color: #008a00; } .ql-editor .ql-bg-blue { background-color: #06c; } .ql-editor .ql-bg-purple { background-color: #93f; } .ql-editor .ql-color-white { color: #fff; } .ql-editor .ql-color-red { color: #e60000; } .ql-editor .ql-color-orange { color: #f90; } .ql-editor .ql-color-yellow { color: #ff0; } .ql-editor .ql-color-green { color: #008a00; } .ql-editor .ql-color-blue { color: #06c; } .ql-editor .ql-color-purple { color: #93f; } .ql-editor .ql-align-center { text-align: center; } .ql-editor .ql-align-right { text-align: right; } .ql-editor .ql-align-justify { text-align: justify; } .ql-editor .ql-video { display: block; max-width: 100%; margin: 1rem 0; } .ql-editor a { color: #06c; text-decoration: underline; } .ql-editor a:hover { color: #004c99; } @media (min-width: 768px) { .sk-form .col-md-6 { flex: 0 0 auto; width: 50%; } .sk-form .col-md-4 { flex: 0 0 auto; width:33.33%; } } ${globalCss?.innerHTML} `; } constructor(){ super(); this.store_name = Shopify.shop; this.mailData = []; this.forms = null; this.formData = this.querySelectorAll('[sk-forms]'); this.formsMain = this.querySelectorAll('[sk-form-block]'); this.submitBtn = null; this.elements = null; this.customization = window.skcustomization || {}; this.plan = window.skplan; this.init(); this.setAssets(); } checkWatermark = (Domain) => { let fd = new FormData(); const that = this; let logoelement = this.querySelector('.sk-logo-image'); fd.append('shop', this.store_name); fetch(`${Domain}getConfigurations`, { method: 'POST', headers: { 'Accept': 'application/json' }, body: fd }) .then(res => res.json()) .then(response => { if (response.remove_watermark !== '1') { let watermark = `
`; if (logoelement) { logoelement.innerHTML = watermark; } else if (document.querySelector('.sk-logo-image')) { document.querySelector('.sk-logo-image').innerHTML = watermark; } } }); } /* Function for get current date */ getCurrentDate = () => { let date = new Date(); let year = date.getFullYear(); let month = String(date.getMonth() + 1).padStart(2, '0'); // Months are zero-indexed let day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } getCurrentDateTime = () => { let now = new Date(); let year = now.getFullYear(); let month = String(now.getMonth() + 1).padStart(2, '0'); let day = String(now.getDate()).padStart(2, '0'); let hours = String(now.getHours()).padStart(2, '0'); let minutes = String(now.getMinutes()).padStart(2, '0'); return `${year}-${month}-${day}T${hours}:${minutes}`; } setMinTime = () => { let now = new Date(); let hours = String(now.getHours()).padStart(2, '0'); let minutes = String(now.getMinutes()).padStart(2, '0'); return `${hours}:${minutes}`; } checkMinDate = (input, errorElement, count) => { let minDate = input.getAttribute('min'); if (minDate) { let inputDate = new Date(input.value); let minDateValue = new Date(minDate); if (inputDate < minDateValue) { count += 1; errorElement.innerHTML = `The date must be after ${minDate}`; } else { errorElement.innerHTML = ''; } } return count; } formatAcceptTypes = (accept) => { if (!Array.isArray(accept)) { accept = [accept]; } return accept .filter(type => typeof type === 'string' && type.trim() !== '') .map(type => { type = type.trim(); return type.startsWith('.') ? type : `.${type}`; }) .join(', '); }; checkDate = () => { let dateInput = this.querySelectorAll('[sk-date]'); let count = 0; if (dateInput) { const that = this; dateInput.forEach(curr => { curr.addEventListener('input', () => { let errorMessage = curr.nextElementSibling; that.checkMinDate(curr, errorMessage, count); }); }); } } correctCaptcha = (response, token) => { if (response !== null) { document.querySelector(`[sk-submit-btn][data-btn-token="${token}"]`).removeAttribute('disabled'); } } formAppend = (Domain) => { this.formData.forEach(curr => { if (curr.textContent.trim() != '') { let res = JSON.parse(curr.textContent), formName = res.form_name, formData = JSON.parse(res.formData), formSettingsData = JSON.parse(res.formSettingsData), afterSubmissionData = JSON.parse(res.afterSubmissionAction), formDesignData = JSON.parse(res.formDesign), enable_recaptcha = res.enable_recaptcha, previewHtml = ``, renderForm = '', customCss = res.custom_css, appendTo = this.querySelector(`[sk-form-block][data-token="${res.form_token}"]`); if (formData && res.form_status == '1') { formData.forEach(data => { let formDataId = data.id || Math.floor(Math.random() * 1_000_000_0000); switch (data.type) { case 'textarea': previewHtml += `Form Submitted Successfully!!
'; curr.querySelector('.sk-success-message').scrollIntoView({behavior: 'smooth', block: 'start', inline: 'start'}); break; case "redirect": redirectPage += 1; break; case "hideAndmessage": curr.querySelector('.row').style.display = 'none'; curr.querySelector('.sk-success-message').innerHTML = (afterSubmissionMessage != null) ? afterSubmissionMessage : 'Form submitted
'; curr.querySelector('.sk-success-message').scrollIntoView({behavior: 'smooth', block: 'start', inline: 'start'}); break; default: break; } this.formSubmit(Domain, token); this.sendMail(response, Domain, this.store_name, token); if ((this.plan?.billable ? this.plan?.plan !== null : true) && customerTags.allowCustomerTag == '1' && customerTags.customerTag.length > 0 && customerEmail !== '') { this.addcustomertags(Domain, customerFname, customerLname, customerEmail, customerTags.customerTag); } // this.afterSubmission(scriptData); try { if (JSON.parse(JSON.parse(scriptData).afterSubmissionAction).formSubmissionAfterMessageJs != null) { eval(JSON.parse(JSON.parse(scriptData).afterSubmissionAction).formSubmissionAfterMessageJs); } } catch (error) { console.log(error); } if (redirectPage !== 0) { setTimeout(() => { window.location.href = redirectURL; }, 2000); } } else { curr.querySelector('.sk-error-message').innerHTML = `${response.error}
`; curr.classList.remove('blur'); document.querySelector('.sk-captcha')?.classList.remove('blur'); curr.querySelector(`.sk-form-submitting`).classList.add('hide'); curr.querySelector('.sk-error-message').scrollIntoView({behavior: 'smooth', block: 'start', inline: 'start'}); } }) } else { curr.classList.remove('blur'); document.querySelector('.sk-captcha')?.classList.remove('blur'); curr.querySelector(`.sk-form-submitting`).classList.add('hide'); } } } formViewMutation = (Domain, token) => { const target = document.querySelector(`.sk-form[data-token="${token}"]`); if (!target) return; const observer = new IntersectionObserver( (entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { this.formView(Domain, token); observer.unobserve(entry.target); } }); }, { root: null, threshold: 0.1 } ); observer.observe(target); } formView = (Domain, token) => { let fd = new FormData(); fd.append('shop', Shopify.shop); fd.append('token', token); fetch(`${Domain}form/view`, { method: 'POST', headers: { 'Accept': 'application/json' }, body: fd }) .then(res => res.json()) .then(response => {}) } formSubmit = (Domain, token) => { let fd = new FormData(); fd.append('shop', Shopify.shop); fd.append('token', token); fetch(`${Domain}form/submit`, { method: 'POST', headers: { 'Accept': 'application/json' }, body: fd }) .then(res => res.json()) .then(response => {}) } checkGemEvent = (gtmTags) => { let gtagData = JSON.parse(gtmTags); if (gtagData.allowGtag == '1') { if (typeof gtag === 'function') { gtag('event', gtagData.gtagEvent); } } if (gtagData.allowFbq == '1') { if (typeof fbq === 'function') { fbq('track_custom', gtagData.fbqEvent); } } } sendMail = (response, Domain, shop, token) => { let fd = new FormData(); fd.append('shop', shop); fd.append('token', token); fd.append('admin_email', JSON.stringify(response.admin_email)); fd.append('admin_email_subject', response.admin_email_subject); fd.append('configurations', JSON.stringify(response.configurations)); fd.append('customer_email', response.customer_email); fd.append('customer_name', response.customer_name); fd.append('file', JSON.stringify(response.file)); fd.append('form', JSON.stringify(response.form)); fd.append('fromMail', response.fromMail); fd.append('fromName', response.fromName); fd.append('key_data', response.key_data); fd.append('key_value', response.key_value); fd.append('mail_data', JSON.stringify(response.mail_data)); fd.append('remove_watermark', response.remove_watermark); fd.append('response_tag', JSON.stringify(response.response_tag)); fd.append('responses', JSON.stringify(response.responses)); fd.append('shop_data', JSON.stringify(response.shop_data)); fd.append('created_at', response.created_at); fetch(`${Domain}sendMailFun`, { method: 'POST', headers: { 'Accept': 'application/json' }, body: fd }) .then(res => res.json()) .then(response => { }); } addcustomertags = (Domain, customerFname, customerLname, customerEmail, customerTags) => { let fd = new FormData(); fd.append('shop', this.store_name); fd.append('fname', customerFname); fd.append('lname', customerLname); fd.append('email', customerEmail); fd.append('tags', customerTags); fetch(`${Domain}checkCustomers`, { method: 'POST', headers: { 'Accept': 'application/json' }, body: fd }) .then(res => res.json()) .then(response => { }); } colorChange = () => { this.inputField = this.querySelector('input[type="color"]'); this.textValue = this.querySelector('[data-value]'); if (this.inputField) { this.inputField.addEventListener('input', (e) => { let currValue = e.currentTarget.value; this.textValue.textContent = currValue; }); } } ratingChange = () => { let stars = this.querySelectorAll('[sk-stars]'); stars.forEach((currStar) => { let id = currStar.getAttribute('data-id'), starChange = this.querySelectorAll(`[data-id="${id}"].bi-star-fill`); starChange.forEach((curr, index) => { curr.addEventListener('mouseover', () => { starChange.forEach((curr, starInd) => { if (starInd <= index) { curr.setAttribute('fill', 'orange'); } }); }); curr.addEventListener('mouseout', () => { starChange.forEach(curr => { if (!curr.classList.contains('selected')) { curr.setAttribute('fill', 'currentColor'); } }); }); curr.addEventListener('click', () => { starChange.forEach(curr => { curr.classList.remove('selected'); }); starChange.forEach((curr, starInd) => { if (starInd <= index) { curr.classList.add('selected'); curr.setAttribute('fill', 'orange'); } }); currStar.querySelector(`[sk-rating-value]`).value = curr.getAttribute('data-val'); }) }); }); } afterSubmission = (scriptData) => { try { if (JSON.parse(JSON.parse(scriptData).afterSubmissionAction).formSubmissionAfterMessageJs != null) { eval(JSON.parse(JSON.parse(scriptData).afterSubmissionAction).formSubmissionAfterMessageJs); } } catch (error) { console.log(error); } } init = () => { this.formAppend('https://formbuilder.magento2extensions.com/api/'); } } customElements.define('sk-form', skFormBuilder);