6

My custom module massaction action code as below:

<?php

namespace Namespace\Modulename\Controller\Adminhtml\Index;

use Magento\Backend\App\Action;
use Namespace\Modulename\Model\ResourceModel\Modulename\CollectionFactory;
use Magento\Ui\Component\MassAction\Filter;

/**
 * Class MassDelete
 */
class MassDelete extends \Magento\Backend\App\Action
{
     protected $_coreRegistry = null;

    /**
     * @var \Magento\Framework\View\Result\PageFactory
     */
    protected $resultPageFactory;

     protected $moduleFactory;

    /**
     * @param Action\Context $context
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     * @param \Magento\Framework\Registry $registry
     */
    public function __construct(
        Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        \Magento\Framework\Registry $registry,
        Filter $filter,
         CollectionFactory $module
    ) {
        $this->resultPageFactory = $resultPageFactory;
        $this->_coreRegistry = $registry;
        $this->moduleFactory = $module;
         $this->filter = $filter;
        parent::__construct($context);
    }


    /**
     * Execute action
     *
     * @return \Magento\Backend\Model\View\Result\Redirect
     * @throws \Magento\Framework\Exception\LocalizedException|\Exception
     */
    public function execute()
    {
        $deleteIds = $this->getRequest()->getParams('selected');

        $collection = $this->moduleFactory->create();

        $collection->addFieldToFilter('id', array('in' => $deleteIds));

        $count = 0;
        foreach ($collection as $child) {
            $child->delete();
            $count++;
        }

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

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

Using above code if I select some record it is working fine.But if I select all it is not working (no one record deleted).Also I have tried using below code.

<?php    
    namespace Namespace\Modulename\Controller\Adminhtml\Index;

    use Magento\Backend\App\Action;
    use Namespace\Modulename\Model\ResourceModel\Modulename\CollectionFactory;
    use Magento\Ui\Component\MassAction\Filter;

    /**
     * Class MassDelete
     */
    class MassDelete extends \Magento\Backend\App\Action
    {
         protected $_coreRegistry = null;

        /**
         * @var \Magento\Framework\View\Result\PageFactory
         */
        protected $resultPageFactory;

         protected $moduleFactory;

        /**
         * @param Action\Context $context
         * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
         * @param \Magento\Framework\Registry $registry
         */
        public function __construct(
            Action\Context $context,
            \Magento\Framework\View\Result\PageFactory $resultPageFactory,
            \Magento\Framework\Registry $registry,
            Filter $filter,
             CollectionFactory $module
        ) {
            $this->resultPageFactory = $resultPageFactory;
            $this->_coreRegistry = $registry;
            $this->moduleFactory = $module;
             $this->filter = $filter;
            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->moduleFactory->create());

            $count = 0;
            foreach ($collection as $child) {
                $child->delete();
                $count++;
            }

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

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

Above code gives error as below:

SQLSTATE[42S22]: Column not found: 1054 Champ '' inconnu dans where clause, query was: SELECT main_table.* FROM mytable AS main_table WHERE (`` IN('', '', '', '', '', ''))

ui_component code:

<massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">module_index_grid.module_index_grid.module_columns.ids</item>
                    <item name="indexField" xsi:type="string">module_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="module/index/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>

Model code app/code/Namespace/Modulename/Model/ResourceModel/Module.php

 <?php
    namespace Namespace\Modulename\Model\ResourceModel;

    class Module extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
    {
        /**
         * Initialize resource model
         *
         * @return void
         */
        protected function _construct()
        {       
            $this->_init('mytable', 'module_id');
        }
    }
    ?>

5 Answers 5

35

Try the following code:

<?php

namespace Vendor\ModuleName\Controller\Adminhtml\Module;

use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Vendor\ModuleName\Model\ResourceModel\Module\CollectionFactory;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\App\ResponseInterface;

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);
    }

    /**
     * Dispatch request
     *
     * @return \Magento\Framework\Controller\ResultInterface|ResponseInterface
     * @throws \Magento\Framework\Exception\NotFoundException
     */
    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 element(s) have been deleted.', $collectionSize));

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

Works perfectly for me.

Good luck! :)

Edit: if it won't work, it can be also something wrong with your grid definition, so please post it here too

Do you have following code in 'columns' node of your ui_component?

<selectionsColumn name="ids">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="resizeEnabled" xsi:type="boolean">false</item>
            <item name="resizeDefaultWidth" xsi:type="string">55</item>
            <item name="indexField" xsi:type="string">module_id</item>
        </item>
    </argument>
</selectionsColumn>

Check if you have following line in your Model\ResourceModel\Module\Collection.php file:

protected $_idFieldName = 'module_id';
17
  • It is not working i have tried with same code in my second try Commented Apr 22, 2016 at 6:33
  • Then add here also code of your massactions definition from ui_component Commented Apr 22, 2016 at 6:42
  • Thanks.Updated question with ui_component code can you please check it Commented Apr 22, 2016 at 6:46
  • Check my edit, do you have exact same code? Commented Apr 22, 2016 at 7:10
  • 5
    The last piece $_idFieldName solved it for me! Commented Aug 24, 2016 at 14:57
7

Follow this process to implement Massaction delete

Namespace: Prince

Modulename: PincodeChecker

1) Use this code in UI Grid file(prince_pincodechecker_index.xml) before

<massaction name="listing_massaction">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="selectProvider" xsi:type="string">prince_pincodechecker_index.prince_pincodechecker_index.prince_pincodechecker_columns.ids</item>
            <item name="indexField" xsi:type="string">pincode_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="prince_pincodechecker/pincodechecker/massDelete"/>
                <item name="confirm" xsi:type="array">
                    <item name="title" xsi:type="string" translate="true">Delete staffs</item>
                    <item name="message" xsi:type="string" translate="true">Are you sure you wan't to delete selected staffs?</item>
                </item>
            </item>
        </argument>
    </action>
</massaction>

You must have define indexField

<selectionsColumn name="ids">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="indexField" xsi:type="string">pincode_id</item>
        </item>
    </argument>
</selectionsColumn>

2) Create MassDelete.php controller

app/code/Prince/PincodeChecker/Controller/Adminhtml/Pincodechecker/MassDelete.php

<?php
namespace Prince\PincodeChecker\Controller\Adminhtml\Pincodechecker;

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

    protected $_filter;

    protected $_collectionFactory;

    public function __construct(
        \Magento\Ui\Component\MassAction\Filter $filter,
        \Prince\PincodeChecker\Model\ResourceModel\Pincodechecker\CollectionFactory $collectionFactory,
        \Magento\Backend\App\Action\Context $context
        ) {
        $this->_filter            = $filter;
        $this->_collectionFactory = $collectionFactory;
        parent::__construct($context);
    }

    public function execute() {
        try{ 

            $logCollection = $this->_filter->getCollection($this->_collectionFactory->create());
            //echo "<pre>";
            //print_r($logCollection->getData());
            //exit;
            foreach ($logCollection as $item) {
                $item->delete();
            }
            $this->messageManager->addSuccess(__('Log Deleted Successfully.'));
        }catch(Exception $e){
            $this->messageManager->addError($e->getMessage());
        }
        $resultRedirect = $this->resultRedirectFactory->create();
        return $resultRedirect->setPath('Prince_Pincodechecker/pincodechecker/index'); //Redirect Path
    }

     /**
     * is action allowed
     *
     * @return bool
     */
    protected function _isAllowed() {
        return $this->_authorization->isAllowed('Prince_PincodeChecker::view');
    }
}

3) Define protected $_idFieldName in collection.php

app/code/Prince/PincodeChecker/Model/ResourceModel/Pincodechecker/Collection.php

<?php
namespace Prince\PincodeChecker\Model\ResourceModel\Pincodechecker;

class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{

    /**
     * Define resource model
     *
     * @return void
     */
    protected $_idFieldName = 'pincode_id';

    protected function _construct()
    {
        $this->_init(
            'Prince\PincodeChecker\Model\Pincodechecker',
            'Prince\PincodeChecker\Model\ResourceModel\Pincodechecker'
        );
    }
}
2
  • Thanks @Prince your code working for me Commented Jul 17, 2019 at 12:53
  • hi @Prince, how can we add Massaction tree drop down here, Assign as first option, then once that is clicked, All other users in the drop down. Commented Mar 21, 2021 at 17:49
3

You can try this code :-

public function execute()

{ 
    $collection = $this->_filter->getCollection($this->_collectionFactory->create());
    $recordDeleted = 0;

    foreach ($collection as $record) {

        $deleteItem = $this->_objectManager->get('Vendor\Modulename\Model\modelname')->load($record->getId());
        $deleteItem->delete();
        $recordDeleted++;
    }

    $this->messageManager->addSuccess(__('A total of %1 record(s) have been deleted.', $recordDeleted));
    return $this->resultFactory->create(ResultFactory::TYPE_REDIRECT)->setPath('*/*/index');
}
2

You can just try inside your controller file,

 public function execute()
    {
        $deleteIds = $this->getRequest()->getParam('teams');
        if (!is_array($deleteIds) || empty($deleteIds)) {
            $this->messageManager->addError(__('Please select item(s).'));
        } else {
            try {
                foreach ($deleteIds as $itemId) {
                    $post = $this->_objectManager->get('Package\Module\Model\Module')->load($itemId);
                    $post->delete();
                }
                $this->messageManager->addSuccess(
                    __('A total of %1 record(s) have been deleted.', count($itemIds))
                );
            } catch (\Exception $e) {
                $this->messageManager->addError($e->getMessage());
            }
        }
        $resultRedirect = $this->resultRedirectFactory->create();
        return $resultRedirect->setPath('*/*/');       
    }

In above method you have to just pass your model file instead of Package\Module\Model\Module. This is working code.

2
  • Yes it is working but it is only delete some records, It will not delete if I select all. I have tried same also posted in question in first section. Commented Apr 22, 2016 at 7:08
  • have you checked above method or not, i have call object inside foreach so plz check using above method. Commented Apr 22, 2016 at 7:25
0
<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <listingToolbar name="listing_top">
            <massaction name="listing_massaction">
                <action name="order_delete">
                    <argument name="data" xsi:type="array">
                        <item name="config" xsi:type="array">
                            <item name="type" xsi:type="string">order_delete</item>
                            <item name="label" xsi:type="string" translate="true">Delete Order</item>
                            <item name="url" xsi:type="url" path="sales/order/massdelete"/>
                            <item name="confirm" xsi:type="array">
                                <item name="title" xsi:type="string" translate="true">Delete Order(s)</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>
    </listingToolbar>
</listing>

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.