-
-
Save javaidnaik/3fa5ed74cb37ad981f1d2892e36c9981 to your computer and use it in GitHub Desktop.
Dynamic Freeshipping Bar Shopify (Liquid, Javascript, CSS)
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
.fsb { | |
background-color: var(--bg-color); | |
color: var(--color); | |
font-size: 15px; | |
height: 4em; | |
} | |
.fsb .fsb-progress { | |
display: flex; | |
padding: 1em; | |
align-items: center; | |
justify-content: center; | |
text-align: center; | |
height: 100%; | |
position: relative; | |
} | |
.fsb .fsb-progress p { | |
font-size: 1em; | |
text-transform: uppercase; | |
letter-spacing: 0.1em; | |
margin: 0; | |
position: relative; | |
z-index: 2; | |
} | |
.fsb .fsb-progress p .fsb--number { | |
color: var(--accent-color); | |
font-weight: bold; | |
} | |
.fsb .fsb-progress::before { | |
content: ""; | |
width: var(--progress); | |
background-color: var(--progress-color); | |
position: absolute; | |
left: 0; | |
height: 100%; | |
transition: width 0.75s ease-in-out; | |
z-index: 1; | |
} |
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
class Fsb { | |
constructor(fsb = { selector: '#fsb', events: [], placeholder: '(x)' }) { | |
if (fsb.selector && typeof fsb.selector == 'string' && fsb.selector !== '') { | |
this.selector = fsb.selector; | |
} else { | |
throw new TypeError("Please pass a valid selector"); | |
} | |
this.fsbElement = document.querySelector(this.selector); | |
if(!this.fsbElement) { | |
throw new TypeError("Freeshipping Bar Element Not Found"); | |
} | |
this.events = fsb.events; | |
this.placeholder = fsb.placeholder; | |
this.goal = parseInt(this.fsbElement.dataset.goal); | |
this.startHeadline = this.fsbElement.dataset.headlineStart; | |
this.middleHeadline = this.fsbElement.dataset.headlineMiddle; | |
this.endHeadline = this.fsbElement.dataset.headlineEnd; | |
} | |
getCart() { | |
return fetch('/cart.js') | |
.then(res=>res.json()) | |
} | |
update(cart) { | |
let shipping = { | |
difference: this.goal - cart.total_price, | |
progress: Math.round((cart.total_price * 100) / this.goal) | |
} | |
if(cart.total_price <= 0) { | |
this.fsbElement.style.setProperty('--progress', `${shipping.progress}%`); | |
this.fsbElement.querySelector('.fsb-paragraph').innerHTML = this.startHeadline.replace(this.placeholder, `<span class="fsb--number">${this.formatMoney(this.goal)}</span>`); | |
} else if(cart.total_price > 0 && cart.total_price < this.goal) { | |
this.fsbElement.style.setProperty('--progress', `${shipping.progress}%`); | |
this.fsbElement.querySelector('.fsb-paragraph').innerHTML = this.middleHeadline.replace(this.placeholder, `<span class="fsb--number">${this.formatMoney(shipping.difference)}</span>`); | |
} else if(cart.total_price >= this.goal) { | |
this.fsbElement.style.setProperty('--progress', `${shipping.progress}%`); | |
this.fsbElement.querySelector('.fsb-paragraph').innerHTML = this.endHeadline.replace(this.placeholder, `<span class="fsb--number">${this.formatMoney(this.goal)}</span>`); | |
} | |
} | |
attachEvents() { | |
if(this.events.length > 0) { | |
this.events.forEach(event => { | |
document.addEventListener(event, e => this.getCart().then(cart => this.update(cart)), true); | |
}) | |
} | |
} | |
formatMoney(cents, format) { | |
if (typeof cents == 'string') { cents = cents.replace('.',''); } | |
var value = ''; | |
var placeholderRegex = /\{\{\s*(\w+)\s*\}\}/; | |
var formatString = (format || "${{amount_no_decimals}}"); | |
function defaultOption(opt, def) { | |
return (typeof opt == 'undefined' ? def : opt); | |
} | |
function formatWithDelimiters(number, precision, thousands, decimal) { | |
precision = defaultOption(precision, 2); | |
thousands = defaultOption(thousands, ','); | |
decimal = defaultOption(decimal, '.'); | |
if (isNaN(number) || number == null) { return 0; } | |
number = (number/100.0).toFixed(precision); | |
var parts = number.split('.'), | |
dollars = parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousands), | |
cents = parts[1] ? (decimal + parts[1]) : ''; | |
return dollars + cents; | |
} | |
switch(formatString.match(placeholderRegex)[1]) { | |
case 'amount': | |
value = formatWithDelimiters(cents, 2); | |
break; | |
case 'amount_no_decimals': | |
value = formatWithDelimiters(cents, 0); | |
break; | |
case 'amount_with_comma_separator': | |
value = formatWithDelimiters(cents, 2, '.', ','); | |
break; | |
case 'amount_no_decimals_with_comma_separator': | |
value = formatWithDelimiters(cents, 0, '.', ','); | |
break; | |
} | |
return formatString.replace(placeholderRegex, value); | |
} | |
} |
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
{% assign freeShipping = settings.fsb_goal | times: 100 %} | |
{% assign totalPrice = cart.total_price %} | |
{% assign shippingDifference = freeShipping | minus: totalPrice %} | |
{% assign shippingDifferencePercentage = shippingDifference | divided_by: 100 %} | |
{% assign shippingProgress = totalPrice | times:100 | divided_by:freeShipping | append:'%' %} | |
{% assign initial_message = settings.fsb_headline_start %} | |
{% assign middle_message = settings.fsb_headline_middle %} | |
{% assign end_message = settings.fsb_headline_end %} | |
{% assign shippingGoalWithCurrency = freeShipping | money_without_trailing_zeros | prepend:'<span class="fsb--number">'| append:'</span>' %} | |
{% assign shippingDifferenceWithCurrency = shippingDifference | money_without_trailing_zeros | prepend:'<span class="fsb--number">'| append:'</span>' %} | |
<div id="fsb" class="fsb" style="--bg-color: {{settings.fsb_background_color}}; | |
--progress-color: {{settings.fsb_progress_color}}; | |
--color: {{settings.fsb_text_color}}; | |
--accent-color: {{settings.fsb_accent_color}}; | |
--progress: {{shippingProgress}}; | |
" | |
data-headline-start="{{settings.fsb_headline_start}}" | |
data-headline-middle="{{settings.fsb_headline_middle}}" | |
data-headline-end="{{settings.fsb_headline_end}}" | |
data-goal="{{freeShipping}}"> | |
<div class="fsb-progress"> | |
{% if cart.total_price <= 0 %} | |
<p class="fsb-paragraph"> | |
{{ initial_message | replace: "(x)", shippingGoalWithCurrency }} | |
</p> | |
{% elsif cart.total_price > 0 and cart.total_price < freeShipping %} | |
<p class="fsb-paragraph"> | |
{{ middle_message | replace: '(x)', shippingDifferenceWithCurrency }} | |
</p> | |
{% elsif cart.total_price >= freeShipping %} | |
<p class="fsb-paragraph"> | |
{{ end_message | replace: "(x)", shippingGoalWithCurrency }} | |
</p> | |
{% endif %} | |
</div> | |
</div> |
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
{ | |
"name": "Freeshipping Bar", | |
"settings": [ | |
{ | |
"type": "checkbox", | |
"id": "fsb_enable", | |
"label": "Enable/Disable Free Shipping Bar", | |
"default": true | |
}, | |
{ | |
"type": "checkbox", | |
"id": "fsb_ajax", | |
"label": "Enable/Disable Ajax Functionality", | |
"default": true | |
}, | |
{ | |
"type": "header", | |
"content": "Goal" | |
}, | |
{ | |
"type": "range", | |
"id": "fsb_goal", | |
"min": 1, | |
"max": 100, | |
"step": 1, | |
"unit": "$", | |
"label": "Goal", | |
"default": 5 | |
}, | |
{ | |
"type": "header", | |
"content": "Headline Steps" | |
}, | |
{ | |
"type": "text", | |
"id": "fsb_headline_start", | |
"label": "Start Headline", | |
"default": "If you add (x) worth of products to your cart, you'll get Freeshipping!", | |
"info": "Use the special character '(x)' as a placeholder for the 'Goal' amount" | |
}, | |
{ | |
"type": "text", | |
"id": "fsb_headline_middle", | |
"label": "Middle Headline", | |
"default": "You are (x) away from Freeshipping!", | |
"info": "Use the special character '(x)' as a placeholder for the 'Remaining' amount" | |
}, | |
{ | |
"type": "text", | |
"id": "fsb_headline_end", | |
"label": "End Headline", | |
"default": "You have Freeshipping!", | |
"info": "Use the special character '(x)' as a placeholder for the 'Goal' amount" | |
}, | |
{ | |
"type": "header", | |
"content": "Colors" | |
}, | |
{ | |
"type": "color", | |
"id": "fsb_background_color", | |
"label": "Background Color", | |
"default": "#000000" | |
}, | |
{ | |
"type": "color", | |
"id": "fsb_progress_color", | |
"label": "Progress Bar Color", | |
"default": "#006fbb" | |
}, | |
{ | |
"type": "color", | |
"id": "fsb_text_color", | |
"label": "Text Color", | |
"default": "#FFFFFF" | |
}, | |
{ | |
"type": "color", | |
"id": "fsb_accent_color", | |
"label": "Accent Color", | |
"default": "#c03" | |
} | |
] | |
} |
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
//ADD THIS BEFORE </head> | |
{% if settings.fsb_enable %} | |
{{ 'hc-freeshipping-bar.css' | asset_url | stylesheet_tag }} | |
{% if settings.fsb_ajax %} | |
{{ 'hc-freeshipping-bar.js' | asset_url | script_tag }} | |
<script> | |
document.addEventListener('DOMContentLoaded', function() { | |
const freeshippingBar = new HCFsb({ | |
selector: '#hc-fsb', // Selector of the HTML template (Snippet) | |
events: ['fsb:product:added', 'fsb:cart:update'], //Events used to update the FSB | |
placeholder: '(x)' //Placeholder character to replace the goal/remaining amount in the FSB headline | |
}); | |
freeshippingBar.attachEvents(); | |
}); | |
</script> | |
{% endif %} | |
{% endif %} | |
//ADD THIS WHEREVER YOU WANT THE FSB TO APPEAR | |
{% if settings.fsb_enable %} | |
{% render 'hc-freeshipping-bar' %} | |
{% endif %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment