Magento 2 massaction delete not working
-
29-09-2020 - |
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
.* FROMmytable
ASmain_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');
}
}
?>
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.