3

I've created a mass action for my custom grid. i've encountered a weird problem which is when i check all the checkboxes, it won't send any post id data when i try to retrieve it with:

$this->getRequest->getParams();

but when i don't check all of them, it will send all the data that has been checked, here's my mass action code in xml:

<massaction name="listing_massaction">
  <action name="test">
    <argument name="data" xsi:type="array">
      <item name="config" xsi:type="array">
          <item name="type" xsi:type="string">test</item>
          <item name="label" xsi:type="string" translate="true">Test</item>
          <item name="url" xsi:type="url" path="namespace_module/test/massTest"/>
      </item>
    </argument>
  </action>
</massaction>

MassTest.php:

use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class MassTest extends \Magento\Backend\App\Action
{

   public function __construct(
       Context $context,
       Filter $filter,
       \Namespace\Module\Model\ResourceModel\Test\CollectionFactory $collectionFactory
   ) {
       $this->filter = $filter;
       $this->_listingProduct = $listingProduct;
       $this->_collectionFactory = $collectionFactory;
       parent::__construct($context, $filter);
   }

   public function execute(){
     //$collection = $this->filter->getCollection($this->_collectionFactory->create()); // get your selected collection
     //$collectionSize = $collection->getSize();
     //echo $collectionSize;
     $data = $this->getRequest()->getParams();
     print_r($data['selected']);
     exit;
   }

   /**
    * @param AbstractCollection $collection
    * @return \Magento\Backend\Model\View\Result\Redirect
    */
   protected function massAction(AbstractCollection $collection)
   {

   }

}
2
  • Could You please show your MassDelete.php file? Commented Mar 14, 2017 at 7:00
  • @RakeshJesadiya i've updated my question Commented Mar 14, 2017 at 7:17

3 Answers 3

3

I spent a lot of time trying to understand, what is wrong with my code, and why Magento does not send selected parameter with ids in POST request, when mass action is called. Later I found this "feature":

if you have 1 item in list of items, mass action does not send any data. You must have at least 2 items in list, and then selected parameter will exists in POST request and will consists of selected ids.

I have it in Magento 2.1.6.

3
  • yes i think magento has their way to minimize post data Commented May 5, 2017 at 15:58
  • I've run into this issue in 2.1.10. It's incredibly annoying and if it's as designed, it's incredibly short sighted. Any performance improvement gained by minimizing the post data is lost by having to retrieve the filtered collection again. Besides, getting the collection is not working in my case with a custom list.
    – Rooster242
    Commented Dec 20, 2017 at 20:48
  • Thank you for the time save
    – Badong
    Commented Apr 15, 2020 at 10:24
1

You can try the below code for new way to get the filter or selected collection from the list you selected from your grid.

<?php 

namespace Namesapce\Modulename\Controller\Adminhtml\Module;

use Magento\Framework\Controller\ResultFactory;

class MassDelete extends \Magento\Backend\App\Action {

    /**
     * @var \Magento\Ui\Component\MassAction\Filter
     */
    protected $filter;

    /**
     * @var \Namesapce\Modulename\Model\ResourceModel\ModuleModel\CollectionFactory
     */
    protected $_collectionFactory;

    /**
     * @param \Magento\Backend\App\Action\Context $context
     * @param \Magento\Ui\Component\MassAction\Filter $filter
     * @param \Namespace\Modulename\Model\ResourceModel\ModuleModel\CollectionFactory $collectionFactory
     */
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Ui\Component\MassAction\Filter $filter,
        \Namespace\Modulename\Model\ResourceModel\ModuleModel\CollectionFactory $collectionFactory
    ) {

        $this->filter = $filter;
        $this->_collectionFactory = $collectionFactory;
        parent::__construct($context);
    }

    public function execute()
    {
        $collection = $this->filter->getCollection($this->_collectionFactory->create()); // get your selected collection
        $collectionSize = $collection->getSize();

        foreach ($collection as $item) {
            $item->delete(); // Do the stuff you wann to do
        }

        $this->messageManager->addSuccess(__('A total of %1 record(s) have been deleted.', $collectionSize));

        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
        return $resultRedirect->setPath('*/*/');
    }
}
4
  • it will retrieve all the data from my table and its the problem because when i create the grid i filter the grid using <item name="filter_url_params" xsi:type="array"> <item name="some_id_in_url" xsi:type="boolean">1</item> </item> Commented Mar 14, 2017 at 7:06
  • 1
    no it will not as you see $this->filter this will filter and give you the selected rows you want.
    – Priyank
    Commented Mar 14, 2017 at 8:36
  • well in my grid there are only 4 data, and when i checked all and i print the $collectionSize it shows 6 Commented Mar 14, 2017 at 8:54
  • @Priyank Seems to be working for me, do you think could you explain how the filter works here ?
    – Badong
    Commented Aug 7, 2020 at 7:06
0

Please check it app/code/Company/Module/view/adminhtml/ui_component/company_module_grid.xml

...
<massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">company_module_grid.company_module_grid.company_module_columns.ids</item>
                    <item name="indexField" xsi:type="string">id</item>
                </item>
            </argument>
            <action name="delete">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">delete</item>
                        <item name="label" xsi:type="string" translate="true">Delete</item>
                        <item name="url" xsi:type="url" path="routername/controllername/massDelete"/>
                        <item name="confirm" xsi:type="array">
                            <item name="title" xsi:type="string" translate="true">Delete items</item>
                            <item name="message" xsi:type="string" translate="true">Are you sure you wan't to delete selected items?</item>
                        </item>
                    </item>
                </argument>
            </action>
</massaction>
...

Controller File app/code/Company/Module/Controller/Adminhtml/Controllername/MassDelete.php

<?php
namespace Company\Module\Controller\Adminhtml\Controllername;

use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Company\Module\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\Controller\ResultFactory;

/**
 * Class MassDisable
 */
class MassDelete  extends \Magento\Backend\App\Action
{
    /**
     * @var Filter
     */
    protected $filter;

    /**
     * @var CollectionFactory
     */
    protected $collectionFactory;


    /**
     * @param Context $context
     * @param Filter $filter
     * @param CollectionFactory $collectionFactory
     */
    public function __construct(Context $context, Filter $filter, CollectionFactory $collectionFactory)
    {
        $this->filter = $filter;
        $this->collectionFactory = $collectionFactory;
        parent::__construct($context);
    }
    /**
     * Execute action
     *
     * @return \Magento\Backend\Model\View\Result\Redirect
     * @throws \Magento\Framework\Exception\LocalizedException|\Exception
     */
    public function execute()
    {
        $collection = $this->filter->getCollection($this->collectionFactory->create());
        $collectionSize = $collection->getSize();

        foreach ($collection as $item) {
            $item->delete();
        }

        $this->messageManager->addSuccess(__('A total of %1 record(s) have been deleted.', $collectionSize));

        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
        return $resultRedirect->setPath('*/*/');
    }
}

Company\Module\Model\ResourceModel\Product\CollectionFactory; Please add appropriate extension factory class in about file.

2
  • the $collectionSize is still counting more then i checked if i checked it all Commented Mar 14, 2017 at 8:55
  • I don't see why retrieving the filtered collection should give the the checked items. It would return all the items in the list, checked or not, wouldn't it?
    – Rooster242
    Commented Dec 20, 2017 at 20:53

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.