Inserted a product grid in my custom admin form using the below code: UPDATED view/adminhtml/layout/mymodule_form.xml
<fieldset name="assign_products">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Products</item>
<item name="collapsible" xsi:type="boolean">true</item>
<item name="sortOrder" xsi:type="number">40</item>
</item>
</argument>
<container name="assign_products_container" >
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="sortOrder" xsi:type="number">60</item>
</item>
</argument>
<htmlContent name="html_content">
<argument name="block" xsi:type="object">Company\Mymodule\Block\Adminhtml\Productgrid\AssignProducts</argument>
</htmlContent>
</container>
</fieldset>
Company/Mymodule/Block/Adminhtml/Productgrid/AssignProducts.php
namespace Company\Mymodule\Block\Adminhtml\Productgrid;
class AssignProducts extends \Magento\Backend\Block\Template
{
/**
* Block template
*
* @var string
*/
protected $_template = 'mymodule/category/edit/assign_products.phtml';
/**
* @var \Magento\Catalog\Block\Adminhtml\Category\Tab\Product
*/
protected $blockGrid;
/**
* @var \Magento\Framework\Registry
*/
protected $registry;
/**
* @var \Magento\Framework\Json\EncoderInterface
*/
protected $jsonEncoder;
/**
* AssignProducts constructor.
*
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\Json\EncoderInterface $jsonEncoder
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\Json\EncoderInterface $jsonEncoder,
array $data = []
) {
$this->registry = $registry;
$this->jsonEncoder = $jsonEncoder;
parent::__construct($context, $data);
}
/**
* Retrieve instance of grid block
*
* @return \Magento\Framework\View\Element\BlockInterface
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getBlockGrid()
{
if (null === $this->blockGrid) {
$this->blockGrid = $this->getLayout()->createBlock(
'Company\Mymodule\Block\Adminhtml\Mymodule\Tab\Product',
'category.product.grid'
);
}
return $this->blockGrid;
}
/**
* Return HTML of grid block
*
* @return string
*/
public function getGridHtml()
{
return $this->getBlockGrid()->toHtml();
}
/**
* @return string
*/
public function getProductsJson()
{
$products = $this->getCategory()->getProductsPosition();
if (!empty($products)) {
return $this->jsonEncoder->encode($products);
}
return '{}';
}
/**
* Retrieve current category instance
*
* @return array|null
*/
public function getCategory()
{
return $this->registry->registry('mymodule_item');
}
}
Company/Mymodule/Block/Adminhtml/Mymodule/Tab/Product.php
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
/**
* Product in category grid
*
* @author Magento Core Team <[email protected]>
*/
namespace Company\Mymodule\Block\Adminhtml\Mymodule\Tab;
use Magento\Backend\Block\Widget\Grid;
use Magento\Backend\Block\Widget\Grid\Column;
use Magento\Backend\Block\Widget\Grid\Extended;
class Product extends \Magento\Backend\Block\Widget\Grid\Extended
{
/**
* Core registry
*
* @var \Magento\Framework\Registry
*/
protected $_coreRegistry = null;
/**
* @var \Magento\Catalog\Model\ProductFactory
*/
protected $_productFactory;
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Backend\Helper\Data $backendHelper
* @param \Magento\Productlabel\Model\ProductFactory $productFactory
* @param \Magento\Framework\Registry $coreRegistry
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Backend\Helper\Data $backendHelper,
\Magento\Catalog\Model\ProductFactory $productFactory,
\Magento\Framework\Registry $coreRegistry,
array $data = []
) {
$this->_productFactory = $productFactory;
$this->_coreRegistry = $coreRegistry;
parent::__construct($context, $backendHelper, $data);
}
/**
* @return void
*/
protected function _construct()
{
parent::_construct();
$this->setId('catalog_category_products');
$this->setDefaultSort('entity_id');
$this->setUseAjax(true);
}
/**
* @return array|null
*/
public function getCategory()
{
return $this->_coreRegistry->registry('mymodule_item');
}
/**
* @param Column $column
* @return $this
*/
protected function _addColumnFilterToCollection($column)
{
// Set custom filter for in category flag
if ($column->getId() == 'in_category') {
$productIds = $this->_getSelectedProducts();
if (empty($productIds)) {
$productIds = 0;
}
if ($column->getFilter()->getValue()) {
$this->getCollection()->addFieldToFilter('entity_id', ['in' => $productIds]);
} elseif (!empty($productIds)) {
$this->getCollection()->addFieldToFilter('entity_id', ['nin' => $productIds]);
}
} else {
parent::_addColumnFilterToCollection($column);
}
return $this;
}
/**
* @return Grid
*/
protected function _prepareCollection()
{
if ($this->getCategory()->getId()) {
$this->setDefaultFilter(['in_category' => 1]);
}
$collection = $this->_productFactory->create()->getCollection()->addAttributeToSelect(
'name'
)->addAttributeToSelect(
'sku'
)->addAttributeToSelect(
'price'
)->joinField(
'position',
'catalog_category_product',
'position',
'product_id=entity_id',
'category_id=' . (int)$this->getRequest()->getParam('id', 0),
'left'
);
$storeId = (int)$this->getRequest()->getParam('store', 0);
if ($storeId > 0) {
$collection->addStoreFilter($storeId);
}
$this->setCollection($collection);
if ($this->getCategory()->getProductsReadonly()) {
$productIds = $this->_getSelectedProducts();
if (empty($productIds)) {
$productIds = 0;
}
$this->getCollection()->addFieldToFilter('entity_id', ['in' => $productIds]);
}
return parent::_prepareCollection();
}
/**
* @return Extended
*/
protected function _prepareColumns()
{
if (!$this->getCategory()->getProductsReadonly()) {
$this->addColumn(
'in_category',
[
'type' => 'checkbox',
'name' => 'in_category',
'values' => $this->_getSelectedProducts(),
'index' => 'entity_id',
'header_css_class' => 'col-select col-massaction',
'column_css_class' => 'col-select col-massaction'
]
);
}
$this->addColumn(
'entity_id',
[
'header' => __('ID'),
'sortable' => true,
'index' => 'entity_id',
'header_css_class' => 'col-id',
'column_css_class' => 'col-id'
]
);
$this->addColumn('name', ['header' => __('Name'), 'index' => 'name']);
$this->addColumn('sku', ['header' => __('SKU'), 'index' => 'sku']);
$this->addColumn(
'price',
[
'header' => __('Price'),
'type' => 'currency',
'currency_code' => (string)$this->_scopeConfig->getValue(
\Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
),
'index' => 'price'
]
);
$this->addColumn(
'position',
[
'header' => __('Position'),
'type' => 'number',
'index' => 'position',
'editable' => !$this->getCategory()->getProductsReadonly()
]
);
return parent::_prepareColumns();
}
/**
* @return string
*/
public function getGridUrl()
{
return $this->getUrl('catalog/category/grid', ['_current' => true]);
}
/**
* @return array
*/
protected function _getSelectedProducts()
{
$products = $this->getRequest()->getPost('selected_products');
if ($products === null) {
$products = $this->getCategory()->getProductsPosition();
return array_keys($products);
}
return $products;
}
}
web/templates/mymodule/category/edit/assign_products.phtml
$blockGrid = $block->getBlockGrid();
$gridJsObjectName = $blockGrid->getJsObjectName();
?>
<?php echo $block->getGridHtml(); ?>
<input type="hidden" name="category_products" id="in_category_products" data-form-part="mymodule_form" value="" />
<script type="text/x-magento-init">
{
"*": {
"Company_Mymodule/mymodule/category/assign-products": {
"selectedProducts": <?php /* @escapeNotVerified */ echo $block->getProductsJson(); ?>,
"gridJsObjectName": <?php /* @escapeNotVerified */ echo '"' . $gridJsObjectName . '"' ?: '{}'; ?>
}
}
}
</script>
<!-- @todo remove when "UI components" will support such initialization -->
<script>
require('mage/apply/main').apply();
</script>
assign-products.js
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
/* global $, $H */
define([
'mage/adminhtml/grid'
], function () {
'use strict';
return function (config) {
var selectedProducts = config.selectedProducts,
categoryProducts = $H(selectedProducts),
gridJsObject = window[config.gridJsObjectName],
tabIndex = 1000;
$('in_category_products').value = Object.toJSON(categoryProducts);
/**
* Register Category Product
*
* @param {Object} grid
* @param {Object} element
* @param {Boolean} checked
*/
function registerCategoryProduct(grid, element, checked) {
if (checked) {
if (element.positionElement) {
element.positionElement.disabled = false;
categoryProducts.set(element.value, element.positionElement.value);
}
} else {
if (element.positionElement) {
element.positionElement.disabled = true;
}
categoryProducts.unset(element.value);
}
$('in_category_products').value = Object.toJSON(categoryProducts);
grid.reloadParams = {
'selected_products[]': categoryProducts.keys()
};
}
/**
* Click on product row
*
* @param {Object} grid
* @param {String} event
*/
function categoryProductRowClick(grid, event) {
var trElement = Event.findElement(event, 'tr'),
isInput = Event.element(event).tagName === 'INPUT',
checked = false,
checkbox = null;
if (trElement) {
checkbox = Element.getElementsBySelector(trElement, 'input');
if (checkbox[0]) {
checked = isInput ? checkbox[0].checked : !checkbox[0].checked;
gridJsObject.setCheckboxChecked(checkbox[0], checked);
}
}
}
/**
* Change product position
*
* @param {String} event
*/
function positionChange(event) {
var element = Event.element(event);
if (element && element.checkboxElement && element.checkboxElement.checked) {
categoryProducts.set(element.checkboxElement.value, element.value);
$('in_category_products').value = Object.toJSON(categoryProducts);
}
}
/**
* Initialize category product row
*
* @param {Object} grid
* @param {String} row
*/
function categoryProductRowInit(grid, row) {
var checkbox = $(row).getElementsByClassName('checkbox')[0],
position = $(row).getElementsByClassName('input-text')[0];
if (checkbox && position) {
checkbox.positionElement = position;
position.checkboxElement = checkbox;
position.disabled = !checkbox.checked;
position.tabIndex = tabIndex++;
Event.observe(position, 'keyup', positionChange);
}
}
gridJsObject.rowClickCallback = categoryProductRowClick;
gridJsObject.initRowCallback = categoryProductRowInit;
gridJsObject.checkboxCheckCallback = registerCategoryProduct;
if (gridJsObject.rows) {
gridJsObject.rows.each(function (row) {
categoryProductRowInit(gridJsObject, row);
});
}
};
});
Now the product grid appears on my form, but the issue is no product ids are getting on post values.Moreover the ajax actions are also not working.{I don't want to show position field in product grid compared to the default product grid in category form}
Please help me, Iam struggling with this product grid.:(