/   /   /  Magento 2 Backend: create custom tab in customer view and load grid inside admin

Note:

For more extensions and themes visit our store

Magento 2 Backend: create custom tab in customer view and load grid inside admin



Wow this is our first tutorial about Magento 2, how create you custom nav tab in customer view (backend side)
Get the Extension in Github
Magento 2 offer structured technique :
 Steps :
    A –  declare your module inside app/code/Ibnab/ComparedProduct/etc/ create module.xml with code :
 

  1.   <?xml version="1.0"?>
  2.   <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
  3.     <module name="Ibnab_ComparedProduct" setup_version="1.0.0" schema_version="1.0.0">
  4.           <sequence>
  5.               <module name="Magento_Customer"/>
  6.           </sequence>
  7.     </module>
  8.   </config>
  9.  


   you can go to official doc for more infos : http://devdocs.magento.com/guides/v2.0/extension-dev-guide/bk-extension-dev-guide.html


  B – now we need add our tab link in the left side (backend customer view) and related to grid of all  
product in compare for specific customer :

Magento 2 use small layout snippets every path (handle) inside an xml file example :
customer_index_edit for adminhtml  (admin/customer/index/edit) is inside app/code/Ibnab/ComparedProduct/view/adminhtml/customer_index_edit.xml

yes two new technique small snippets and in the same folder of your extension

ok create app/code/Ibnab/ComparedProduct/view/adminhtml/customer_index_edit.xml and put this code for add the link tab and infos and override the default view  :
  1.  
  2. <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left"
  3.     xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
  4.     <body>
  5.            <referenceBlock name="customer_form">
  6.              <block class="Ibnab\ComparedProduct\Block\Adminhtml\Edit\Tab\Compared" name="customer_edit_tab_compared">
  7.               <action method="setTabLabel">
  8.                   <argument name="label" xsi:type="string">Product Compared</argument>
  9.               </action>
  10.             </block>
  11.           </referenceBlock>
  12.     </body>
  13. </page>
  14.  


See the label of the tab link is  Product Compared and the class of tab is  Ibnab\ComparedProduct\Block\Adminhtml\Edit\Tab\Compared create inside  app/Ibnab/ComparedProduct/Block/Adminhtml/Edit/Tab/Compared and put you code  :

  1.  
  2. <?php
  3. /**
  4.  * Copyright © 2015 Magento. All rights reserved.
  5.  * See COPYING.txt for license details.
  6.  */
  7. namespace Ibnab\ComparedProduct\Block\Adminhtml\Edit\Tab;
  8. use Magento\Customer\Controller\RegistryConstants;
  9. use Magento\Ui\Component\Layout\Tabs\TabInterface;
  10. /**
  11.  * Customer account form block
  12.  */
  13. class Compared extends \Magento\Backend\Block\Template implements TabInterface
  14. {
  15.     /**
  16.      * Core registry
  17.      *
  18.      * @var \Magento\Framework\Registry
  19.      */
  20.     protected $_coreRegistry;
  21.     /**
  22.      * @param \Magento\Backend\Block\Template\Context $context
  23.      * @param \Magento\Framework\Registry $registry
  24.      * @param array $data
  25.      */
  26.     public function __construct(
  27.         \Magento\Backend\Block\Template\Context $context,
  28.         \Magento\Framework\Registry $registry,
  29.         array $data = []
  30.     ) {
  31.         $this->_coreRegistry = $registry;
  32.         parent::__construct($context, $data);
  33.     }
  34.     /**
  35.      * @return string|null
  36.      */
  37.     public function getCustomerId()
  38.     {
  39.         return $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
  40.     }
  41.     /**
  42.      * @return \Magento\Framework\Phrase
  43.      */
  44.     public function getTabLabel()
  45.     {
  46.         return __('Product Compare');
  47.     }
  48.     /**
  49.      * @return \Magento\Framework\Phrase
  50.      */
  51.     public function getTabTitle()
  52.     {
  53.         return __('Product Compare');
  54.     }
  55.     /**
  56.      * @return bool
  57.      */
  58.     public function canShowTab()
  59.     {
  60.         if ($this->getCustomerId()) {
  61.             return true;
  62.         }
  63.         return false;
  64.     }
  65.  
  66.     /**
  67.      * @return bool
  68.      */
  69.     public function isHidden()
  70.     {
  71.         if ($this->getCustomerId()) {
  72.             return false;
  73.         }
  74.         return true;
  75.     }
  76.     /**
  77.      * Tab class getter
  78.      *
  79.      * @return string
  80.      */
  81.     public function getTabClass()
  82.     {
  83.         return '';
  84.     }
  85.     /**
  86.      * Return URL link to Tab content
  87.      *
  88.      * @return string
  89.      */
  90.     public function getTabUrl()
  91.     {
  92.         return $this->getUrl('compared/*/compare', ['_current' => true]);
  93.     }
  94.     /**
  95.      * Tab should be loaded trough Ajax call
  96.      *
  97.      * @return bool
  98.      */
  99.     public function isAjaxLoaded()
  100.     {
  101.         return true;
  102.     }
  103. }
  104.  


