I have added product grid in Magento 2 admin form using this link: product grid. But now I am creating admin form using ui component and I am not able to change product grid using ui component. Please help me.
view/adminhtml/layout/productlabel_productlabel_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">
<body>
<referenceContainer name="content">
<uiComponent name="productlabel_form"/>
</referenceContainer>
</body>
</page>
view/adminhtml/ui_component/productlabel_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 in Category</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">160</item>
</item>
</argument>
<htmlContent name="html_content">
<argument name="block" xsi:type="object">Magento\Catalog\Block\Adminhtml\Category\AssignProducts</argument>
</htmlContent>
</container>
</fieldset>
Please Help!
-
show your code what you have tried and where you are facing issue.Priyank– Priyank2016年12月12日 04:37:59 +00:00Commented Dec 12, 2016 at 4:37
2 Answers 2
Please check this.
Step 1: Add the following code in your ui form
<fieldset name="assign_products">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Assign 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">Namespace\Module\Block\Adminhtml\Products\Edit\AssignProducts</argument>
</htmlContent>
</container>
</fieldset>
Step 2: Create AssignProducts.php in Namespace\Module\Block\Adminhtml\Products\Edit
namespace Namespace\Module\Block\Adminhtml\Products\Edit;
class AssignProducts extends \Magento\Backend\Block\Template
{
/**
* Block template
*
* @var string
*/
protected $_template = 'products/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;
protected $_productCollectionFactory;
/**
* 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,
\Namespace\Module\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory, //your custom collection
array $data = []
) {
$this->registry = $registry;
$this->jsonEncoder = $jsonEncoder;
$this->_productCollectionFactory = $productCollectionFactory;
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(
'Namespace\Module\Block\Adminhtml\Products\Edit\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()
{
$vProducts = $this->_productCollectionFactory->create()
->addFieldToFilter('customer_id', $this->getItem()->getCustomerId())
->addFieldToSelect('product_id');
$products = array();
foreach($vProducts as $pdct){
$products[$pdct->getProductId()] = '';
}
if (!empty($products)) {
return $this->jsonEncoder->encode($products);
}
return '{}';
}
public function getItem()
{
return $this->registry->registry('my_item');
}
}
Step3:Create Product.php in Namespace\Module\Block\Adminhtml\Products\Edit\Tab\
namespace Namespace\Module\Block\Adminhtml\Products\Edit\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
{
protected $logger;
/**
* Core registry
*
* @var \Magento\Framework\Registry
*/
protected $_coreRegistry = null;
/**
* @var \Magento\Catalog\Model\ProductFactory
*/
protected $_productFactory;
protected $_productCollectionFactory;
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Backend\Helper\Data $backendHelper,
\Magento\Catalog\Model\ProductFactory $productFactory,
\Namespace\Module\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Framework\Registry $coreRegistry,
array $data = []
) {
$this->_productFactory = $productFactory;
$this->_coreRegistry = $coreRegistry;
$this->_productCollectionFactory = $productCollectionFactory;
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 getItem()
{
return $this->_coreRegistry->registry('my_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->getItem()->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->getItem()->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->getItem()->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->getItem()->getProductsReadonly()
]
);
return parent::_prepareColumns();
}
/**
* @return string
*/
public function getGridUrl()
{
return $this->getUrl('module/products/grid', ['_current' => true]);
}
/**
* @return array
*/
protected function _getSelectedProducts()
{
$products = $this->getRequest()->getPost('selected_products');
if ($products === null) {
$vProducts = $this->_productCollectionFactory->create()
->addFieldToFilter('customer_id', $this->getItem()->getCustomerId())
->addFieldToSelect('product_id');
$products = array();
foreach($vProducts as $pdct){
$products[] = $pdct->getProductId();
}
}
return $products;
}
}
Step4:Create assign_products.phtml in Namespace\Module\view\adminhtml\templates\products\
<?php
$blockGrid = $block->getBlockGrid();
$gridJsObjectName = $blockGrid->getJsObjectName();
?>
<?php echo $block->getGridHtml(); ?>
<input type="hidden" name="category_products" id="in_category_products" data-form-part="your_form" value="" />
<script type="text/x-magento-init">
{
"*": {
"Namespace_Module/products/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>
Step 4: Copy vendor/magento/module-catalog/view/adminhtml/web/catalog/category/assign-products.js to Namespace/Module/view/adminhtml/web/products/
Step 5: Create Grid.php Namespace/Module/Controller/Adminhtml/Products
namespace Namespace\Module\Controller\Adminhtml\Products;
class Grid extends \Namespace\Module\Controller\Adminhtml\Products\Product
{
/**
* @var \Magento\Framework\Controller\Result\RawFactory
*/
protected $resultRawFactory;
/**
* @var \Magento\Framework\View\LayoutFactory
*/
protected $layoutFactory;
/**
* @param \Magento\Backend\App\Action\Context $context
* @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory
* @param \Magento\Framework\View\LayoutFactory $layoutFactory
*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\Controller\Result\RawFactory $resultRawFactory,
\Magento\Framework\View\LayoutFactory $layoutFactory
) {
parent::__construct($context);
$this->resultRawFactory = $resultRawFactory;
$this->layoutFactory = $layoutFactory;
}
/**
* Grid Action
* Display list of products related to current category
*
* @return \Magento\Framework\Controller\Result\Raw
*/
public function execute()
{
$item = $this->_initItem(true);
if (!$item) {
/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultRedirectFactory->create();
return $resultRedirect->setPath('module/item/new', ['_current' => true, 'id' => null]);
}
/** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
$resultRaw = $this->resultRawFactory->create();
return $resultRaw->setContents(
$this->layoutFactory->create()->createBlock(
'Namespace\Module\Block\Adminhtml\Products\Edit\Tab\Product',
'category.product.grid'
)->toHtml()
);
}
protected function _initItem($getRootInstead = false)
{
$id = (int)$this->getRequest()->getParam('id', false);
$myModel = $this->_objectManager->create('Namespace\Module\Model\Item');
if ($id) {
$myModel->load($id);
}
$this->_objectManager->get('Magento\Framework\Registry')->register('item', $myModel);
$this->_objectManager->get('Magento\Framework\Registry')->register('my_item', $myModel);
$this->_objectManager->get('Magento\Cms\Model\Wysiwyg\Config');
return $storeModel;
}
}
Step 6: Create Product.php Namespace/Module/Controller/Adminhtml/Products
namespace Namespace\Module\Controller\Adminhtml\Products;
abstract class Product extends \Magento\Backend\App\Action
{
/**
* Authorization level of a basic admin session
*
* @see _isAllowed()
*/
const ADMIN_RESOURCE = 'Namespace_Module::item_list';
}
-
1I following above spates but i getting one error
Call to a member function getProductsReadonly() on null in Product.phpcan you help me ?Deexit Sanghani– Deexit Sanghani2017年02月14日 10:44:47 +00:00Commented Feb 14, 2017 at 10:44 -
1Can you please share your codeJancy Abraham– Jancy Abraham2017年02月14日 11:04:07 +00:00Commented Feb 14, 2017 at 11:04
-
1Same issue here. regardsTTech IT Solutions– TTech IT Solutions2017年05月16日 14:07:28 +00:00Commented May 16, 2017 at 14:07
-
1Can you please share your codeJancy Abraham– Jancy Abraham2017年05月17日 05:23:26 +00:00Commented May 17, 2017 at 5:23
-
1@AveshNaik Copy vendor/magento/module-catalog/view/adminhtml/web/catalog/category/assign-products.js to Namespace/Module/view/adminhtml/web/products/Jancy Abraham– Jancy Abraham2019年05月10日 04:50:00 +00:00Commented May 10, 2019 at 4:50
if you are getting this getProductsReadonly() on null type of error try to remove getCategory() check and also remove getId() check than products grid will be shown
Namespace\Module\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory, //your custom collection ? can you please give example
If you don't know what is this 2nd number question than it is simple copy Product/Collection.php class from Module-cataloge and create in your custom module in same path rename only namespace with your module name.
Kindly kudos me if you done or if you have any queries regarding this comment here