Magento 2 custom product grid on the custom module not updating hidden values of
It should be like this like category -
AssignProducts.php
<?php
/**
* Created By : RH
*/
namespace Social\Media\Block\Adminhtml;
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;
/**
* @var \RH\CustProductGrid\Model\ResourceModel\Product\CollectionFactory
*/
protected $productFactory;
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\Json\EncoderInterface $jsonEncoder
* @param \RH\CustProductGrid\Model\ResourceModel\Product\CollectionFactory $productFactory
* @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 $productFactory,
array $data = []
) {
$this->registry = $registry;
$this->jsonEncoder = $jsonEncoder;
$this->productFactory = $productFactory;
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(
'Social\Media\Block\Adminhtml\Tab\Productgrid',
'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()
{
$entity_id = $this->getRequest()->getParam('entity_id');
$productFactory = $this->productFactory->create();
$productFactory->addFieldToSelect(['product_id', 'position']);
$productFactory->addFieldToFilter('entity_id', ['eq' => $entity_id]);
$result = [];
if (!empty($productFactory->getData())) {
foreach ($productFactory->getData() as $rhProducts) {
$result[$rhProducts['product_id']] = '';
}
return $this->jsonEncoder->encode($result);
}
return '{}';
}
public function getItem()
{
return $this->registry->registry('galaxymedia');
}
}
assign_products.phtml
<?php
/**
* Created By : RH
*/
?>
<?php
$blockGrid = $block->getBlockGrid();
$gridJsObjectName = $blockGrid->getJsObjectName();
?>
<?= $block->getGridHtml() ?>
<input type="hidden" name="related_products" data-form-part="social_form" id="rh_products" value='' />
<script type="text/x-magento-init">
{
"*": {
Social_Media/js/assign-products": {
"selectedProducts": <?= /* @escapeNotVerified */ $block->getProductsJson() ?>,
"gridJsObjectName": <?= /* @escapeNotVerified */ '"' . $gridJsObjectName . '"' ?: '{}' ?>
}
}
}
</script>
<script>
require('mage/apply/main').apply();
</script>
Productgrid.php
<?php
/**
* Created By : RH
*/
namespace Social\Media\Block\Adminhtml\Tab;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Framework\App\ObjectManager;
use Magento\Store\Model\Store;
class Productgrid extends \Magento\Backend\Block\Widget\Grid\Extended
{
/**
* @var \Magento\Framework\Registry
*/
protected $coreRegistry = null;
/**
* @var \Magento\Catalog\Model\ProductFactory
*/
protected $productFactory;
/**
* @var \RH\CustProductGrid\Model\ResourceModel\Product\CollectionFactory
*/
protected $productCollFactory;
protected $_socialform;
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Backend\Helper\Data $backendHelper
* @param \Magento\Catalog\Model\ProductFactory $productFactory
* @param \Magento\Framework\Registry $coreRegistry
* @param \Magento\Framework\Module\Manager $moduleManager
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param Visibility|null $visibility
* @param array $data
*/
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 $productCollFactory,
\Magento\Framework\Registry $coreRegistry,
\Magento\Framework\Module\Manager $moduleManager,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Social\Media\Model\SocialformFactory $socialform,
Visibility $visibility = null,
array $data = []
) {
$this->productFactory = $productFactory;
$this->productCollFactory = $productCollFactory;
$this->coreRegistry = $coreRegistry;
$this->moduleManager = $moduleManager;
$this->_storeManager = $storeManager;
$this->_socialform = $socialform;
$this->visibility = $visibility ?: ObjectManager::getInstance()->get(Visibility::class);
parent::__construct($context, $backendHelper, $data);
}
/**
* [_construct description]
* @return [type] [description]
*/
protected function _construct()
{
parent::_construct();
$this->setId('rh_grid_products');
$this->setDefaultSort('entity_id');
$this->setDefaultDir('ASC');
$this->setUseAjax(true);
if ($this->getRequest()->getParam('id')) {
$this->setDefaultFilter(['in_products' => 1]);
} else {
$this->setDefaultFilter(['in_products' => 0]);
}
$this->setSaveParametersInSession(false);
}
/**
* [get store id]
*
* @return Store
*/
protected function _getStore()
{
$storeId = (int) $this->getRequest()->getParam('store', 0);
return $this->_storeManager->getStore($storeId);
}
protected function _prepareCollection()
{
$store = $this->_getStore();
$collection = $this->productFactory->create()->getCollection()->addAttributeToSelect(
'sku'
)->addAttributeToSelect(
'name'
)->addAttributeToSelect(
'attribute_set_id'
)->addAttributeToSelect(
'type_id'
)->setStore(
$store
);
if ($this->moduleManager->isEnabled('Magento_CatalogInventory')) {
$collection->joinField(
'qty',
'cataloginventory_stock_item',
'qty',
'product_id=entity_id',
'{{table}}.stock_id=1',
'left'
);
}
if ($store->getId()) {
$collection->setStoreId($store->getId());
$collection->addStoreFilter($store);
$collection->joinAttribute(
'name',
'catalog_product/name',
'entity_id',
null,
'inner',
Store::DEFAULT_STORE_ID
);
$collection->joinAttribute(
'status',
'catalog_product/status',
'entity_id',
null,
'inner',
$store->getId()
);
$collection->joinAttribute(
'visibility',
'catalog_product/visibility',
'entity_id',
null,
'inner',
$store->getId()
);
$collection->joinAttribute('price', 'catalog_product/price', 'entity_id', null, 'left', $store->getId());
} else {
$collection->addAttributeToSelect('price');
$collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
$collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
}
$this->setCollection($collection);
return parent::_prepareCollection();
}
protected function _addColumnFilterToCollection($column)
{
if ($column->getId() == 'in_products') {
$productIds = $this->_getSelectedProducts();
if (empty($productIds)) {
$productIds = 0;
}
if ($column->getFilter()->getValue()) {
$this->getCollection()->addFieldToFilter('entity_id', ['in' => $productIds]);
} else {
if ($productIds) {
$this->getCollection()->addFieldToFilter('entity_id', ['nin' => $productIds]);
}
}
} else {
parent::_addColumnFilterToCollection($column);
}
return $this;
}
/**
* @return Extended
*/
protected function _prepareColumns()
{
$this->addColumn(
'in_products',
[
'type' => 'checkbox',
'html_name' => 'products_id',
'required' => true,
'values' => $this->_getSelectedProducts(),
'align' => 'center',
'index' => 'entity_id',
]
);
$this->addColumn(
'entity_id',
[
'header' => __('ID'),
'width' => '50px',
'index' => 'entity_id',
'type' => 'number',
]
);
$this->addColumn(
'name',
[
'header' => __('Name'),
'index' => 'name',
'header_css_class' => 'col-type',
'column_css_class' => 'col-type',
]
);
$this->addColumn(
'sku',
[
'header' => __('SKU'),
'index' => 'sku',
'header_css_class' => 'col-sku',
'column_css_class' => 'col-sku',
]
);
$store = $this->_getStore();
$this->addColumn(
'price',
[
'header' => __('Price'),
'type' => 'price',
'currency_code' => $store->getBaseCurrency()->getCode(),
'index' => 'price',
'header_css_class' => 'col-price',
'column_css_class' => 'col-price',
]
);
$this->addColumn(
'position',
[
'header' => __('Position'),
'name' => 'position',
'width' => 60,
'type' => 'number',
'validate_class' => 'validate-number',
'index' => 'position',
'editable' => true,
'edit_only' => true,
]
);
return parent::_prepareColumns();
}
/**
* @return string
*/
public function getGridUrl()
{
return $this->getUrl('galaxymedia/index/grids', ['_current' => true]);
}
/**
* @return array
*/
protected function _getSelectedProducts()
{
$products = array_keys($this->getSelectedProducts());
//$products = array_values($this->getSelectedProducts());
/*echo "<pre>";
print_r($products);
die;*/
return $products;
}
/**
* @return array
*/
public function getSelectedProducts()
{
$id = $this->getRequest()->getParam('id');
$model = $this->_socialform->create()->load($id);
$model = $model->getRelatedProducts();
$model = json_decode($model);
$grids = [];
if(!empty($model)){
foreach ($model as $key => $value) {
$grids[] = $key;
}
}
return $grids;
}
}
Grids.php
<?php
/**
* Created By : RH
*/
namespace Social\Media\Controller\Adminhtml\Index;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\Result\RawFactory;
use Magento\Framework\View\LayoutFactory;
class Grids extends \Magento\Backend\App\Action
{
/**
* @var \Magento\Framework\Controller\Result\RawFactory
*/
protected $resultRawFactory;
/**
* @var \Magento\Framework\View\LayoutFactory
*/
protected $layoutFactory;
/**
* @param Context $context
* @param Rawfactory $resultRawFactory
* @param LayoutFactory $layoutFactory
*/
public function __construct(
Context $context,
Rawfactory $resultRawFactory,
LayoutFactory $layoutFactory
) {
parent::__construct($context);
$this->resultRawFactory = $resultRawFactory;
$this->layoutFactory = $layoutFactory;
}
/**
* @return \Magento\Framework\Controller\Result\Raw
*/
public function execute()
{
$resultRaw = $this->resultRawFactory->create();
return $resultRaw->setContents(
$this->layoutFactory->create()->createBlock(
'Social\Media\Block\Adminhtml\Tab\Productgrid',
'rh.custom.tab.productgrid'
)->toHtml()
);
}
}
assign-products.js
/**
* Created by : RH
*/
/* 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;
/**
* Show selected product when edit form in associated product grid
*/
$('rh_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);
}
$('rh_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);
$('rh_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);
});
}
};
});
Data is saving properly in this format - {"1":"","2":"","3":""}
but when edit item then hidden input values show blank because of this old checkbox selected not saving in table but it is saving new checkbox selected.
Source - https://www.rohanhapani.com/magento-2-how-to-add-product-grid-in-ui-form-using-uicomponent/
Does anyone know how to solve this?