Updating the Progress Bar in Shopify when the "Add to Cart" button is clicked: A step-by

I'm currently working on implementing a shipping progress bar on my Shopify Theme. However, I've encountered an issue where the progress bar does not update correctly unless I refresh the page along with the content text.

Can anyone provide guidance or assistance with this project?

For a live demonstration, you can view it here:

The placement of my progress bar is above the add to cart button. https://i.sstatic.net/KO1ne.png

JavaScript Code:

  var $freeShippingClass = $('.js-free-shipping'),
      $freeShippingTextClass = $('.js-free-shipping-text'),
      $free_fisrt = $freeShippingClass.attr('data-start'),
      $free_end = $freeShippingClass.attr('data-end')
      minOrderValue = parseInt($freeShippingClass.data('value')) || 0,
      $percentClass = $('.js-free-shipping .progress-bar');

  function generate(cart){
    var priceCart = cart.total_price;
    if (priceCart >= minOrderValue){
      $percentClass.css('width','100%').removeClass('progress-bar-striped bg-primary');
      $freeShippingTextClass.text(theme.strings.freeShipping)
    }else{
      let percent = priceCart / minOrderValue * 100;
      let left = Shopify.formatMoney((minOrderValue - priceCart),theme.moneyFormat);
      $percentClass.css('width',percent+'%').addClass('progress-bar-striped primary');
      $freeShippingTextClass.html($free_fisrt +' '+ left +' '+ $free_end);
      theme.updateCurrencies();
    }
  }

  Shopify.getCart(function(cart){
    generate(cart);
  });

  return {
    load:generate
  }
})()

Shipping.liquid

  <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuemin="0" aria-valuemax="100"></div>
  <span class="free-shipping-content">
    <span class="js-free-shipping-text">
    </span>
  </span>
</div>

CSS

.js-free-shipping{
  position: relative;
  height: 30px;
  margin:0 0 15px;
  background:#343a40;
  border-radius:0;
  font-size: val(--g-font-size);
  #jsCrosssell &{
    margin-bottom:0;
    .progress-bar{
      -webkit-animation:none;
      animation:none;
    }
  }
  .mini-cart-content &{
    .progress-bar{
      -webkit-animation:none;
      animation:none;
    }
  }
}
.js-free-shipping-text{
  .mini-cart-content &{
    font-size:calc(val(--g-font-size) - 2px);
  }
}
.mini-cart-content{
  .js-free-shipping{
    margin-top:15px;
  }
}

.free-shipping-content{
  position: absolute;
  width: 100%;
  text-align: center;
  line-height: 30px;
  color: white;
  font-weight: bold;
  left:0;
  .svg,[class^=svg-]{
    margin:-2px 10px 0 0 ;
  }
}

Answer №1

One of the issues you may be facing is that your progress bar only updates on a page reload because Cart information is fetched only once on page load. When a user makes changes to their cart using the Shopify Ajax API without refreshing the page, the progress bar becomes outdated as it does not trigger the function again. To resolve this, you need to monitor cart updates and re-call your function.

By implementing code found on Shopify Cart Update Events, you can modify your code like so:

const open = window.XMLHttpRequest.prototype.open;

function openReplacement() {
  this.addEventListener("load", function () {
    if (
      [
        "/cart/add.js",
        "/cart/update.js",
        "/cart/change.js",
        "/cart/clear.js",
      ].includes(this._url)
    ) {
      generate(this.response);
    }
  });
  return open.apply(this, arguments);
}

window.XMLHttpRequest.prototype.open = openReplacement;

Now, whenever the cart is updated, your generate function will be triggered again with the most recent cart information.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips on adjusting the OrbitControls target for navigation movement?

How can I make the orbitcontrols focus on a selected object for navigation? I see there is a center/target attribute, but I'm unsure how to set it to the object I have chosen. I attempted the following: var controls = this.controls = new THREE.Edito ...

What methods does Angular use to display custom HTML tags in IE9/10 without causing any issues for the browser?

Exploring web components and utilizing customElements.define tends to cause issues in IE9/10. I've noticed that Angular is compatible with IE9/10, and upon inspecting the DOM tree, it seems like Angular successfully displays the custom element tags. ...

identifying HTTP requests originating from an embedded iframe

I have a unique scenario where there is an iframe on my page that calls a URL from a different domain. Occasionally, this URL will tunnel to a different URL than the one I specified. Unfortunately, due to cross-domain restrictions, I am unable to view the ...

Error encountered in Intellij for Typescript interface: SyntaxError - Unexpected identifier

