Created
December 4, 2024 13:34
-
-
Save sandipklevu/6660115e410c512334099fbbc9f15faf to your computer and use it in GitHub Desktop.
Klevu Template Custom Price Fetch from BigCommerce
This file contains 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
<script type="text/javascript"> | |
var klevuIdsWithKeys = []; | |
klevu.interactive(function () { | |
function formatPrice(price, currency, locale = navigator.language) { | |
return new Intl.NumberFormat(locale, {style: 'currency', currency: currency}).format(price); | |
} | |
function findProductList(data) { | |
return data.find(item => item.id === 'productList'); | |
} | |
function clearElementsById(elements) { | |
elements.forEach((element) => { | |
if (typeof element === 'string') { | |
element = document.getElementById(element); | |
} | |
if (element) { | |
element.innerHTML = ''; | |
} | |
}); | |
} | |
function cleanUpProductId(id) { | |
if (typeof id === 'undefined' || id === '') { | |
return false; | |
} | |
let pid = id.toUpperCase(); | |
if (pid.indexOf('-') !== -1) { | |
pid = pid.split('-')[0]; | |
} | |
return pid; | |
} | |
function fetchPrices(klevuIds, callback) { | |
const finalEntIds = []; | |
let bcId = ''; | |
klevuIds.forEach(function (id) { | |
bcId = cleanUpProductId(id); | |
finalEntIds.push(bcId); | |
klevuIdsWithKeys.push(bcId); | |
}); | |
console.log('finalIds before request to BC: '+ finalEntIds); | |
fetch('/graphql', { | |
method: 'POST', | |
credentials: 'same-origin', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer {{ settings.storefront_api.token }}' // use auto-generated token | |
}, | |
body: JSON.stringify({ | |
query: `query FetchGroupPrices { | |
site { | |
products(entityIds:[` + finalEntIds + `],first:50){ | |
edges { | |
node { | |
id | |
entityId | |
sku | |
prices(currencyCode: {{currency_selector.active_currency_code}}) { | |
price { | |
...PriceFields | |
} | |
salePrice { | |
...PriceFields | |
} | |
basePrice { | |
...PriceFields | |
} | |
retailPrice { | |
...PriceFields | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
fragment PriceFields on Money { | |
currencyCode | |
value | |
}` | |
}) | |
}) | |
.then(res => res.json()) | |
.then(callback) | |
.catch(error => console.error(error)); | |
} | |
function renderPricesOnFrontend( | |
result, | |
productList, | |
priceSelector, | |
listItemSelector, | |
country, | |
currency | |
) { | |
if (!result.data) { | |
return; | |
} | |
const priceBeforeDiscountSelector = priceSelector.replace('Sale', 'Orig'); | |
const helpers = klevu.search.base.getScope().template.getHelpers(); | |
const resNodes = result.data.site.products.edges || {}; | |
if (!resNodes) { | |
return; | |
} | |
helpers.clearElementsById(document.querySelectorAll(priceSelector)); | |
helpers.clearElementsById(document.querySelectorAll(priceBeforeDiscountSelector)); | |
var idx = 0; | |
const resultObject = resNodes; | |
// Loop through all the items from the current Klevu response | |
for (const currentProduct of productList) { | |
const {id: product_id} = currentProduct; | |
var klevuPId = cleanUpProductId(product_id).toString(); | |
// return if the product is excluded from the store and there's no data for it | |
if (resultObject[idx].node['entityId'] === null) continue; | |
resultObject.forEach(item => { | |
const bEntityId = item.node.entityId.toString(); | |
if (bEntityId === klevuPId) { | |
var basePrice = item.node['prices']['basePrice']['value']; | |
var price = item.node['prices']['price']['value']; | |
var salePrice = item.node['prices']['salePrice'] ? item.node['prices']['salePrice']['value'] : ''; | |
const label = ''; | |
// Now, we are selecting the proper elements by ID and grab prices from our POST request | |
const listPriceItems = document.querySelectorAll(`${listItemSelector}[data-id="${product_id}"]`); // our parent element, referring by ID | |
[...listPriceItems].forEach((list) => { | |
const salePriceItem = list.querySelector(priceSelector); | |
const origPriceItem = list.querySelector(priceBeforeDiscountSelector); | |
domModifyPriceChange(salePriceItem, origPriceItem); | |
}); | |
function domModifyPriceChange(salePriceItem, origPriceItem) { | |
const priceFinal = helpers.formatPrice(price, currency, country); | |
const priceBeforeDiscount = helpers.formatPrice(basePrice, currency, country); | |
if (salePriceItem) { | |
salePriceItem.innerHTML = `<span data-bigc-price="${priceFinal}" class="klevu-cg-prices">${label} ${priceFinal}</span>`; | |
} | |
if (origPriceItem && parseFloat(price) > parseFloat(salePrice)) { | |
origPriceItem.innerHTML = `<span data-globalE-price="${priceBeforeDiscount}" class="klevu-cg-prices">${priceBeforeDiscount}</span>`; | |
} | |
} | |
} | |
}); | |
} | |
idx++; | |
} | |
klevu.search.base.getScope().template.setHelper('formatPrice', formatPrice); | |
klevu.search.base.getScope().template.setHelper('findProductList', findProductList); | |
klevu.search.base.getScope().template.setHelper('clearElementsById', clearElementsById); | |
klevu.search.base.getScope().template.setHelper('fetchPrices', fetchPrices); | |
klevu.search.base.getScope().template.setHelper('cleanUpProductId', cleanUpProductId); | |
klevu.search.base.getScope().template.setHelper('renderPricesOnFrontend', renderPricesOnFrontend); | |
}); | |
//Below code is for quick search. | |
klevu.afterTemplateRender("quick", function (data, scope) { | |
const helpers = klevu.search.base.getScope().template.getHelpers(); | |
const salePriceSelector = '.klevuQuickSalePrice'; | |
const kuProductSelector = '.kuQuickResultsListContainer .klevuProduct'; | |
if (typeof klevu_currentCurrencyCode === 'undefined') { | |
let klevu_currentCurrencyCode = "{{currency_selector.active_currency_code}}"; | |
} | |
helpers.clearElementsById(document.querySelectorAll(salePriceSelector)); | |
const klevuResponse = klevu.getObjectPath(data, "response.current.queryResults"); | |
const productList = typeof helpers.findProductList(klevuResponse) !== 'undefined' | |
? (helpers.findProductList(klevuResponse)).records | |
: null; | |
if (!productList) return; | |
const arrayIDs = productList.map(element => element.id); | |
helpers.fetchPrices(arrayIDs, (result) => { | |
helpers.renderPricesOnFrontend( | |
result, | |
productList, | |
salePriceSelector, | |
kuProductSelector, | |
'US', | |
klevu_currentCurrencyCode | |
); | |
}); | |
}); | |
klevu.afterTemplateRender("full_page", function (data, scope) { | |
const helpers = klevu.search.base.getScope().template.getHelpers(); | |
const salePriceSelector = '.kuSalePrice'; | |
const origPriceSelector = '.kuOrigPrice'; | |
const kuProductSelector = '.klevuProduct'; | |
if (typeof klevu_currentCurrencyCode === 'undefined') { | |
let klevu_currentCurrencyCode = "{{currency_selector.active_currency_code}}"; | |
} | |
const klevuResponse = klevu.getObjectPath(data, "response.current.queryResults"); | |
const productList = typeof helpers.findProductList(klevuResponse) !== 'undefined' | |
? (helpers.findProductList(klevuResponse)).records | |
: null; | |
if (!productList) return; | |
const arrayIDs = productList.map(element => element.id); | |
//console.log(JSON.stringify(arrayIDs)); | |
helpers.fetchPrices(arrayIDs, (result) => { | |
helpers.renderPricesOnFrontend( | |
result, | |
productList, | |
salePriceSelector, | |
kuProductSelector, | |
'US', //change this | |
klevu_currentCurrencyCode | |
); | |
}); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment