2

I need to add a collection filter to my grid. I do few search on Internet but unfortunately it can't resolve my case.

I'm using gridContainer instead of usual way.

Here is my files:

layout.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <update handle="styles"/>
    <body>
        <referenceContainer name="content">
            <uiComponent name="test_module_listing"/>
        </referenceContainer>
    </body>
</page>

ui_component.xml

<?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">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">test_modules_listing.integration_upload_listing_data_source</item>
            <item name="deps" xsi:type="string">test_modules_listing.integration_upload_listing_data_source</item>
        </item>
        <item name="spinner" xsi:type="string">test_modules_columns</item>
    </argument>
    <dataSource name="test_modules_listing_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">TestGridDataProvider</argument>
            <argument name="name" xsi:type="string">test_modules_listing_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">unique_id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="update_url" xsi:type="url" path="mui/index/render"/>
                </item>
            </argument>
        </argument>
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
            </item>
        </argument>
    </dataSource>
    <container name="listing_top">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="template" xsi:type="string">ui/grid/toolbar</item>
            </item>
        </argument>
        <bookmark name="bookmarks">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/bookmarks/bookmarks</item>
                    <item name="displayArea" xsi:type="string">dataGridActions</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="saveUrl" xsi:type="url" path="mui/bookmark/save"/>
                        <item name="deleteUrl" xsi:type="url" path="mui/bookmark/delete"/>
                        <item name="namespace" xsi:type="string">test_modules_listing</item>
                    </item>
                </item>
            </argument>
        </bookmark>
        <container name="columns_controls">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="columnsData" xsi:type="array">
                        <item name="provider" xsi:type="string">test_modules_listing.test_modules_listing.test_modules_columns</item>
                    </item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item>
                    <item name="displayArea" xsi:type="string">dataGridActions</item>
                </item>
            </argument>
        </container>
        <filterSearch name="fulltext">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/search/search</item>
                    <item name="displayArea" xsi:type="string">dataGridFilters</item>
                    <item name="provider" xsi:type="string">test_modules_listing.integration_upload_listing_data_source</item>
                    <item name="chipsProvider" xsi:type="string">test_modules_listing.test_modules_listing.listing_top.listing_filters_chips</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">test_modules_listing.test_modules_listing.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.search</item>
                    </item>
                </item>
            </argument>
        </filterSearch>
        <filters name="listing_filters">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="displayArea" xsi:type="string">dataGridFilters</item>
                    <item name="dataScope" xsi:type="string">filters</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">test_modules_listing.test_modules_listing.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.filters</item>
                    </item>
                    <item name="childDefaults" xsi:type="array">
                        <item name="provider" xsi:type="string">test_modules_listing.test_modules_listing.listing_top.listing_filters</item>
                        <item name="imports" xsi:type="array">
                            <item name="visible" xsi:type="string">test_modules_listing.test_modules_listing.listing_top.bookmarks:current.columns.${ $.index }.visible</item>
                        </item>
                    </item>
                </item>
            </argument>
            <filterRange name="unique_id">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="dataScope" xsi:type="string">unique_id</item>
                        <item name="label" xsi:type="string" translate="true">ID</item>
                        <item name="childDefaults" xsi:type="array">
                            <item name="provider" xsi:type="string">test_modules_listing.test_modules_listing.listing_top.listing_filters</item>
                        </item>
                    </item>
                </argument>
                <filterInput name="from">
                    <argument name="data" xsi:type="array">
                        <item name="config" xsi:type="array">
                            <item name="dataScope" xsi:type="string">from</item>
                            <item name="label" xsi:type="string" translate="true">from</item>
                            <item name="placeholder" xsi:type="string" translate="true">From</item>
                        </item>
                    </argument>
                </filterInput>
                <filterInput name="to">
                    <argument name="data" xsi:type="array">
                        <item name="config" xsi:type="array">
                            <item name="dataScope" xsi:type="string">to</item>
                            <item name="label" xsi:type="string" translate="true">to</item>
                            <item name="placeholder" xsi:type="string" translate="true">To</item>
                        </item>
                    </argument>
                </filterInput>
            </filterRange>
            ......
        </filters>
        <massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">test_modules_listing.test_modules_listing.test_modules_columns.ids</item>
                    <item name="indexField" xsi:type="string">unique_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="customerexport/upload/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>
        <paging name="listing_paging">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">test_modules_listing.test_modules_listing.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.paging</item>
                    </item>
                    <item name="selectProvider" xsi:type="string">test_modules_listing.test_modules_listing.test_modules_columns.ids</item>
                    <item name="displayArea" xsi:type="string">bottom</item>
                    <item name="options" xsi:type="array">
                        <item name="20" xsi:type="array">
                            <item name="value" xsi:type="number">20</item>
                            <item name="label" xsi:type="string" translate="true">20</item>
                        </item>
                        <item name="30" xsi:type="array">
                            <item name="value" xsi:type="number">30</item>
                            <item name="label" xsi:type="string" translate="true">30</item>
                        </item>
                        <item name="50" xsi:type="array">
                            <item name="value" xsi:type="number">50</item>
                            <item name="label" xsi:type="string" translate="true">50</item>
                        </item>
                        <item name="100" xsi:type="array">
                            <item name="value" xsi:type="number">100</item>
                            <item name="label" xsi:type="string" translate="true">100</item>
                        </item>
                        <item name="200" xsi:type="array">
                            <item name="value" xsi:type="number">200</item>
                            <item name="label" xsi:type="string" translate="true">200</item>
                        </item>
                    </item>
                </item>
            </argument>
        </paging>
    </container>
    <columns name="test_modules_columns">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="storageConfig" xsi:type="array">
                    <item name="provider" xsi:type="string">test_modules_listing.test_modules_listing.listing_top.bookmarks</item>
                    <item name="namespace" xsi:type="string">current</item>
                </item>
                <item name="childDefaults" xsi:type="array">
                    <item name="fieldAction" xsi:type="array">
                        <item name="provider" xsi:type="string">test_modules_listing.test_modules_listing.test_modules_columns.actions</item>
                        <item name="target" xsi:type="string">applyAction</item>
                        <item name="params" xsi:type="array">
                            <item name="0" xsi:type="string">edit</item>
                            <item name="1" xsi:type="string">${ $.$data.rowIndex }</item>
                        </item>
                    </item>
                    <item name="controlVisibility" xsi:type="boolean">true</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">test_modules_listing.test_modules_listing.listing_top.bookmarks</item>
                        <item name="root" xsi:type="string">columns.${ $.index }</item>
                        <item name="namespace" xsi:type="string">current.${ $.storageConfig.root}</item>
                    </item>
                </item>
            </item>
        </argument>
        <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">unique_id</item>
                </item>
            </argument>
        </selectionsColumn>

        <column name="unique_id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">textRange</item>
                    <item name="sorting" xsi:type="string">asc</item>
                    <item name="label" xsi:type="string" translate="true">ID</item>
                </item>
            </argument>
        </column>
        ....
        <column name="source_type">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">Test\Modules\Model\Something\Source\SourceType</item>
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">select</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
                    <item name="editor" xsi:type="string">select</item>
                    <item name="dataType" xsi:type="string">select</item>
                    <item name="label" xsi:type="string" translate="true">Source Type</item>
                </item>
            </argument>
        </column>
        <actionsColumn name="actions" class="Test\Modules\Ui\Component\Listing\Column\TestActions">
            <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">107</item>
                    <item name="indexField" xsi:type="string">unique_id</item>
                </item>
            </argument>
        </actionsColumn>
    </columns>
