I'm trying to make a mass delete action for my custom grid. A very helpful source of examples is this grid sample module by Marius but still I can't find the reason why the grid pass collection of Documents instead actual collection of models.
My mass action declaration in the grid ui component:
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">fields_grid.fields_grid_data_source</item>
<item name="deps" xsi:type="string">fields_grid.fields_grid_data_source</item>
<!--Declare the data source name which will be defined below-->
</item>
<item name="spinner" xsi:type="string">vendor_modulename_columns</item>
<!--Declare the listing of columns which will be defined below-->
<item name="buttons" xsi:type="array">
<item name="add" xsi:type="array">
<item name="name" xsi:type="string">add</item>
<item name="label" xsi:type="string" translate="true">Add New Field</item>
<item name="class" xsi:type="string">primary</item>
<item name="url" xsi:type="string">*/field/newfield</item>
</item>
<!--The button on the top of the Grid-->
</item>
</argument>
<dataSource name="fields_grid_data_source">
<!--The data source-->
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider</argument>
<argument name="name" xsi:type="string">fields_grid_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">id</argument>
<argument name="requestFieldName" xsi:type="string">id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
<item name="update_url" xsi:type="url" path="mui/index/render"/>
<item name="storageConfig" xsi:type="array">
<item name="indexField" xsi:type="string">id</item>
</item>
</item>
</argument>
</argument>
</dataSource>
<massaction name="listing_massaction">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="selectProvider" xsi:type="string">fields_grid.fields_grid.vendor_modulename_columns.ids</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</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="*/field/massdelete"/>
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">Delete fields</item>
<item name="message" xsi:type="string" translate="true">Are you sure to delete selected fields?</item>
</item>
</item>
</argument>
</action>
</massaction>
And the mass action controller:
<?php
namespace Vendor\ModuleName\Controller\Adminhtml\Field;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Registry;
use Magento\Framework\Stdlib\DateTime\Filter\Date;
use Magento\Framework\View\Result\PageFactory;
use Magento\Ui\Component\MassAction\Filter;
use Vendor\ModuleName\Api\FieldRepositoryInterface;
use Vendor\ModuleName\Controller\Adminhtml\Field;
use Vendor\ModuleName\Model\Field as FieldModel;
use Vendor\ModuleName\Model\ResourceModel\Field\CollectionFactory;
abstract class MassAction extends Field
{
/**
* @var Filter
*/
protected $filter;
/**
* @var CollectionFactory
*/
protected $collectionFactory;
/**
* @var string
*/
protected $successMessage;
/**
* @var string
*/
protected $errorMessage;
/**
* @param Registry $registry
* @param FieldRepositoryInterface $fieldRepository
* @param PageFactory $resultPageFactory
* @param Date $dateFilter
* @param Context $context
* @param Filter $filter
* @param CollectionFactory $collectionFactory
* @param $successMessage
* @param $errorMessage
*/
public function __construct(
Registry $registry,
FieldRepositoryInterface $fieldRepository,
PageFactory $resultPageFactory,
Date $dateFilter,
Context $context,
Filter $filter,
CollectionFactory $collectionFactory,
$successMessage,
$errorMessage
) {
$this->filter = $filter;
$this->collectionFactory = $collectionFactory;
$this->successMessage = $successMessage;
$this->errorMessage = $errorMessage;
parent::__construct($registry, $resultPageFactory, $dateFilter, $context, $fieldRepository);
}
/**
* @param FieldModel $field
* @return mixed
*/
protected abstract function massAction(FieldModel $field);
/**
* execute action
*
* @return \Magento\Backend\Model\View\Result\Redirect
*/
public function execute()
{
try {
$collection = $this->filter->getCollection($this->collectionFactory->create());
$collectionSize = $collection->getSize();
foreach ($collection as $field) {
$this->massAction($field); // <-- here lies the problem, $collection contains documents instead of Models
}
$this->messageManager->addSuccessMessage(__($this->successMessage, $collectionSize));
} catch (LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
$this->messageManager->addExceptionMessage($e, __($this->errorMessage));
}
$redirectResult = $this->resultRedirectFactory->create();
$redirectResult->setPath('Vendor_ModuleName/index/index');
return $redirectResult;
}
}
var_dump($collection->toArray());
returns correct array of elements which have been selected
What are the possible faults that cause this sort problem?
Best Answer
You should create a VirtualType in di.xml and type should be link to grid\collection