5

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

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 Apr 22 '16 at 6:33
  • Then add here also code of your massactions definition from ui_component Apr 22 '16 at 6:42
  • Thanks.Updated question with ui_component code can you please check it Apr 22 '16 at 6:46
  • Check my edit, do you have exact same code? Apr 22 '16 at 7:10
  • 4
    The last piece $_idFieldName solved it for me! Aug 24 '16 at 14:57
4

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 Jul 17 '19 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. Mar 21 at 17:49
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. Apr 22 '16 at 7:08
  • have you checked above method or not, i have call object inside foreach so plz check using above method. Apr 22 '16 at 7:25
2

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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