Created
August 11, 2021 13:12
-
-
Save husseyexplores/2e6d18a934387cc9150c44c9085f708c to your computer and use it in GitHub Desktop.
[Klaviyo Integration] Klaviyo signup form & BIS #klaviyo
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
<button type="button" class="btn klaviyo-bis-trigger-custom" {% if product.selected_or_first_available_variant.available %}style="display: none;"{% endif %}>Notify me when available</button> | |
<div | |
id="KlaviyoBIS-{{ product.id }}" | |
class="modal modal--square modal--mobile-friendly klaviyo-bis-popup" | |
data-product-id="{{ product.id }}" | |
> | |
<div class="modal__inner"> | |
<div class="modal__centered medium-up--text-center"> | |
<div class="modal__centered-content"> | |
<div class="klaviyo-bis"> | |
<h2>{{ product.title }}</h2> | |
<p>{{ 'products.back_in_stock.popup_body_content' | t }}</p> | |
<div class="form-vertical" style="padding-top: 15px;"> | |
<form action="#" class="klaviyo-bis-form-custom"> | |
<input type="hidden" name="subscribe_for_newsletter" value="true"> | |
<input type="hidden" name="platform" value="shopify"> | |
<input type="hidden" name="g" value="RzPhNs"> <!-- lst id --> | |
<input type="hidden" name="a" value="QQyd2Z"> <!-- pub api key --> | |
<input type="hidden" name="product" value="{{ product.id }}"> | |
<div {% if product.variants.size == 1 %}style="display: none;"{% endif %}> | |
<label for="KlaviyoBIS-{{ product.id }}--variants">Options</label> | |
<select id="KlaviyoBIS-{{ product.id }}--variants" name="variant" class="variants" style="width: 100%;"> | |
{%- for v in product.variants -%} | |
{%- unless v.available -%} | |
<option value="{{ v.id }}">{{ v.title }}</option> | |
{%- endunless -%} | |
{%- endfor -%} | |
</select> | |
</div> | |
<label for="KlaviyoBIS-{{ product.id }}--name">Name</label> | |
<input type="tel" id="KlaviyoBIS-{{ product.id }}--name" class="input-full" name="name" value="{% if customer %}{{ customer.first_name | default: '' }} {{ customer.last_name | default: '' }}{% endif %}"> | |
<label for="KlaviyoBIS-{{ product.id }}--name">Email *</label> | |
<input type="email" id="KlaviyoBIS-{{ product.id }}--email" class="input-full" name="email" autocorrect="off" autocapitalize="off" value="" required> | |
<label for="KlaviyoBIS-{{ product.id }}--phone">Phone Number</label> | |
<input type="tel" id="KlaviyoBIS-{{ product.id }}--phone" class="input-full" name="phone_number" pattern="[0-9\-]*" value="{% if customer %}{{ customer.phone | default: '' }}{% endif %}"> | |
<div class="completed_message alert" style="display: none;">{{ 'products.back_in_stock.subscription_success_label' | t }} <a href="#" role="button" class="text-close js-modal-close">Close</a></div> | |
<div class="error_message alert" style="display: none;"></div> | |
<button class="btn submit-btn" style="width: 100%;">{{ 'products.back_in_stock.popup_button_label' | t }}</button> | |
</form> | |
</div> | |
<!-- <button type="button" class="text-close js-modal-close">Close</button> --> | |
</div> | |
</div> | |
<button type="button" class="modal__close js-modal-close text-link"> | |
<svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-close" viewBox="0 0 64 64"><path d="M19 17.61l27.12 27.13m0-27.12L19 44.74"/></svg> | |
<span class="icon__fallback-text">{{ 'general.accessibility.close_modal' | t | json }}</span> | |
</button> | |
</div> | |
</div> | |
</div> | |
<script> | |
(function() { | |
function domReady(fn) { | |
// If we're early to the party | |
document.addEventListener("DOMContentLoaded", fn); | |
// If late; I mean on time. | |
if (document.readyState === "interactive" || document.readyState === "complete" ) { | |
fn(); | |
} | |
} | |
let pid = {{ product.id }}; | |
let currentVId = {{ product.selected_or_first_available_variant.id }}; | |
domReady(function() { | |
let id = 'KlaviyoBIS-' + pid | |
let modal = new theme.Modals(id, id) | |
let modalElement = document.getElementById(id) | |
let productSection = document.getElementById('ProductSection-' + pid) | |
if (productSection) { | |
let trigger = productSection.querySelector('.klaviyo-bis-trigger-custom') | |
let bisForm = productSection.querySelector('.klaviyo-bis-form-custom') | |
let submitBtn = bisForm.querySelector('.submit-btn') | |
let bisFormVariants = bisForm.querySelector('.variants') | |
let succEl = bisForm.querySelector('.completed_message') | |
let errEl = bisForm.querySelector('.error_message') | |
let variantOptionsArray = Array.from(bisFormVariants.options) | |
productSection.addEventListener('variantChange', e => { | |
let variant = e.detail.variant | |
let available = variant.available | |
currentVId = variant.id | |
if (!available) { | |
trigger.style.display = 'block' | |
} else { | |
trigger.style.display = 'none' | |
} | |
}) | |
trigger.addEventListener('click', function() { | |
bisFormVariants.selectedIndex = variantOptionsArray.findIndex(x => x.value == currentVId) | |
modal.open(); | |
}) | |
bisForm.addEventListener('submit', e => { | |
console.log('submit') | |
e.preventDefault(); | |
e.stopPropagation(); | |
if (bisForm.checkValidity()) { | |
postFormData() | |
} | |
}) | |
function postFormData() { | |
succEl.style.display = 'none' | |
errEl.style.display = 'none' | |
var formData = new FormData(bisForm); | |
var data = {}; | |
formData.forEach((value, key) => { | |
value = typeof value === 'string' ? value.trim() : value | |
if (value) { | |
if (key == 'name') { | |
let nameParts = value.split(' ') | |
if (nameParts[0]) { | |
data.$first_name = nameParts[0] | |
} | |
if (nameParts[1]) { | |
data.$last_name = nameParts[1] | |
} | |
} else { | |
data[key] = value; | |
} | |
} | |
}); | |
console.log(data) | |
if (!data.email || !data.variant || !data.product) { | |
return | |
} | |
// data.variant = 1338281066525 | |
// data.product = 114834341917 | |
submitBtn.setAttribute('disabled', 'true') | |
fetch("https://a.klaviyo.com/onsite/components/back-in-stock/subscribe", { | |
"headers": { | |
"accept": "*/*", | |
"accept-language": "en-US,en;q=0.9", | |
"content-type": "application/x-www-form-urlencoded", | |
}, | |
"body": objToStrUrlEncode(data), | |
"method": "POST", | |
"mode": "cors", | |
"credentials": "omit" | |
}) | |
.then(r => r.json()) | |
.then(r => { | |
if (r.status == 200 || r.success) { | |
succEl.style.display = 'block' | |
submitBtn.style.display = 'none' | |
subscribeToList(data) | |
} else { | |
errEl.innerHTML = r.message | |
errEl.style.display = 'block' | |
submitBtn.removeAttribute('disabled') | |
} | |
}) | |
} | |
function subscribeToList(data) { | |
let newData = { $email: data.email, a: data.a, g: data.g, $fields: [] } | |
if (data.$first_name) { | |
newData.$first_name = data.$first_name | |
newData.$fields.push('$first_name') | |
} | |
if (data.$last_name) { | |
newData.$last_name = data.$last_name | |
newData.$fields.push('$last_name') | |
} | |
if (data.phone_number) { | |
newData.$phone_number = data.phone_number | |
newData.$fields.push('$phone_number') | |
} | |
newData.$fields = newData.$fields.join(',') | |
fetch("https://a.klaviyo.com/ajax/subscriptions/subscribe", { | |
"headers": { | |
"accept": "*/*", | |
"accept-language": "en-US,en;q=0.9", | |
"access-control-allow-headers": "*", | |
"content-type": "application/x-www-form-urlencoded; charset=UTF-8", | |
}, | |
"referrer": "https://help.klaviyo.com/", | |
"referrerPolicy": "strict-origin-when-cross-origin", | |
"body": objToStrUrlEncode(newData), | |
"method": "POST", | |
"mode": "cors", | |
"credentials": "omit" | |
}) | |
} | |
function objToStrUrlEncode(obj) { | |
const str = []; | |
for (var key in obj) { | |
if (obj.hasOwnProperty(key) && typeof obj[key] !== 'undefined') { | |
str.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key])) | |
} | |
} | |
return str.join('&') | |
} | |
} | |
}) | |
})(); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Glad you found it useful! You can ping me if you get stuck or need any pointers.