I'm using Magento 2.3.4 and want to add product grid with checkbox as an input for sales rule form (shopping cart price rule), i follow the instruction to add product grid input from here but when I print the $_POST
value the input data does not exist. Here's my code:
app/code/Becom/Freegift/view/adminhtml/ui_component/sales_rule_form.xml
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="free_gift">
<htmlContent name="html_content">
<block name="gallery" class="Becom\Freegift\Block\Adminhtml\Products\Edit\FreegiftProducts"/>
</htmlContent>
</fieldset>
</form>
app/code/Becom/Freegift/Block/Adminhtml/Products/Edit/Tab/Product.php
namespace Becom\Freegift\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,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Framework\Registry $coreRegistry,
\Becom\Freegift\Model\RuleProductFactory $ruleProductFactory,
array $data = []
) {
$this->_productFactory = $productFactory;
$this->_coreRegistry = $coreRegistry;
$this->_productCollectionFactory = $productCollectionFactory;
$this->ruleProductFactory = $ruleProductFactory;
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()->setFlag('has_stock_status_filter', true)->addAttributeToSelect(
'name'
)->addAttributeToSelect(
'sku'
)->addAttributeToSelect(
'price'
)->joinField(
'qty',
'cataloginventory_stock_item',
'qty',
'product_id=entity_id',
'{{table}}.stock_id=1',
'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('qty', ['header' => __('Qty'), 'index' => 'qty']);
$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('freegift/products/grid', ['_current' => true]);
}
/**
* @return array
*/
protected function _getSelectedProducts()
{
$ruleId = $this->getRequest()->getParams('id');
$products = array();
if ($ruleId) {
$vProducts = $this->ruleProductFactory->create()->getCollection()
->addFieldToFilter('rule_id',$ruleId);
foreach($vProducts as $pdct){
$products[] = $pdct->getProductId();
}
}
return $products;
}
public function getRowUrl($row)
{
return false;
}
}
app/code/Becom/Freegift/Block/Adminhtml/Products/Edit/FreegiftProducts.php
namespace Becom\Freegift\Block\Adminhtml\Products\Edit;
class FreegiftProducts extends \Magento\Backend\Block\Template
{
/**
* Block template
*
* @var string
*/
protected $_template = 'products/freegift_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,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory, //your custom collection
\Becom\Freegift\Model\RuleProduct $ruleProductFactory,
array $data = []
) {
$this->registry = $registry;
$this->jsonEncoder = $jsonEncoder;
$this->_productCollectionFactory = $productCollectionFactory;
$this->ruleProductFactory = $ruleProductFactory;
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(
'Becom\Freegift\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()
{
$ruleId = $this->getRequest()->getParams('id');
$freeGiftProductsIds = array();
if ($ruleId) {
$freeGiftProducts = $this->ruleProductFactory->create()->getCollection()
->addFieldToFilter('rule_id',$ruleId);
foreach($freeGiftProducts as $freeGiftProduct){
$freeGiftProductsIds[] = $freeGiftProduct->getProductId();
}
}
$vProducts = $this->_productCollectionFactory->create();
$products = array();
foreach($vProducts as $pdct){
if (in_array($pdct->getId(),$freeGiftProductsIds)) {
$products[$pdct->getId()] = 1;
}
}
if (!empty($products)) {
return $this->jsonEncoder->encode($products);
}
return '{}';
}
public function getItem()
{
return $this->registry->registry('my_item');
}
}
app/code/Becom/Freegift/Controller/Adminhtml/Products/Product.php
namespace Becom\Freegift\Controller\Adminhtml\Products;
abstract class Product extends \Magento\Backend\App\Action
{
/**
* Authorization level of a basic admin session
*
* @see _isAllowed()
*/
const ADMIN_RESOURCE = 'Becom_Freegift::item_list';
}
app/code/Becom/Freegift/Controller/Adminhtml/Products/Grid.php
namespace Becom\Freegift\Controller\Adminhtml\Products;
class Grid extends \Becom\Freegift\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('freegift/item/new', ['_current' => true, 'id' => null]);
// }
/** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
$resultRaw = $this->resultRawFactory->create();
return $resultRaw->setContents(
$this->layoutFactory->create()->createBlock(
'Becom\Freegift\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('Becom\Freegift\Model\RuleProduct');
//
// 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;
}
}
app/code/Becom/Freegift/view/adminhtml/templates/products/freegift_products.phtml
<?php
$blockGrid = $block->getBlockGrid();
$gridJsObjectName = $blockGrid->getJsObjectName();
?>
<?php echo $block->getGridHtml(); ?>
<input type="hidden" name="category_products" id="in_category_products" data-form-part="sales_rule_form" value="" />
<script type="text/x-magento-init">
{
"*": {
"Becom_Freegift/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>
app/code/Becom/Freegift/view/adminhtml/web/products/assign-products.js same as vendor/magento/module-catalog/view/adminhtml/web/catalog/category/assign-products.js