:::: MENU ::::
Browsing posts in: Magento 2

Magento 2 add custom block below shipping method

Hello, this tutorial is about Magento 2 add custom block below shipping method.First of all i assume that you are an advance learner of magento 2.Hence you are here to learn how to add custom block below shipping method in one page check out in magento 2.Above all if you are not familiar with magento 2 please start from basics.

lets start our tutorial and focus on our topic. For example if you want to add custom block below shipping methods. And aslo this custom block should be inside of shipping method form. In this tutorial i will discuss in detail how we can do it. It is a four to five step method.And i would try to explain it in a simple way. So that you can do it efficiently.

The first step is to Declare module’s checkout dependency.

Declare module’s checkout dependency

First of all find the directory to your module file

app/code/QaisarSatti/HelloWorld/etc/module.xml

and paste the below code

<?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="QaisarSatti_HelloWorld" setup_version="0.0.1" active="true">
        <sequence>
            <module name="Magento_Checkout"/>
        </sequence>
    </module>
</config>

Now we will move to the second step which is to Overwrite checkout layout.

Overwrite checkout layout

In the

app/code/QaisarSatti/HelloWorld/view/frontend/layout/checkout_index_index.xml

directory, paste the below code:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="shipping-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="shippingAddress" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="shippingAdditional" xsi:type="array">
                                                            <item name="component" xsi:type="string">uiComponent</item>
                                                            <item name="displayArea" xsi:type="string">shippingAdditional</item>
                                                            <item name="children" xsi:type="array">
                                                                <item name="additional_block" xsi:type="array">
                                                                    <item name="component" xsi:type="string">QaisarSatti_HelloWorld/js/view/checkout/shipping/additional-block</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

similarly the the third step is to Create JavaScript UI Component.

Create JavaScript UI Component

For your information JavaScript (with Knockout)manages checkout in Magento 2 .So for that you need to create a custom JS compnent. It will create the link between checkout UI component and your custom HTML template.

in the

app/code/QaisarSatti/HelloWorld/view/frontend/web/js/view/checkout/shipping/additional-block.js

directory, paste the below code

define([
    'uiComponent'

], function (Component) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'QaisarSatti_HelloWorld/checkout/shipping/additional-block'
        }
    });
});

Similarly we will move to the fourth step which is to Create HTML template.

Create HTML template

Now create the HTML template wich going to be displayed in checkout.
In the

app/code/QaisarSatti/HelloWorld/view/frontend/web/template/checkout/shipping/additional-block.html

directory,use below code

<div class="checkout-block" id="block-custom">
    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
    <p>Cum sociis natoque penatibus et magnis dis parturient montes.</p>
</div>

Now the fifth and final step is to clear cache.

clear cache

Finally run following commands to clear cache:

