Question

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');
        }
    }
    ?>
Was it helpful?

Solution

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';

OTHER TIPS

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

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top