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.
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.
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;
}
}
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).