</listing>

di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Test\Modules\Api\Data\TestInterface" type="Test\Modules\Model\Test" />
<virtualType name="TestGridFilterPool" type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
    <arguments>
        <argument name="appliers" xsi:type="array">
            <item name="regular" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\RegularFilter</item>
            <item name="fulltext" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\FulltextFilter</item>
        </argument>
    </arguments>
</virtualType>
<virtualType name="TestGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
    <arguments>
        <argument name="collection" xsi:type="object" shared="false">Test\Modules\Model\Resource\Test\Collection</argument>
        <argument name="filterPool" xsi:type="object" shared="false">TestGridFilterPool</argument>
    </arguments>
</virtualType>
<virtualType name="Test\Modules\Model\ResourceModel\Test\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
    <arguments>
        <argument name="mainTable" xsi:type="string">test_modules_test</argument>
        <argument name="resourceModel" xsi:type="string">Test\Modules\Model\ResourceModel\Test</argument>
    </arguments>
</virtualType>
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
    <arguments>
        <argument name="collections" xsi:type="array">
            <item name="test_modules_listing_data_source" xsi:type="string">Test\Modules\Model\ResourceModel\Upload\Test\Grid\Collection</item>
        </argument>
    </arguments>
</type>
</config>

Well, the final di.xml is from another module which I will call it module A, module A collection and grid collection are being used by module B, C,..etc

layout.xml (file in view/adminhtml/layout folder) and ui_component.xml (file in view/adminhtml/ui_component folder) are files from children modules (B, C, ... Z).

The concept here is keep module A does everything for its children, it suppose to has only one collection and only one data source.

The questions are:

  • Is is possible to filter a collection if keep using GridContainer (Magento\Backend\Block\Widget\Grid\Container) in Magento 2?
  • Why Magento\Backend\Block\Widget\Grid\Container doesn't have _prepareCollection() method?
  • How to override _prepareCollection() if my Block.php is extending from Magento\Backend\Block\Widget\Grid\Container