php bin/magento cache:clean
php bin/magento setup:upgrade
chmod -R 777 var/*

That’s it in this tutorial. Certainly, i have tried to explain these codes and their logic in a simple way, i hope they help you learn in an easy and better way.

Since these tutorials are for learning purpose please feel free to drop any suggestions or queries in comments section. That will definitely be highly appreciated.

Author: Qaisar Satti
Category: Magento 2
Last Modified: October 12, 2018


Magento 2 Get base url in js

This tutorial is about magento 2 Get base url in js file. First of all i assume that you are familiar with magento 2 and hence you are at this level where you want to know how to get base url from js file in magento 2. Above all if you are not familiar with advance magento concepts and are looking for basics,please look for magento 2 basic tutorials.

So lets start our tutorial and focus on our topic. For example if you want to get base url from .js file and append it with your module controller link from. How can we do it? It is almost impossible to use block to get the base url.

Get base url

So we will look at the way how we can get base url. to do that,paste the following code in your routes.xml file

define([

   'mage/url'
], function (url) {

  var linkUrl = url.build('test/test/test');
  console.log(linkUrl);
});

Where frontname is your routes.xml file frontname.

Since it is necessary,you have to pass your frontname from routes.xml file instead of module name(namespace_module).

Furthermore you can lookup your routes.xml file from

app/code/QaisarSatti/HelloWorld/etc/frontend/routes.xml

It might work for some and might not for others.

Further more Add this code in phtml file:

<input type="hidden" value="<?php echo $this->getUrl(); ?>" id="baseUrl"/>

having done that you can use this base url in js file by id :

$("#baseUrl").val();

It is a quite useful and tested trick. So i thought to share it.

There is another approach for this task.Having said that it may too be useful.

You should pass url to js(widget).Url is a parameter of js widget.And put script below to your template where you want to.

<script type="text/x-magento-init">
{
    "*": {
        "Magento_Ui/js/core/app": {
            "components": {
                "yourWidget": {
                    "dataUrl": "<?php echo $block->getBaseUrl(); ?>"
                }
            }
        }
    }
}
</script>

Similarly in javascript widget, you can access to dataUrl by below code.

define(['uiComponent'], function(Component) {
    'use strict';

    return Component.extend({
        initialize: function() {
            console.log(this.dataUrl);
        }
    });
});

Another simple approach is

<script>
window.testUrl = <?php echo json_encode($block->getBaseUrl()); ?>
</script>

Using your custom js you can have easy access to window.testUrl global variable.

That’s it from this tutorial. I hope it serves the purpose.

Since these tutorials are for learning purpose please feel free to drop any suggestions or queries in comments section. That will definitely be highly appreciated.

Author: Qaisar Satti
Category: Magento 2
Last Modified: October 12, 2018


Use Country based region selection in admin form Magento 2

In this tutorial we will learn about a default functionality of magento,Use Country based region selection in admin form Magento 2 . This is a built in function of magento. Magento provides this default functionality in the admin panel ui-component.Suppose you want to add country and region fields in your custom module in admin section.Now we know what you want to do, so lets shift our focus to the method and code which will help us to accomplish our task.

Lets have a look at the code part.

Country based region selection magento

Below code will use this default magneto functionality in your admin panel ui component form.

<field name="country_id">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">Magento\Directory\Model\Config\Source\Country</item>
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">text</item>
            <item name="label" xsi:type="string" translate="true">Country</item>
            <item name="formElement" xsi:type="string">select</item>
            <item name="source" xsi:type="string">store</item>
            <item name="component" xsi:type="string">Magento_Ui/js/form/element/country</item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="boolean">true</item>
            </item>
        </item>
    </argument>
</field>
<field name="region">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">text</item>
            <item name="label" xsi:type="string" translate="true">State/Region</item>
            <item name="formElement" xsi:type="string">input</item>
            <item name="source" xsi:type="string">store</item>
            <item name="sortOrder" xsi:type="number">15</item>
            <item name="visible" xsi:type="boolean">false</item>
        </item>
    </argument>
</field>
<field name="region_id">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">Magento\Directory\Model\ResourceModel\Region\Collection</item>
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">text</item>
            <item name="label" xsi:type="string" translate="true">State/Region</item>
            <item name="formElement" xsi:type="string">select</item>
            <item name="source" xsi:type="string">store</item>
            <item name="sortOrder" xsi:type="number">20</item>
            <item name="customEntry" xsi:type="string">region</item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="boolean">true</item>
            </item>
            <item name="filterBy" xsi:type="array">
                <item name="target" xsi:type="string">${ $.provider }:${ $.parentScope }.country_id</item>
                <item name="field" xsi:type="string">country_id</item>
            </item>
        </item>
    </argument>
</field>

So you can populate the country field values, and by selecting country you can also get the regions by using above code.

That’s it from this tutorial,i have tried to explain this magento functionality in a simplest and easiest way.Therefore i hope this will help you in a better way.

Since these tutorials are for learning purpose please feel free to drop any suggestions or queries in comments section. That will definitely be highly appreciated.

Author: Qaisar Satti
Category: Magento 2
Last Modified: October 12, 2018


Indexer in Magento 2

This tutorial is about Indexer in Magento 2. First of all lets discuss what is indexing in magento 2? The answer is how Magento 2 transforms data ( products, categories) to improve the performance of your storefront is called indexing.To optimize storefront performance, Magento accumulates data into special tables using indexers. As magento stores lots of data (including catalog data, prices, users, stores) in many database tables.

Lets have an example to clarify the concept. Suppose you changed the price of an item from $4.99 to $3.99. Magento must reindex the changed price to display it on your storefront. Otherwise loading the product information would take a long time, which may result in cart abandonment.

So this was a brief introduction of indexing.Now, lets come to our topic. In this tutorial we will look at different aspects and functionalities of indexing.

Above all lets start learning

indexing in magento 2

We will start with Magento 2 indexers.

Magento 2 indexers

There are basically 10 indexers. we can say that there are 10 default indexers. Which are as follows:

– Design Config Grid ( name: design_config_grid )
– Customer Grid ( name : customer_grid )
– Category products ( name: catalog_category_product )
– Product categories ( name: catalog_product_category)
– Product price ( name: catalog_product_price)
– Product entity attribute value ( name: catalog_product_attribute)
– Catalog search ( name: catalogsearch_fulltext)
– Stock ( name: cataloginventory_stock)
– Catalog rule product ( name: catalogrule_rule)
– Catalog product rule ( name: catalogrule_product)

Furthermore you can look indexer info using following command:

php bin/magento indexer:info

Now we will discuss Indexer status.

Indexer status

An indexer status can be one of following:

– valid: data is synchronized, no reindex required
– invalid: the original data was changed, the index should be updated
– working: indexing is in progress

Similarly you can get indexer status using the following command:

php bin/magento indexer:status

Furthermore lets have a look at Indexing modes.

Indexing modes

Re-indexing can be performed in two modes:

Update on Save: index tables are updated immediately after the dictionary data ( product, category, store…) is changed.
Update by Schedule: index tables are updated by cron job according to the configured schedule.

Similarly you can get indexer status using the following command:

php bin/magento indexer:show-mode

Following command can change indexer mode:

php bin/magento indexer:set-mode {realtime|schedule} [indexer-name]

For the reason that “realtime” is equal to “Update on Save” and “schedule” is equal to “Update by Schedule”.

Re-index

Rather using “System -> Index Management” in Magento backend, we can also re-index using the following command:

php bin/magento indexer:reindex [indexer-name]

You will get the result like:
1 Customer Grid index has been rebuilt successfully in

Futhermore reset indexer when it’s locked.h3>

Reset indexer

During re-index process, you may get the message like:

Stock index is locked by another reindex process. Skipping.

So we need to reset that indexer status to be able to re-index ( in this case, it’s “cataloginventory_stock” )

Similarly you can reset indexer using following command:

php bin/magento indexer:reset [indexer-name]

That’s it from this tutorial. I hope it serves the purpose.

Since these tutorials are for learning purpose please feel free to drop any suggestions or queries in comments section. That will definitely be highly appreciated.

Author: Qaisar Satti
Category: Magento 2
Last Modified: October 12, 2018


Magento 2 Call Helper method in phtml

This tutorial is about Magento 2 Helper method in phtml.i.e Helper method in magento 2. First of all i assume you are familiar with magento 2. And if you are not familiar with advance magento concepts and are looking for basics,please look for magento 2 basic tutorials.

lets start our tutorial.Suppose you want to call a Helper method in template(.phtml) file.How can you do it?. We will discuss it briefly in this tutorial.

It is not a good practice to use helper calls directly in the template.Because it introduces an undeclared dependency. If you want to do this properly you should only call in the template only methods from the block that renders it.Rather you can have your helper instance provided as a dependency to the block that renders the template and create a method in your block that calls the helper and call that method in the template.

You can defined your block like:

protected $helperData;
public function __construct(
     ....
    \QaisarSatti\HelloWorld\Helper\Data $helperData,
    ....
) {
    ....
    $this->helperData = $helperData;
    ....
}

public function doSomething()
{
    return $this->helperData->doSomething();
}

Finally you can call this block like:

$block->doSomething()

Where block something in my case is just for understanding.You will use your own function name.

Similarly there is another way of doing it.Lets have a look at the code:

$helper = $this->helper('QaisarSatti\HelloWorld\Helper\Data');
$values = $helper->YourHelperMethod();

Furthermore you have to write the whole class name in helper as below:

$this->helper('QaisarSatti\HelloWorld\Helper\Data')

You can use it in phtml file using above code.

Further more with some modifications, there is another approach of doing it.

Lets have a look at it.

Likewise you can look at the directory,in which this code is implemented:

/var/www/html/magento2/app/code/QaisarSatti/HelloWorld/Block/Test.php

  <?php
namespace QaisarSatti\HelloWorld\Block;

class Test extends \Magento\Framework\View\Element\Template
{

protected $_helper;

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    array $data = [],
    \QaisarSatti\HelloWorld\Helper\Data $helper
) {
    parent::__construct($context, $data);

    $this->_helper = $helper;
}

public function getEnable(){
        return $this->_helper->getEnable();
    }

}

Similarly in

/var/www/html/magento2/app/code/QaisarSatti/HelloWorld/view/frontend/templates/homehorizontalwidget.phtml

you can modify:

 <?php  echo $block->getEnable(); ?>

Furthermore in

/var/www/html/magento2/app/code/QaisarSatti/HelloWorld/Helper/Data.php

. we can use below code:

<?php
namespace QaisarSatti\HelloWorld\Helper;

class Data extends \Magento\Framework\App\Helper\AbstractHelper {

    /** * @var \Magento\Framework\App\Config\ScopeConfigInterfac
        */

    protected $_scopeConfig;
    CONST ENABLE = 'helloworld/general/enable_module';


    public function __construct( \Magento\Framework\App\Helper\Context $context,
            \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig ) {

             parent::__construct($context); $this->_scopeConfig = $scopeConfig;
    }

    public function getEnable(){
        return $this->_scopeConfig->getValue(self::ENABLE);
    }

}

Similarly in

/var/www/html/magento2/app/code/QaisarSatti/HelloWorld/etc/adminhtml/system.xml

System configurations are created.

Author: Qaisar Satti
Category: Magento 2
Last Modified: October 12, 2018


Magento 2 call any block function in phtml

This tutorial is about magento 2 call block function in phtml. First of all i assume that you are familiar with magento 2 and hence you are at this level where you want to know how in magento 2 call any block function in phtml. Above all if you are not familiar and are looking for basics please look for magento 2 basic tutorials.

Seems like i have conveyed my message so lets start our tutorial and focus on our topic. For example if you want to call your custom block function in product list.phtml?.How can we do it? I will try to explain it in a simple way.

Call custom block funtion

Lets have a look at the code.
For example your block class is as below

<?php
namespace QaisarSatti\HelloWorld\Block;
use Magento\Framework\View\Element\Template;

class Test extends Template
{
    public function getMyCustomMethod()
    {
        return 'Get Your custom method';
    }
}

Then in any phtml file,you can use the following code to get method of this block.

<?php
$blockObj= $block->getLayout()->createBlock('QaisarSatti\HelloWorld\Block\Test');
echo $blockObj->getMyCustomMethod();
?>

That is how it can be done.Certainly, i have tried to explain these codes and their logic in a simple way, i hope they help you learn in an easy and better way. That’s it from this tutorial.