- You can see is implements from  TabInterface and the more important function in this class is : getTabUrl()  and isAjaxLoaded() :
getTabUrl()  contain the  code  return $this->getUrl('compared/*/compare', ['_current' => true]); equal go to action or file compare and execute the complete path of your controller in Magento 2  is
 app/code/Ibnab/ComparedProduct/Controller/Adminhtml/Index/Compare.php Magento 2 go to this file and finding the function execute() and execute the code , ok complete code of file is :
  1.  
  2. <?php
  3. /**
  4.  * Copyright © 2015 Magento. All rights reserved.
  5.  * See COPYING.txt for license details.
  6.  */
  7. namespace Ibnab\ComparedProduct\Controller\Adminhtml\Index;
  8.  
  9. class Compare extends \Magento\Customer\Controller\Adminhtml\Index
  10. {
  11.     /**
  12.      * Customer compare grid
  13.      *
  14.      * @return \Magento\Framework\View\Result\Layout
  15.      */
  16.     public function execute()
  17.     {
  18.         $this->initCurrentCustomer();
  19.         $resultLayout = $this->resultLayoutFactory->create();
  20.         return $resultLayout;
  21.     }
  22. }
  23.  


As you see is load the layout , the name of layout is compared_index_compare.xml Magento 2 take get from function   getTabUrl() :
  1.  
  2.     public function getTabUrl()
  3.     {
  4.         return $this->getUrl('compared/*/compare', ['_current' => true]);
  5.     }
  6.  


C : Ok create app/code/Ibnab/ComparedProduct/view/adminhtml/compared_index_compare.xml for loading the grid :
  1.  
  2. <?xml version="1.0"?>
  3.  
  4. <!--
  5.  
  6. /**
  7.  * Copyright © 2015 Magento. All rights reserved.
  8.  * See COPYING.txt for license details.
  9.  */
  10. -->
  11.  
  12. <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd">
  13.     <container name="root" label="Root">
  14.         <block class="Ibnab\ComparedProduct\Block\Adminhtml\Edit\Tab\View\Compared" name="comparedproduct.edit.tab.compared"/>
  15.     </container>
  16. </layout>
  17.  