I tried to put a Grid.php under Test\Modules\Block\Adminhtml\Test but it just simply not working.

Grid.php

<?php
namespace Test\Modules\Block\Adminhtml\Test;

class Grid extends \Magento\Backend\Block\Widget\Grid
{
    protected function _prepareCollection()
    {
        $this->setDefaultFilter(array('field_need_to_filter' => 'value'));
        return parent::_prepareCollection();
    }
}

UPDATED (05/05/16: 1462431094)

Here is my collection file

Collection.php

<?php
namespace Test\Modules\Model\ResourceModel\Test;

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class Collection extends AbstractCollection
{
    /**
     * @var string
     */
    protected $_idFieldName = 'unique_id';

    /**
     * Define resource model
     *
     * @return void
     */
    protected function _construct()
    {
        $this->_init('Test\Modules\Model\Test', 'Test\Modules\Model\ResourceModel\Test');
    }
}

UPDATED (05/05/16: 1462438671)

There is no separate collection for grid (You can know that by reading my di.xml).

UPDATED (05/05/16: 1462440386)

In case you don't like to read. I would like to add different filter to different modules. Those modules are extending from module A, this can be done by create multiple different collection in my module A. But I don't like that, I feel comfortable with my current structure. Keep it be unique and other modules must extend and call it father.

All I need now is how to add a filter in Grid(s)

Does it make sense?

  • Do you have Test\Modules\Model\ResourceModel\Upload\Test\Collection collection file? If yes update your question with code of collection file. – Prashant Valanda May 5 '16 at 5:42
  • @PrashantValanda: Please check, I've just added collection file. – Toan Nguyen May 5 '16 at 6:53
  • Is this separate collection for grid? Have you created separate collection file for grid? – Prashant Valanda May 5 '16 at 7:35
  • @PrashantValanda There is no separate collection for grid. Take a look on my di.xml – Toan Nguyen May 5 '16 at 8:55
0

Create a collection file for grid code as below:

<?php

namespace Test\Modules\Model\ResourceModel\Test\Grid;

use Magento\Framework\Api\Search\SearchResultInterface;
use Magento\Framework\Search\AggregationInterface;
use Test\Modules\Model\ResourceModel\Upload\Test\Collection as TestCollection;


class Collection extends TestCollection implements SearchResultInterface
{

    protected $aggregations;


    public function __construct(
        \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        $mainTable,
        $eventPrefix,
        $eventObject,
        $resourceModel,
        $model = 'Magento\Framework\View\Element\UiComponent\DataProvider\Document',
        $connection,
        \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource
    ) {
        parent::__construct(
            $entityFactory,
            $logger,
            $fetchStrategy,
            $eventManager,
            $storeManager,
            $connection,
            $resource
        );
        $this->_eventPrefix = $eventPrefix;
        $this->_eventObject = $eventObject;
        $this->_init($model, $resourceModel);
        $this->setMainTable($mainTable);
    }


    public function getAggregations()
    {
        return $this->aggregations;
    }


    public function setAggregations($aggregations)
    {
        $this->aggregations = $aggregations;
    }



    public function getAllIds($limit = null, $offset = null)
    {
        return $this->getConnection()->fetchCol($this->_getAllIdsSelect($limit, $offset), $this->_bindParams);
    }


    public function getSearchCriteria()
    {
        return null;
    }


    public function setSearchCriteria(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria = null)
    {
        return $this;
    }


    public function getTotalCount()
    {
        return $this->getSize();
    }


    public function setTotalCount($totalCount)
    {
        return $this;
    }


    public function setItems(array $items = null)
    {
        return $this;
    }
}

Replace below code in di.xml

<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
    <arguments>
        <argument name="collections" xsi:type="array">
            <item name="test_modules_listing_data_source" xsi:type="string">Test\Modules\Model\ResourceModel\Upload\Test\Collection</item>
        </argument>
    </arguments>
</type>

Replce to:

<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
    <arguments>
        <argument name="collections" xsi:type="array">
            <item name="test_modules_listing_data_source" xsi:type="string">Test\Modules\Model\ResourceModel\Test\Grid\Collection</item>
        </argument>
    </arguments>
</type>
  • It doesn't help at all. It works exactly like my current collection. I used Dependency Injection, thanks Magento 2 for this new and powerful feature. What I need here is how to add a different filter for different children modules. Thanks anyway. – Toan Nguyen May 5 '16 at 9:25
  • By the way: There is no Test\Modules\Model\ResourceModel\Upload\Test\Collection in my di.xml, it already defined by my virtualType – Toan Nguyen Jun 16 '16 at 8:00

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.