Since these tutorials are for learning purpose please feel free to drop any suggestions or queries in comments section. That will definitely be highly appreciated.

Author: Qaisar Satti
Category: Magento 2
Last Modified: October 4, 2018


Add remove product from compare programmatically in Magento2

In this tutorial we will discuss another technique of magento 2, we will learn How to add and remove product from compare in Magento 2. Obviously there are many ways and techniques of doing a task but if you are looking for a better and dynamic way then this tutorial may satisfy your needs. If a product is already added to the compare collection then on next click on that icon should remove that product from compare collection.

Remove product from compare

To remove product from compare collection , following piece of code will get the desired results.

protected  $_productloader;
protected $_compareItemFactory;
protected $_catalogProductCompareList;

public function __construct(
    \Magento\Catalog\Model\Product\Compare\ItemFactory $compareItemFactory,
    \Magento\Catalog\Model\Product\Compare\ListCompare $catalogProductCompareList,
    \Magento\Catalog\Model\ProductFactory $productloader
) {
    $this->_productloader = $productloader;
    $this->_compareItemFactory = $compareItemFactory;
    $this->_catalogProductCompareList = $catalogProductCompareList;
}

public function execute()
{
    $productId = (int)$this->getRequest()->getParam('product');
    $product=$this->_productloader->create()->load($productId);
    $compareitem=$this->_compareItemFactory->create()->loadByProduct($product);
    if($compareitem):
      $this->_catalogProductCompareList->removeProduct($product);
    endif;
}

As you can see magento 2 is using following code for removing the product from compare you can use this code too.

<a href="#" class="action tocompare" title="<?php echo $block->escapeHtml(__('Remove Compare')); ?>"
           aria-label="<?php echo $block->escapeHtml(__('Remove Compare')); ?>"
         data-post='<?php /* @escapeNotVerified */ echo $compareHelper->getPostDataRemove($_product); ?>'
                role="button">
      <span><?php /* @escapeNotVerified */ echo __('Remove Compare') ?></span>
 </a>

Add product to compare

To perform the add product to compare collection task, following code should be able to get the desired result.

protected  $_productloader;

protected $_catalogProductCompareList;

public function __construct(

    \Magento\Catalog\Model\Product\Compare\ListCompare $catalogProductCompareList,
    \Magento\Catalog\Model\ProductFactory $productloader
) {
    $this->_productloader = $productloader;
    $this->_catalogProductCompareList = $catalogProductCompareList;
}

public function execute()
{
    $productId = (int)$this->getRequest()->getParam('product');
    $product=$this->_productloader->create()->load($productId);

   
    $this->_catalogProductCompareList->addProduct($product);
   
}

A new file can be created to implement the above mentioned code and can be considered as a good technique but you can modify the existing file as well as per your requirements.

It is also a good practice to add your module and redirect it on your controllers, don’t try to edit the core file as it may get complicated.

Author: Qaisar Satti
Category: Magento 2
Last Modified: September 26, 2018


Pages:1234567...16