I am currently testing a basic interface with the following code: interface TestInterface { id: number; text: string; } const testInterfaceImplementation: TestInterface = { id: 1, text: 'sample text' }; console.log(testInterface ...

Can you recommend a technology similar to WebSockets that does not rely on a framework like Node.js?

I am currently developing a basic betting game and I want to enhance the user experience by updating values in real-time. The challenge is that most of my application is written in jQuery and JavaScript, with a MySQL database set up by a different develo ...

Ways to emphasize the current tab on the site's navigation bar?

Here's my question: I have a menu with different items, and I want to make sure that the active tab is highlighted when users switch to another page. I noticed that Stack Overflow uses the following CSS: .nav { float: left; font-size: 1 ...

Is there a different way to retrieve the tag name of an element besides using

Currently, I am dealing with an outdated version (Chromium 25) of chromium. My goal is to utilize the tagName method in order to retrieve the name of the specific HTML tag being used. While I am aware that Element.tagName functions for versions 43 and ab ...

"Make sure to tick the checkbox if it's not already selected,

Could use some assistance with traversing and logic in this scenario. Here is the logic breakdown: If any checkbox in column3 is checked, then check the first column checkbox. If none in column 3 are selected, uncheck checkbox in column1. If column1 ...

Incorporating interactive maps into an AngularJS web application

I've been attempting to integrate Google Maps into my AngularJS application, using the script tag below: <script src="https://maps.googleapis.com/maps/api/js?key=[MySecretKeyHere]&callback=initMap" async defer></script> I found this ...

Attempting to set a JavaScript variable as the placeholder value without any user interaction in Next.js

In my form, I have four inputs: token_name, token_expire_date, token_issue_date, and token_value. The first two require user input, while the second two are predetermined values (token_issue_date and token_value). Despite being predetermined, I need all th ...

$q.all - successfully resolving some HTTP requests while encountering errors on others

I encountered a coding scenario like this angular.forEach(config.tvshows.shows, function(show) { promises.push($http.get('http://epguides.frecar.no/show/' + show.replace(/\s|\./g, '') + '/next/')); }); re ...

Challenges arise with the Boostrap grid system, overflow scroll functionality, and responsive design when incorporating specific heights (vh) in elements

Attempting to implement a two-column layout using Bootstrap 4 that incorporates an overflow scroll feature when the height of a parent container is specified. You can view the fiddle here: https://jsfiddle.net/zeropsi/g19kzpsh/ The challenge I'm fac ...

Looking to include some extra padding when an item is displayed - jQuery

So, I'm working on a jQuery code snippet that controls the visibility of a rectangle element: $("#rectangle").hide(); $("#toggle-rec").click(function () { $("#rectangle").toggle(2000); }); This code hides the rectangle initially and toggles it ...

Utilizing Next.js to create dynamic routes and static builds incorporating unique ID values within the URL paths

Is there a way to create a page in Next.js where I can extract the ID from the URL in a dynamic route and use it for a static build without having to predefine all possible values of the ID in getStaticProps()? For example, the URL is as follows: localhost ...

Is there a way to automatically insert a timestamp into a table row and increment the tote number when it changes?

After the user enters their initials, I need to automatically add a timestamp followed by a new line. The tote number of the next line should also increment to the next number (e.g., on line 2, the tote number will be 2). This is the structure of my table ...

Clicking on text will open a popup div using HTML and CSS

I am looking to create a popup div instead of a popup window for my 'About' picture/page with the current button. Here is an example: ...

Combining file and JSON data in React and Express: A guide to uploading both simultaneously

I am looking to send both a file and JSON data from a form using my react handle submission method. const formData = new FormData(); formData.append('File', selectedFile); const data = { name: 'vasu', email: 'example@example ...

What is the best way to display a header element in front of an article element?

I'm struggling with making my header element sticky and appear in front of my article. Modifying the z-index hasn't given me the desired result so far. Is the z-index ineffective when dealing with floating elements? Or is there a workaround to m ...

Choosing a radio button based on the stored value within a variable

When transferring a variable (active) from my route to EJS, I initially found it easy to simply display its value: <!-- Active Text Input--> <div class="form-outline mb-4"> <label for="active" class="form-label">Active</label> ...

Even though there is an error in the line of code saying "Error in render: RangeError: Invalid array length", it still manages to perform its intended task

When trying to round a float number and display stars equal to that rating number, the code works as expected. Surprisingly, it also generates an error Error in render: "RangeError: Invalid array length" <p>Rating: <i v-for='n in Math.round( ...