1

I want to add a product grid in my module's tab.

How can I achieve this?

Please help me.

I tried this. But I am getting a blank page.

5
  • Take a look at this sample module: github.com/tzyganu/Magento2SampleModule. it may not be up to date with the latest magento version, but it will give you a place to start
    – Marius
    Mar 7, 2016 at 12:41
  • Is there any other extension in latest magento ?
    – Krupali
    Mar 7, 2016 at 13:24
  • I don't have one. I didn't get around to make it compatible.
    – Marius
    Mar 7, 2016 at 13:42
  • @Marius I have update my ans.Please check.This may help me
    – Krupali
    Mar 8, 2016 at 5:13
  • Please follow my answer and save selected products into database.magento.stackexchange.com/questions/236854/… Jun 26, 2020 at 17:19

2 Answers 2

4

Namespace: Vendor

ModuleName: Productattach

Example: https://github.com/mageprince/magento2-productAttachment

1) Create controller

app/code/Vendor/Productattach/Controller/Adminhtml/Index/ProductsGrid.php

<?php

namespace Vendor\Productattach\Controller\Adminhtml\Index;

use Magento\Backend\App\Action;
use Magento\TestFramework\ErrorLog\Logger;

class ProductsGrid extends \Magento\Backend\App\Action
{

    /**
     * @var \Magento\Framework\View\Result\LayoutFactory
     */
    protected $_resultLayoutFactory;

    /**
     * @param \Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory
     * @param Action\Context $context
     */
    public function __construct(
        Action\Context $context,
        \Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory
    ) {
        parent::__construct($context);
        $this->_resultLayoutFactory = $resultLayoutFactory;
    }

    /**
     * {@inheritdoc}
     */
    protected function _isAllowed()
    {
        return true;
    }

    /**
     * Save action
     *
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        $resultLayout = $this->_resultLayoutFactory->create();
        $resultLayout->getLayout()->getBlock('productattach.edit.tab.products')
                     ->setInBanner($this->getRequest()->getPost('index_products', null));

        return $resultLayout;
    }

}

2) Create layout

app/code/Vendor/Productattach/view/adminhtml/layout

/productattach_index_productsgrid.xml

<?xml version="1.0" encoding="UTF-8"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <container name="root" label="Root">
        <block class="Vendor\Productattach\Block\Adminhtml\Productattach\Edit\Tab\Products" name="productattach.edit.tab.products"/>
    </container>
</layout>

3) Create block which we defined in layout file

app/code/Vendor/Productattach/Block/Adminhtml/Productattach/Edit/Tab/Products.php

<?php

namespace Vendor\Productattach\Block\Adminhtml\Productattach\Edit\Tab;

use Vendor\Productattach\Model\ProductattachFactory;

class Products extends \Magento\Backend\Block\Widget\Grid\Extended
{
    /**
     * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
     */
    protected $productCollectionFactory;

    /**
     * Contact factory
     *
     * @var ContactFactory
     */
    protected $contactFactory;

    /**
     * @var  \Magento\Framework\Registry
     */
    protected $registry;

    protected $_objectManager = null;

