Skip to content

Instantly share code, notes, and snippets.

@guilhermechapiewski
Last active April 13, 2025 17:26
Show Gist options
  • Save guilhermechapiewski/dc2b2570679c43ac3b80ddab88acc43e to your computer and use it in GitHub Desktop.
Save guilhermechapiewski/dc2b2570679c43ac3b80ddab88acc43e to your computer and use it in GitHub Desktop.
2peaksbikes.com Ecwid customization script to show our Booxi appointment booking widget properly.
var foundDynElements = false;
var dynElementsInterval = null;
var tpbBookingOpen = false;
const tpbStartInterval = function() {
if ((foundDynElements == false) && (!dynElementsInterval)) {
dynElementsInterval = setInterval(function(){
tpbAttachBookingLink();
}, 500);
}
};
const tpbCancelInterval = function() {
clearInterval(dynElementsInterval);
};
const tpbHide = function(element_class_name) {
const bookingLink = document.getElementById('2pb_book');
if (bookingLink) {
var elements = document.getElementsByClassName(element_class_name);
if (elements) {
Array.prototype.forEach.call(elements, (element) => {
element.style.display = "none";
});
}
}
};
const tpbHideButtons = function() { tpbHide("grid-product__buy-now"); };
const tpbHideProductDetails = function() { tpbHide("product-details__action-panel"); };
const tpbBookingOnCloseCallback = function() {
//location.reload();
tpbBookingOpen = false;
};
const tpbAttachBookingLinkToElement = function(element) {
if (element) {
foundDynElements = true;
element.addEventListener('click', function(event) {
const linkTitle = element.title;
if (!tpbBookingOpen) {
tpbBookingOpen = true;
BookNow.open({apiKey:'252OKm68e7c52A5LDXTb8q7ZO03362Vv', language:'en', iframeId:'booxi_custom_iframe_id', serviceTags:linkTitle, onClose:tpbBookingOnCloseCallback});
}
event.preventDefault();
}, true);
tpbHideButtons();
tpbHideProductDetails();
tpbCancelInterval();
}
}
const tpbAttachBookingLinkToElementsInArray = function(elementsArray) {
if (elementsArray) {
for (var i=0; i<elementsArray.length; i++) {
tpbAttachBookingLinkToElement(elementsArray[i]);
}
}
}
const tpbAttachBookingLink = function() {
tpbAttachBookingLinkToElement(document.getElementById('2pb_book'));
tpbAttachBookingLinkToElementsInArray(Array.from(document.querySelectorAll('.ins-control')).filter(el => el.querySelector('.ins-control__text')?.textContent === 'Book it now!'));
};
const observer = new MutationObserver(mutations => { tpbAttachBookingLink(); });
const tpbObserve = function(element, config) { if (element) { observer.observe(element, config); } }
const tpbObserveMultiple = function(elements, config) { if (elements) { for (var i=0; i<elements.length; i++) { tpbObserve(elements[i], config); } } }
const tpbStartObservers = function() {
const config = { attributes: true, childList: true, subtree: true, characterData: true };
tpbObserve(document.querySelector('#tile-product-details'), config);
tpbObserve(document.querySelector('.ins-tiles--main'), config);
tpbObserveMultiple(Array.from(document.querySelectorAll('.ins-control')).filter(el => el.querySelector('.ins-control__text')?.textContent === 'Book it now!'), config);
tpbObserve(document, config);
};
const tpbAddEventListener = function(element, eventName) {
element.addEventListener(eventName, function(event) {
tpbStartInterval(); tpbStartObservers();
});
}
tpbAddEventListener(document, 'DOMContentLoaded');
tpbAddEventListener(window, 'load');
tpbAddEventListener(window, 'popstate');
tpbAddEventListener(window, 'click');
setTimeout(function(){
console.log('3.5 second timeout searching for link');
tpbHideButtons();
tpbHideProductDetails();
tpbCancelInterval();
}, 3500);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment