Skip to content

Instantly share code, notes, and snippets.

@husseyexplores
Created August 11, 2021 13:12
Show Gist options
  • Save husseyexplores/2e6d18a934387cc9150c44c9085f708c to your computer and use it in GitHub Desktop.
Save husseyexplores/2e6d18a934387cc9150c44c9085f708c to your computer and use it in GitHub Desktop.
[Klaviyo Integration] Klaviyo signup form & BIS #klaviyo
<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>
@husseyexplores
Copy link
Author

Glad you found it useful! You can ping me if you get stuck or need any pointers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment