Magento2 How to Initialize JS Component Using Layout XML

 

In Magento2, mainly we have seen on checkout page all Js components loads using xml, these components are defined in checkout_index_index.xml file.

We can also define our custom Js Components using our xml Layout File.

Step 1: Create our module registration php file as registration.php.

Location: app/code/Magemeta/CreateCustomer/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Magemeta_CustomLayout',
    __DIR__
);

Location:
app/code/Magemeta/CreateCustomer/etc/module.xml
<?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="Magemeta_CustomLayout" setup_version="1.0.0"></module> </config>

Location:
app/code/Magemeta/CustomLayout/composer.json
{     "name": "magemeta/module-custom-layout",     "description": "This module is used to create customers",     "type": "magento2-module",     "license": "OSL-3.0",     "authors": [         {             "email": "info@magemeta.com",             "name": "magemeta"         }     ],     "minimum-stability": "dev",     "require": {},     "autoload": {         "files": [             "registration.php"         ],         "psr-4": {             "Magemeta\\CustomLayout\\": ""         }     } }

Step 2:
We need to call our custom js renderer block into xml layout. Here we have use customer_account_edit.xml.

Location:
app/code/Magemeta/CustomLayout/view/frontend/layout/customer_account_edit.xml
<?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">     <update handle="customer_account"/>     <body>         <referenceContainer name="content">             <block class="Magemeta\CustomLayout\Block\CustomLayout" name="magemeta_custom_layout" template="Magemeta_CustomLayout::custom_layout.phtml" cacheable="false">                 <arguments>                     <argument name="jsLayout" xsi:type="array">                         <item name="components" xsi:type="array">                             <item name="customcomponent" xsi:type="array">                                 <item name="component" xsi:type="string">Magemeta_CustomLayout/js/custom-component</item>                             </item>                         </item>                     </argument>                 </arguments>             </block>         </referenceContainer>     </body> </page>

Step 3:
We need to create our custom block to collect information to insert into js layout.

Location: app/code/Magemeta/CustomLayout/Block/CustomLayout.php
<?php /**  * Magemeta_CustomLayout  *  * @category  Magemeta  * @package   Magemeta_CustomLayout  * @author    Magemeta Team <info@magemeta.com>  * @copyright Copyright (c) 2019 Magemeta (http://www.magemeta.com)  */ namespace Magemeta\CustomLayout\Block; use Magemeta\CustomLayout\Model\CustomConfigProvider; use Magento\Framework\View\Element\Template\Context; class CustomLayout extends \Magento\Framework\View\Element\Template {     /**      * @var array      */     protected $jsLayout;     /**      * @var CustomConfigProvider      */     protected $configProvider;     /**      * @param Context $context      * @param array $data      */     public function __construct(         Context $context,         CustomConfigProvider $configProvider,         array $data = []     )     {         parent::__construct($context, $data);         $this->jsLayout = isset($data['jsLayout']) && is_array($data['jsLayout']) ? $data['jsLayout'] : [];         $this->configProvider = $configProvider;     }     /**      * @return string      */     public function getJsLayout()     {         return \Zend_Json::encode($this->jsLayout);     }     public function getCustomConfig()     {         return $this->configProvider->getConfig();     } }

Step 4:
We need to create model to collect and return configuration information to block.

Location: app/code/Magemeta/CustomLayout/Model/CustomConfigProvider.php
<?php /**  * Magemeta_CustomLayout  *  * @category  Magemeta  * @package   Magemeta_CustomLayout  * @author    Magemeta Team <info@magemeta.com>  * @copyright Copyright (c) 2019 Magemeta (http://www.magemeta.com)  */ namespace Magemeta\CustomLayout\Model; class CustomConfigProvider implements ConfigProviderInterface {     /**      * @var ConfigProviderInterface[]      */     private $configProviders;     /**      * @param ConfigProviderInterface[] $configProviders      * @codeCoverageIgnore      */     public function __construct(         array $configProviders     ) {         $this->configProviders = $configProviders;     }     /**      * {@inheritdoc}      */     public function getConfig()     {         $config = [];         foreach ($this->configProviders as $configProvider) {             $config = array_merge_recursive($config, $configProvider->getConfig());         }         return $config;     } }

We also need to create model interface as ConfigProviderInterface.

Location:
app/code/Magemeta/CustomLayout/Model/ConfigProviderInterface.php
<?php /**  * Magemeta_CustomLayout  *  * @category  Magemeta  * @package   Magemeta_CustomLayout  * @author    Magemeta Team <info@magemeta.com>  * @copyright Copyright (c) 2019 Magemeta (http://www.magemeta.com)  */ namespace Magemeta\CustomLayout\Model; interface ConfigProviderInterface {     /**      * Retrieve associative array of checkout configuration      *      * @return array      */     public function getConfig(); }
Step 5: Now we need to create our custom .phtml file as custom_layout.phtml. Here we initialized our custom component and load the custom js components by getJsLayout() method.

Location: app/code/Magemeta/CustomLayout/view/frontend/templates/custom_layout.phtml
<script>     window.customConfig = <?php echo \Zend_Json::encode($block->getCustomConfig()); ?>; </script> <div id="custom-component" data-bind="scope:'customcomponent'">     <!-- ko template: getTemplate() --><!-- /ko -->     <script type="text/x-magento-init">     {         "#custom-component": {             "Magento_Ui/js/core/app":  <?php /* @escapeNotVerified */ echo $block->getJsLayout();?>         }     }     </script> </div>

Step 6:
Now we need to create our custom js file.

Location: app/code/Magemeta/CustomLayout/view/frontend/web/js/custom-component.js
define([         'jquery',         'uiComponent',         'ko',     ], function ($, Component, ko) {         'use strict';         var customConfigData = window.customConfig;         return Component.extend({             defaults: {                 template: 'Magemeta_CustomLayout/custom_layout'             },             initialize: function () {                 this._super();             },         });     } );

Step 7:
Finally we need to create our custom custom_layout.html file if we set it component template part of custom-component.js. If you don't want to add template, just comment it out from js script.

Location:
app/code/Magemeta/CustomLayout/view/frontend/web/template/custom_layout.html
<div class="customLayout"> <p>This is custom layout html</p> </div>

We are done with initializing the custom js component in custom layout. Hope this helps you guys!

 

Leave a Reply