How to add free shipping bar in top mini-cart

How to add free shipping bar in top mini-cart

How to add free shipping bar In top mini-cart

Steps to create free shipping bar

  • Create & register the module
  • Extend default.xml layout and define a block
  • Create block class & related template file (.phtml file)
  • Define jsLayout component in <block> element in default.xml layout
  • Create jsLayout component(.js file) & template(.html file) file at a location which is defined in default.xml layout file
  • Calculate percentage and binding it with shipping progress bar using knockout js.
  • Create a configuration menu to set the maximum price for free shipping bar at admin panel
  • Get maximum price config value for shipping bar which is set from the admin panel, and bind it to the shipping progress bar.

 

  1. Create Module for Free Shipping Bar

Let’s create the separate module to add free shipping bar in top mini-cart.

You have to create vendor directory under app/code directory. Not only this, you will also have to create a module directory under newly created vendor directory.

Create Vendor & Module directory as follow :

app/code/Kiwicommerce/Shippingbar

  1. Create registration.php file

Create a registration.php file on the root folder of your module for module registration and add the following content:

\Magento\Framework\Component\ComponentRegistrar::register(
   \Magento\Framework\Component\ComponentRegistrar::MODULE,
   'Kiwicommerce_Shippingbar',
   __DIR__
);
  1. Create module.xml file

For our module instruction, create a new directory “etc” on root directory. Also, create a module.xml file under “etc” directory and add the following content.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
   <module name="Kiwicommerce_Shippingbar" setup_version="1.0.0">
       <sequence>
           <module name="Magento_Checkout"/>
           <module name="Magento_Tax"/>
       </sequence>
   </module>
</config>

In <sequence> element add those Magento core modules that you want to load before the current module.

Run the following command using the command line interface from Magento root directory to enable the module.

$ php ./bin/magento setup:upgrade

  1. Extend default.xml layout to add shipping bar block

To add a new block for shipping bar in the minicart section, we need to extend layout from Magento checkout core module.

For extending layout, we need to create a default.xml layout at the following location :

app/code/Kiwicommerce/Shippingbar/view/frontend/layout/default.xml

Add following content in the default.xml file to create the new block for shipping bar.

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
   <body>
       <referenceContainer name="minicart.addons">
           <block class="Kiwicommerce\Shippingbar\Block\Cart\Sidebar" name="shipping_bar" template="Kiwicommerce_Shippingbar::cart/minicart.phtml">
               <arguments>
                   <argument name="jsLayout" xsi:type="array">
                       <item name="components" xsi:type="array">
                           <item name="minicart-addons" xsi:type="array">
                               <item name="component" xsi:type="string">Kiwicommerce_Shippingbar/js/view/minicartaddons</item>
                               <item name="config" xsi:type="array">
                                   <item name="template" xsi:type="string">Kiwicommerce_Shippingbar/minicartaddons/content</item>
                               </item>
                           </item>
                       </item>
                   </argument>
               </arguments>
           </block>
       </referenceContainer>
   </body>
</page>
  1. Create block class and template file for block

Create block class for newly added block at the location below :

We will use this class to set dynamic configuration for maximum price of free shipping bar in future.

app/code/Kiwicommerce/Shippingbar/Block/Cart/Sidebar.php

Add following content in Sidebar.php file,

<?php
namespace Kiwicommerce\Shippingbar\Block\Cart;

use Magento\Framework\View\Element\Template;

class Sidebar extends Template
{
   /**
    * Sidebar constructor.
    * @param Template\Context $context
    * @param array $data
    */
   public function __construct(
       Template\Context $context,
       array $data = []
   ) {
       parent::__construct($context, $data);
   }
}

Create template to render the content of knockout js template file at the following location with given content:

app/code/Kiwicommerce/Shippingbar/view/frontend/template/cart/minicart.phtml

