hello I want to include a dynamic shipping bar like this
to my cart via code. Im using the shopify Impulse theme.
So far I’ve created this snippet:
{% if cart != empty %}
{% assign progressThresholdDollars = settings.cart_progress_threshold %}
{% assign progressThreshold = progressThresholdDollars | times: 100 %}
{% assign preGoalMessageTemplate = settings.cart_pre_goal_message %}
{% assign postGoalMessage = settings.cart_post_goal_message %}
{% assign cartTotal = cart.total_price %}
{% assign progressPercentage = cartTotal | times: 100 | divided_by: progressThreshold %}
{% if progressPercentage > 100 %}
{% assign progressPercentage = 100 %}
{% endif %}
{% assign remainingForGoal = progressThreshold | minus: cartTotal %}
{% if remainingForGoal < 0 %}
{% assign remainingForGoal = 0 %}
{% endif %}
{% assign remainingForGoalFormatted = remainingForGoal | money %}
{% assign dynamicPreGoalMessage = preGoalMessageTemplate | replace: '[remainingForGoalFormatted]', remainingForGoalFormatted %}
<div id="cart-progress-wrapper"
class="{% if progressPercentage == 100 %}full{% else %}not-full{% endif %}"
data-threshold="{{ progressThreshold }}"
data-pre-goal-message-template="{{ preGoalMessageTemplate | escape }}"
data-post-goal-message="{{ postGoalMessage | escape }}"
>
<div class="cart-progress-bar-container">
<div id="cart-progress-bar" style="width: {{ progressPercentage }}%;"></div>
</div>
<div class="goal-message">
{% if remainingForGoal > 0 %}
{{ dynamicPreGoalMessage }}
{% else %}
{{ postGoalMessage }}
{% endif %}
</div>
</div>
{% endif %}
<style>
.cart-progress-bar-container {
width: 100%;
background-color: #eee;
border-radius: 10px;
margin: 2px auto;
padding: 1px;
overflow: hidden;
}
#cart-progress-bar {
display: block;
height: 10px;
background-color: var(--progress-bar-color, {{ settings.cart_progress_bar_color }}); /* Default color */
border-radius: 2px;
transition: width 0.5s ease-in-out;
border: 1px solid var(--progress-bar-border-color, {{ settings.cart_progress_bar_color }});
padding: 5px 0;
box-sizing: border-box;
}
#cart-progress-wrapper.full #cart-progress-bar {
--progress-bar-color: {{ settings.cart_progress_bar_full_color }};
--progress-bar-border-color: {{ settings.cart_progress_bar_full_color }};
}
.goal-message {
text-align: center;
margin: 2px auto 10px;
font-size: 1em;
color: #333;
}
</style>
added this setting to schema:
{
"type": "header",
"content": "Cart Progress Bar Settings"
},
{
"type": "text",
"id": "cart_progress_threshold",
"label": "Progress Threshold",
"default": "49",
"info": "Set the cart total required to unlock the goal."
},
{
"type": "text",
"id": "cart_pre_goal_message",
"label": "Pre-Goal Message",
"default": "You're only [remainingForGoalFormatted] away from <strong>FREE SHIPPING</strong>",
"info": "Message displayed before reaching the goal. Use [remainingForGoalFormatted] to insert the dynamic remaining amount."
},
{
"type": "text",
"id": "cart_post_goal_message",
"label": "Post-Goal Message",
"default": "? Congrats! You've unlocked <strong>FREE SHIPPING</strong>",
"info": "Message displayed after reaching the goal."
},
{
"type": "color",
"id": "cart_progress_bar_color",
"label": "Progress Bar Color",
"default": "#d53600",
"info": "Color of the progress bar."
},
{
"type": "color",
"id": "cart_progress_bar_full_color",
"label": "Progress Bar Full Color",
"default": "#d53600",
"info": "Color of the progress bar when complete."
}
this to the main.cart.liquid:
{%- unless settings.cart_type == 'drawer' -%}
{% render 'cart-progress-bar-custom' %}
{%- endunless -%}
this to the cart.drawer.liquid:
{% render 'cart-progress-bar-custom' %}
I was planning to add this code to my theme.js but everytime I do that the images are not loading anymore and the cart fails to change the shipping bar dynamically. Any help on what to adapt?
const updatedCartTotal = parsedState.total_price;
this.updateProgressBar(updatedCartTotal);
updateProgressBar(cartTotal, itemCount) {
const progressWrapper = document.getElementById('cart-progress-wrapper');
const progressThreshold = parseInt(progressWrapper.dataset.threshold, 10);
const preGoalMessageTemplate = progressWrapper.dataset.preGoalMessageTemplate;
const postGoalMessage = progressWrapper.dataset.postGoalMessage;
const progressBar = document.getElementById('cart-progress-bar');
const goalMessageElement = document.querySelector('.goal-message');
if (itemCount === 0 || cartTotal === 0) {
if (progressWrapper) {
progressWrapper.style.display = 'none';
}
if (goalMessageElement) {
goalMessageElement.style.display = 'none';
}
} else {
if (progressWrapper) {
progressWrapper.style.display = 'block';
}
if (progressBar) {
progressBar.style.display = 'block';
const progressPercentage = Math.min((cartTotal / progressThreshold) * 100, 100);
progressBar.style.width = `${progressPercentage}%`;
if (progressPercentage >= 100) {
progressWrapper.classList.add('full');
} else {
progressWrapper.classList.remove('full');
}
}
if (goalMessageElement) {
goalMessageElement.style.display = 'block';
let remainingForGoal = progressThreshold - cartTotal;
if (remainingForGoal < 0) {
remainingForGoal = 0;
}
const remainingAmountFormatted = `$${(remainingForGoal / 100).toFixed(2)}`;
const preGoalMessage = preGoalMessageTemplate.replace('[remainingForGoalFormatted]', remainingAmountFormatted);
goalMessageElement.innerHTML = remainingForGoal > 0
? preGoalMessage
: postGoalMessage;
}
}
}

