3

How to get product grid in my custom module using grid serialization in magento 2??

How to do Grid serialization in magento 2

2 Answers 2

4

For Product grid serialization

In your Tabs.php

 protected function _prepareLayout()
{
     .......

     $this->addTab(
            'productgrid',
            [
                'label' => __('Select Product'),
                'url' => $this->getUrl('modulename/*/actionname', ['_current' => true]),
                'class' => 'ajax',

            ]
        );

       ............
}

In your controller xml

<?xml version="1.0"?>
<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="Company\Module\Block\Adminhtml\Questions\Edit\Tab\Productgrid" name="company.module.edit.tab.productgrid"/>
    <block class="Magento\Backend\Block\Widget\Grid\Serializer" name="productgrid_grid_serializer">
        <arguments>
            <argument name="input_names" xsi:type="string">position</argument>
            <argument name="grid_block" xsi:type="string">company.module.edit.tab.productgrid</argument>
            <argument name="callback" xsi:type="string">getSelectedUpsellProducts</argument>
            <argument name="input_element_name" xsi:type="string">products</argument>
            <argument name="reload_param_name" xsi:type="string">products</argument>
        </arguments>
    </block>
</container>
</layout>

In your Controller php

class Productgrid extends \Magento\Catalog\Controller\Adminhtml\Product
{

protected $resultLayoutFactory;


public function __construct(
    \Magento\Backend\App\Action\Context $context,
    \Magento\Catalog\Controller\Adminhtml\Product\Builder $productBuilder,
    \Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory
) {
    parent::__construct($context, $productBuilder);
    $this->resultLayoutFactory = $resultLayoutFactory;
}



public function execute()
{
    $this->productBuilder->build($this->getRequest());
    $resultLayout = $this->resultLayoutFactory->create();
    $resultLayout->getLayout()->getBlock('company.module.edit.tab.productgrid')
        ->setProducts($this->getRequest()->getPost('products', null)); 
    return $resultLayout;
}
}

Your Productgrid.php

class Productgrid extends \Magento\Backend\Block\Widget\Grid\Extended
{

protected $_coreRegistry = null;


protected $_productFactory;

public function __construct(
    \Magento\Backend\Block\Template\Context $context,
    \Magento\Backend\Helper\Data $backendHelper,
    \Magento\Catalog\Model\ProductFactory $productFactory,
    \Company\Module\Model\yourFactory $yourFactory,
    \Magento\Framework\Registry $coreRegistry,
    array $data = []
) {

    $this->_productFactory = $productFactory;
    $this->_yourFactory = $yourFactory;
    $this->_coreRegistry = $coreRegistry;
    parent::__construct($context, $backendHelper, $data);
}


protected function _construct()
{
    parent::_construct();
    $this->setId('product_grid');
    $this->setDefaultSort('entity_id');
    $this->setUseAjax(true);

}




protected function _addColumnFilterToCollection($column)
{
    // Set custom filter for in product flag
    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;
}



protected function _prepareCollection()
{
    $collection = $this->_productFactory->create()->getCollection()->addAttributeToSelect(
        '*'
    );
    $this->setCollection($collection);
    return parent::_prepareCollection();
}

protected function _prepareColumns()
{

        $this->addColumn(
            'in_products',
            [
                'type' => 'radio',
                'html_name' => 'products_id',
                'required'  => true,
                'values' => $this->_getSelectedProducts(),
                'align' => 'center',
                'index' => 'entity_id',
                'header_css_class' => 'col-select',
                'column_css_class' => 'col-select'
            ]
        );



    $this->addColumn(
        'name',
        [
            'header' => __('Name'),
            'index' => 'name',
            'header_css_class' => 'col-name',
            'column_css_class' => 'col-name'
        ]
    );


    $this->addColumn(
        'sku',
        [
            'header' => __('SKU'),
            'index' => 'sku',
            'header_css_class' => 'col-sku',
            'column_css_class' => 'col-sku'
        ]
    );



    return parent::_prepareColumns();
}


public function getGridUrl()
{
    return $this->_getData(
        'grid_url'
    ) ? $this->_getData(
        'grid_url'
    ) : $this->getUrl(
        'modulename/*/actionname',
        ['_current' => true]
    );
}


protected function _getSelectedProducts()
{

    $products = array_keys($this->getSelectedProducts());

    return $products;
}


public function getSelectedProducts()
{
    $tm_id = $this->getRequest()->getParam('id');
    if(!isset($tm_id)) {
        $tm_id = 0;
    }

    // if you save product id in your custom table 

    $collection = $this->_yourFactory->create()->load($tm_id);
    $data =  $collection->getProductId();
    $products = explode(',',$data);

    $proIds = array();

    foreach($products as $product) { 
        $proIds[$product] = array('id'=>$product);
    }

    return $proIds;
}


  }

This is for radio button in grid

5
  • if I do checkbox I'm not getting the selected product in the POST? do you have any idea? Commented Mar 8, 2018 at 11:20
  • I didn't try with a checkbox, Possibility in a hidden field checkbox value is not added while you click on checkbox check that did you try @Vladimir Kerkhoff answer? it is for checkbox
    – ND17
    Commented Mar 8, 2018 at 12:20
  • I am also facing the same problem : not getting selected product id Commented Apr 13, 2018 at 8:48
  • have yuo get any solution for checkbox? Commented Jul 12, 2018 at 10:16
  • I did not check with Checkbox
    – ND17
    Commented Jul 12, 2018 at 11:49
1

The grid serialisation is available by using the Magento\Backend\Block\Widget\Grid\Serializer block class in your layout file. For example I used it in a sales order view tab that is loaded thru ajax the following way:

Layout file of the controller path that is accessed when clicking on the tab:

<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="Genmato\BackorderStatus\Block\Adminhtml\Sales\Order\View\Tab\BackorderItem" name="sales.order.view.tab.backorderitem"/>
        <block class="Magento\Backend\Block\Widget\Grid\Serializer" name="backorderitem_grid_serializer">
            <arguments>
                <argument name="input_names" xsi:type="string">qty</argument>
                <argument name="grid_block" xsi:type="string">sales.order.view.tab.backorderitem</argument>
                <argument name="callback" xsi:type="string">getCollection</argument>
                <argument name="input_element_name" xsi:type="string">backorder_status</argument>
                <argument name="reload_param_name" xsi:type="string">items</argument>
            </arguments>
        </block>
    </container>
</layout>

The tab extends the Magento\Backend\Block\Widget\Grid\Extended class (and implements Magento\Backend\Block\Widget\Tab\TabInterface) to build the grid.

Within the _prepareColumns() method you need your id field as checkbox type:

$this->addColumn(
            'item_id',
            [
                'header' => __('ID'),
                'type' => 'checkbox',
                'values' => $this->getCollection(),
                'sortable' => true,
                'index' => 'item_id',
                'header_css_class' => 'col-id',
                'column_css_class' => 'col-id'
            ]
        );

and the an editable field:

$this->addColumn(
        'qty_backordered',
        [
            'header' => __('Backorder Qty'),
            'name' => 'qty_backordered',
            'type' => 'number',
            'validate_class' => 'validate-number',
            'index' => 'qty_backordered',
            'editable' => true,
            'edit_only' => true,
            'header_css_class' => 'col-position',
            'column_css_class' => 'col-position',
        ]
    );

As the sales_order_view form doesn't have a form or save action I had to add it thru an extra button and use an AJAX post to store the values, if the form is already used with a form this should not be needed and values should be posted on save of the form.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.