D -  Now we need create our file  Compared.php of our grid :
  1.  
  2. <?php
  3. /**
  4.  * Copyright © 2015 Magento. All rights reserved.
  5.  * See COPYING.txt for license details.
  6.  */
  7. namespace Ibnab\ComparedProduct\Block\Adminhtml\Edit\Tab\View;
  8.  
  9. use Magento\Customer\Controller\RegistryConstants;
  10.  
  11. /**
  12.  * Adminhtml customer recent orders grid block
  13.  */
  14. class Compared extends \Magento\Backend\Block\Widget\Grid\Extended
  15. {
  16.     /**
  17.      * Core registry
  18.      *
  19.      * @var \Magento\Framework\Registry|null
  20.      */
  21.     protected $_coreRegistry = null;
  22.  
  23.     /**
  24.      * @var \Magento\Sales\Model\Resource\Order\Grid\CollectionFactory
  25.      */
  26.     protected $_collectionFactory;
  27.  
  28.     /**
  29.      * Constructor
  30.      *
  31.      * @param \Magento\Backend\Block\Template\Context $context
  32.      * @param \Magento\Backend\Helper\Data $backendHelper
  33.      * @param \Magento\Sales\Model\Resource\Order\Grid\CollectionFactory $collectionFactory
  34.      * @param \Magento\Framework\Registry $coreRegistry
  35.      * @param array $data
  36.      */
  37.     public function __construct(
  38.         \Magento\Backend\Block\Template\Context $context,
  39.         \Magento\Backend\Helper\Data $backendHelper,
  40.         \Magento\Catalog\Model\Resource\Product\Compare\Item\CollectionFactory $collectionFactory,
  41.         \Magento\Framework\Registry $coreRegistry,
  42.         \Psr\Log\LoggerInterface $logger,
  43.         array $data = []
  44.     ) {
  45.          $this->_logger = $logger;
  46.         $this->_coreRegistry = $coreRegistry;
  47.         $this->_collectionFactory = $collectionFactory;
  48.         parent::__construct($context, $backendHelper, $data);
  49.     }
  50.  
  51.     /**
  52.      * Initialize the orders grid.
  53.      *
  54.      * @return void
  55.      */
  56.     protected function _construct()
  57.     {
  58.         parent::_construct();
  59.         $this->setId('comparedproduct_view_compared_grid');
  60.         $this->setDefaultSort('created_at', 'desc');
  61.         $this->setSortable(false);
  62.         $this->setPagerVisibility(false);
  63.         $this->setFilterVisibility(false);
  64.     }
  65.     /**
  66.      * {@inheritdoc}
  67.      */
  68.     protected function _preparePage()
  69.     {
  70.         $this->getCollection()->setPageSize(5)->setCurPage(1);
  71.     }
  72.  
  73.     /**
  74.      * {@inheritdoc}
  75.      */
  76.     protected function _prepareCollection()
  77.     {
  78.         $collection = $this->_collectionFactory->create()->setCustomerId(
  79.             $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID)
  80.         )->useProductItem()->addAttributeToSelect(array("name","price"));
  81.         $this->setCollection($collection);
  82.         return parent::_prepareCollection();
  83.     }
  84.  
  85.     /**
  86.      * {@inheritdoc}
  87.      */
  88.      protected function _prepareColumns()
  89.     {
  90.         $this->addColumn(
  91.             'product_id',
  92.             ['header' => __('ID'), 'index' => 'product_id', 'type' => 'number', 'width' => '100px']
  93.         );
  94.         $this->addColumn(
  95.             'product_name',
  96.             [
  97.                 'header' => __('Product Name'),
  98.                 'index' => 'name',
  99.             ]
  100.         );
  101.         $this->addColumn(
  102.             'product_price',
  103.             [
  104.                 'header' => __('Product Price'),
  105.                 'index' => 'price',
  106.             ]
  107.         );
  108.         return parent::_prepareColumns();
  109.     }
  110.  
  111.     /**
  112.      * Get headers visibility
  113.      *
  114.      * @return bool
  115.      *
  116.      * @SuppressWarnings(PHPMD.BooleanGetMethodName)
  117.      */
  118.     public function getHeadersVisibility()
  119.     {
  120.         return $this->getCollection()->getSize() >= 0;
  121.     }
  122.     /**
  123.      * {@inheritdoc}
  124.      */
  125.     public function getRowUrl($row)
  126.     {
  127.         return $this->getUrl('catalog/product/edit', ['id' => $row->getProductId()]);
  128.     }
  129. }
  130.  


in function :
  1.  
  2. public function __construct(
  3.         \Magento\Backend\Block\Template\Context $context,
  4.         \Magento\Backend\Helper\Data $backendHelper,
  5.         \Magento\Catalog\Model\Resource\Product\Compare\Item\CollectionFactory $collectionFactory,
  6.         \Magento\Framework\Registry $coreRegistry,
  7.         \Psr\Log\LoggerInterface $logger,
  8.         array $data = []
  9.     ) {
  10.          $this->_logger = $logger;
  11.         $this->_coreRegistry = $coreRegistry;
  12.         $this->_collectionFactory = $collectionFactory;
  13.         parent::__construct($context, $backendHelper, $data);
  14.     }
  15.  


I add my custom factory \Magento\Catalog\Model\Resource\Product\Compare\Item\CollectionFactory the new technique of Magento 2 based on DI and Factory Pattern ,  for getting instance of model class or collection class you need pass by injected the factory object to construct function ,and this factory object give you the ability of create object and create your query or any operation in my example I want a collection    of items in compare from the class Magento\Catalog\Model\Resource\Product\Compare\Item\Collection in path folder :
app/code/ Magento/Catalog/Model/Resource/Product/Compare/Item/Collection.php I can't instanced directly but I need get the factory  \Magento\Catalog\Model\Resource\Product\Compare\Item\CollectionFactory and use the method create for getting the object but in new logic of Magento 2 you can put by injecion and use without search how get the factory form doc go to :
http://devdocs.magento.com/guides/v2.0/extension-dev-guide/depend-inj.html  


- The _prepareCollection() get my custom selected collection of items in compare , I use the current user from registry and useProductItem() from my object item collection

- The _prepareColumns()  the columns and index from collection you can use custom renderer

 

Comments

make your store more efficient

Solving problems. With open source technology. Professional results. That’s what makes Ibnab your best choice

IBNAB is a company made of a group of professionals whose work is providing secure open source solutions. Our company strives for reaching magnificent results with each experience and provides professional open source solutions that cover every part of the business process.