    /**
     *
     * @param \Magento\Backend\Block\Template\Context $context
     * @param \Magento\Backend\Helper\Data $backendHelper
     * @param \Magento\Framework\Registry $registry
     * @param ContactFactory $attachmentFactory
     * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
     * @param array $data
     */
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\Backend\Helper\Data $backendHelper,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\ObjectManagerInterface $objectManager,
        ProductattachFactory $contactFactory,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
        array $data = []
    ) {
        $this->contactFactory = $contactFactory;
        $this->productCollectionFactory = $productCollectionFactory;
        $this->_objectManager = $objectManager;
        $this->registry = $registry;
        parent::__construct($context, $backendHelper, $data);
    }

    /**
     * _construct
     * @return void
     */
    protected function _construct()
    {
        parent::_construct();
        $this->setId('productsGrid');
        $this->setDefaultSort('entity_id');
        $this->setDefaultDir('DESC');
        $this->setSaveParametersInSession(true);
        $this->setUseAjax(true);
        if ($this->getRequest()->getParam('productattach_id')) {
            $this->setDefaultFilter(array('in_product' => 1));
        }
    }

    /**
     * add Column Filter To Collection
     */
    protected function _addColumnFilterToCollection($column)
    {
        if ($column->getId() == 'in_product') {
            $productIds = $this->_getSelectedProducts();

            if (empty($productIds)) {
                $productIds = 0;
            }
            if ($column->getFilter()->getValue()) {
                $this->getCollection()->addFieldToFilter('entity_id', array('in' => $productIds));
            } else {
                if ($productIds) {
                    $this->getCollection()->addFieldToFilter('entity_id', array('nin' => $productIds));
                }
            }
        } else {
            parent::_addColumnFilterToCollection($column);
        }

        return $this;
    }

    /**
     * prepare collection
     */
    protected function _prepareCollection()
    {
        $collection = $this->productCollectionFactory->create();
        $collection->addAttributeToSelect('name');
        $collection->addAttributeToSelect('sku');
        $collection->addAttributeToSelect('price');
        $this->setCollection($collection);
        return parent::_prepareCollection();
    }

    /**
     * @return $this
     */
    protected function _prepareColumns()
    {
        /* @var $model \Webspeaks\ProductsGrid\Model\Slide */
        $model = $this->_objectManager->get('\Vendor\Productattach\Model\Productattach');

        $this->addColumn(
            'in_product',
            [
                'header_css_class' => 'a-center',
                'type' => 'checkbox',
                'name' => 'in_product',
                'align' => 'center',
                'index' => 'entity_id',
                'values' => $this->_getSelectedProducts(),
            ]
        );

        $this->addColumn(
            'entity_id',
            [
                'header' => __('Product ID'),
                'type' => 'number',
                'index' => 'entity_id',
                'header_css_class' => 'col-id',
                'column_css_class' => 'col-id',
            ]
        );
        $this->addColumn(
            'names',
            [
                'header' => __('Name'),
                'index' => 'name',
                'class' => 'xxx',
                'width' => '50px',
            ]
        );
        $this->addColumn(
            'sku',
            [
                'header' => __('Sku'),
                'index' => 'sku',
                'class' => 'xxx',
                'width' => '50px',
            ]
        );
        $this->addColumn(
            'price',
            [
                'header' => __('Price'),
                'type' => 'currency',
                'index' => 'price',
                'width' => '50px',
            ]
        );

        return parent::_prepareColumns();
    }

    /**
     * @return string
     */
    public function getGridUrl()
    {
        return $this->getUrl('*/*/productsgrid', ['_current' => true]);
    }

    /**
     * @param  object $row
     * @return string
     */
    public function getRowUrl($row)
    {
        return '';
    }

    protected function _getSelectedProducts()
    {
        $contact = $this->getContact();
        return $contact->getProducts($contact);
    }

    /**
     * Retrieve selected products
     *
     * @return array
     */
    public function getSelectedProducts()
    {
        $contact = $this->getContact();
        $selected = $contact->getProducts($contact);

        if (!is_array($selected)) {
            $selected = [];
        }
        return $selected;
    }

    protected function getContact()
    {
        $contactId = $this->getRequest()->getParam('productattach_id');
        $contact   = $this->contactFactory->create();
        if ($contactId) {
            $contact->load($contactId);
        }
        return $contact;
    }

    /**
     * {@inheritdoc}
     */
    public function canShowTab()
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function isHidden()
    {
        return true;
    }
}

enter image description here

6
  • How can I move above product grid from Select Products tab to Attachment Information tab ? Aug 1, 2017 at 5:33
  • @Prince, what is setInBanner in Controller?
    – Gagan
    Feb 26, 2018 at 5:47
  • @Prince how can i get selected product in post? Mar 6, 2018 at 14:09
  • Hi @prince how can I add new product tab above filter section in product grid??
    – Daniel_12
    Aug 29, 2018 at 7:15
  • Please follow this and save selected product in databse magento.stackexchange.com/questions/236854/… Jun 26, 2020 at 17:16
0

As an example you can take a look on Sales Order View layout. It includes invoice, shipment and creditmemo grids under separate tabs on order view page.

Basically it's adding a container tab:

    <block class="..." name="sales_order_tabs">
        ...
        <block class="Magento\Sales\Block\Adminhtml\Order\View\Tab\Invoices" name="sales_order_invoice.grid.container"/>
        <action method="addTab">
            <argument name="name" xsi:type="string">order_invoices</argument>
            <argument name="block" xsi:type="string">sales_order_invoice.grid.container</argument>
        </action>
        ...
    </block>

And including ui component:

<referenceBlock name="sales_order_invoice.grid.container">
    <uiComponent name="sales_order_view_invoice_grid"/>
</referenceBlock>

To include product grid you should do the same in your module using product_listing ui component (see catalog_product_index layout).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.