<div id="cart-page">
   <div id="block-cart-list" data-bind="scope:'minicart-addons'" class="block">
       <!-- ko template: getTemplate() --><!-- /ko -->
       <script type="text/x-magento-init">
         {
             "#block-cart-list": {
                 "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?>
             },
             "*": {
                 "Magento_Ui/js/block-loader": "<?= /* @escapeNotVerified */ $block->getViewFileUrl('images/loader-1.gif') ?>"
             }
         }
     </script>
   </div>
</div>

Make sure that in the data-bind attribute, the scope name should be the name of our jsLayout component that we had defined in the default.xml file.

  1. Create jsLayout component & template file

Now, we have to create jsLayout component file as well as related template file as per defined in the default.xml file.

  • Create a component file at the following location :

app/code/Kiwicommerce/Shippingbar/view/frontend/web/js/view/minicartaddons.js

  • Create a component template file at the following location :

app/code/Kiwicommerce/Shippingbar/view/frontend/web/template/minicartaddons/content.html

Add following content in template file content.html

<div class="component-wrapper" data-bind="if: getTotalCartItems() > 0">
   <h4 data-bind="text : getpercentage() < 100 ?'Free shipping' : 'Eligible for free shipping!'"></h4>
   <span data-bind="html: cart().subtotal"></span><span> / </span><span data-bind="text: maxprice"></span>
   <div class="minprogress" id="progress">
       <div class="minprogress-active" id="child-progress" data-bind="style: { width: getpercentage() + '%' } "></div>
   </div>
</div>

Add following content in component file minicartaddons.js

define([
       'ko',
       'uiComponent',
       'Magento_Customer/js/customer-data',
   ], function (ko, Component, customerData) {
       'use strict';
       var subtotalAmount;
       var maxPrice = 100;
       var percentage;
       return Component.extend({
           displaySubtotal: ko.observable(true),
           maxprice: '$' + maxPrice.toFixed(2),
           /**
            * @override
            */
           initialize: function () {
               this._super();
               this.cart = customerData.get('cart');
           },
           getTotalCartItems: function () {
               return customerData.get('cart')().summary_count;
           },
           getpercentage: function () {
               subtotalAmount = customerData.get('cart')().subtotalAmount;
               if (subtotalAmount > maxPrice) {
                   subtotalAmount = maxPrice;
               }
               percentage = ((subtotalAmount * 100) / maxPrice);
               return percentage;
           }
       });
   });
  1. Create less file for the progress bar

Create miniprogress.less file for applying css of progress bar at the following location  with the code given below:

app/code/Kiwicommerce/Shippingbar/view/frontend/web/css/miniprogress.less

div.minprogress {
    border: 1px solid #a5a5a5;
    height: 10px;
    border-radius: 5px;
    position: relative;
.minprogress-active {
   position: absolute;
   background-color: #000000;
   height: 10px;
   border-radius: 5px;
}
}

Include miniprogress.less file in <head> element before the <body> element at default.xml layout file by adding the following content.

<head>
   <css src="Kiwicommerce_Shippingbar::css/miniprogress.css"/>
</head>

Free Shipping Bar has been added in mini-cart and you can see that in the screenshot below:

Shipping Bar

  1. Create system.xml file to add configuration menu at admin panel

Now, we are going to add configuration menu for free shipping bar in the store config menu at admin side.

Create system.xml to add a new tab and section for the configuration of shipping bar under store > configuration menu at the following location by adding the code snippet given below:

app/code/Kiwicommerce/Shippingbar/etc/adminhtml/system.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
   <system>
       <tab id="shippingbar" translate="label" sortOrder="1000">
           <label>Shipping Bar</label>
       </tab>
       <section id="shippingbar" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
           <label>Shipping Bar</label>
           <tab>shippingbar</tab>
           <resource>Kiwicommerce_Shippingbar::shippingbar</resource>
           <group id="shippingsection" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
               <label>Shipping Bar</label>
               <field id="shipping_bar" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
                   <label>Max Price</label>
                   <comment>Set Maximum price for free shipping.</comment>
               </field>
           </group>
       </section>
   </system>
</config>
  1. Create config.xml file to define a default value

Create config.xml file to set a default value of shipping bar maximum price at the following location by adding the code given below:

app/code/Kiwicommerce/Shippingbar/etc/config.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
   <default>
       <shippingbar>
           <shippingsection>
               <shipping_bar>100</shipping_bar>
           </shippingsection>
       </shippingbar>
   </default>
</config>

By making the above changes in the file, you will see that the configuration menu will appear at the store > configuration menu.
Shipping Bar Configuration

Now, we are going to fetch default value of max price which is set at admin panel and will reflect it in the shipping bar.

  1. Create helper to get config value of shipping bar

To get the configuration value of max price for shipping bar we need to create helper at the following location with below content.

app/code/Kiwicommerce/Shippingbar/Helper/Data.php

<?php
namespace Kiwicommerce\Shippingbar\Helper;

use Magento\Framework\App\Helper\AbstractHelper;

class Data extends AbstractHelper
{
   const PRICE_SHIPPING_BAR = 'shippingbar/shippingsection/shipping_bar';
   /**
    * Return if maximum price for shipping bar
    * @return int
    */
   public function getPriceForShippingBar()
   {
       return $this->scopeConfig->getValue(
           self::PRICE_SHIPPING_BAR,
           \Magento\Store\Model\ScopeInterface::SCOPE_STORE
       );
   }
}
  1. Use helper to assign config value of shipping bar to the block

Now, we can use the above helper’s function using dependency injection concepts.

Replace the content of app/code/Kiwicommerce/Shippingbar/Block/Cart/Sidebar.php file with the code snippet given below:

<?php
namespace Kiwicommerce\Shippingbar\Block\Cart;

use Magento\Framework\View\Element\Template;

class Sidebar extends Template
{
   /**
    * @var \Kiwicommerce\Jobs\Helper\Data
    */
   private $helper;

   /**
    * Sidebar constructor.
    * @param Template\Context $context
    * @param \Kiwicommerce\Jobs\Helper\Data $helper
    * @param array $data
    */
   public function __construct(
       Template\Context $context,
       \Kiwicommerce\Shippingbar\Helper\Data $helper,
       array $data = []
   ) {
       parent::__construct($context, $data);
       $this->helper = $helper;
   }

   public function getConfigForShippingBar()
   {
       return $this->helper->getPriceForShippingBar();
   }
}
  1. Assign shipping bar config value to the jsLayout component

Add the following code in app/code/Kiwicommerce/Shippingbar/view/frontend/template/cart/minicart.phtml file to assign the config value to the javascript variable.

<script>
   maxpriceShipping = <?= /* @escapeNotVerified */ $this->getConfigForShippingBar() ?>;
</script>

Now, your current file will look like this,

<div id="cart-page">
   <div id="block-cart-list" data-bind="scope:'minicart-addons'" class="block">
       <!-- ko template: getTemplate() --><!-- /ko -->
       <script>
           maxpriceShipping = <?= /* @escapeNotVerified */ $this->getConfigForShippingBar() ?>;
       </script>
       <script type="text/x-magento-init">
         {
             "#block-cart-list": {
                 "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?>
             },
             "*": {
                 "Magento_Ui/js/block-loader": "<?= /* @escapeNotVerified */ $block->getViewFileUrl('images/loader-1.gif') ?>"
             }
         }
     </script>
   </div>
</div>

Modify your js component file with the following content,

app/code/Kiwicommerce/Shippingbar/view/frontend/web/js/view/minicartaddons.js

Replace the following line of code,
var maxPrice = 100;

With the code given below:
var maxPrice = maxpriceShipping;

Happy coding! 🙂

2 Comments
  • Avatar for Sanne
    Sanne
    Posted at 08:06h, 23 October Reply

    Do you maybe have a git with the code? I’m stuck at step 7, the shippingbar won’t appair 🙁
    Thank you.

    • Avatar for KiwiCommerce
      KiwiCommerce
      Posted at 04:39h, 02 November Reply

      Hello, I request you to go through all the steps then check. Make sure about a module should be enabled, clear cache and deploy static content after that.

Leave a Reply

Your email address will not be published. Required fields are marked *