Magento – Default filtering in UI Component Grid

adminfiltergridmagento-2.1uicomponent

I need to filter a grid view to show only where is_approved = true on one of my grids.

This needs to happen on page load (i.e. don't want the user to have to specify a filter).

The grids are made through UI Components, not blocks so this answer and similar applicable. I also find the docs a bit vague/not complete (what does "…" mean?!)

I'm not quite sure where to start after having tried various options but can't find any documentation on it or answered questions.

UI Component

<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">sample_post_listing.sample_post_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">sample_post_listing.sample_post_listing.listing_top.listing_filters</item>
                        <item name="imports" xsi:type="array">
                            <item name="visible" xsi:type="string">sample_post_listing.sample_post_listing.listing_top.bookmarks:current.columns.${ $.index }.visible</item>
                        </item>
                    </item>
                </item>
            </argument>
            <filterInput name="is_approved">0</filterInput>
        </filters>

    <column name="is_approved">
        <argument name="data" xsi:type="array">
            <item name="options" xsi:type="array">
                <item name="disable" xsi:type="array">
                    <item name="value" xsi:type="string">0</item>
                    <item name="label" xsi:type="string" translate="true">Pending</item>
                </item>
                <item name="enable" xsi:type="array">
                    <item name="value" xsi:type="string">1</item>
                    <item name="label" xsi:type="string" translate="true">Approved</item>
                </item>
            </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">Status</item>
            </item>
        </argument>
    </column>

Data Injection

<!-- Data Providers for Admin Grids -->
<virtualType name="PostsGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
    <arguments>
        <argument name="collection" xsi:type="object" shared="false">Sample\Sample\Model\Resource\Subscription\Collection</argument>
        <argument name="filterPool" xsi:type="object" shared="false">SubscriptionGirdFilterPool</argument>
    </arguments>
</virtualType>

<!-- Grid Collections -->
<virtualType name="Sample\Sample\Model\ResourceModel\Posts\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
    <arguments>
        <argument name="mainTable" xsi:type="string">sample_sample_posts</argument>
        <argument name="resourceModel" xsi:type="string">Sample\Sample\Model\ResourceModel\Posts</argument>
        <argument name="default_filter" xsi:type="array">
            <item name="id" xsi:type="string">0</item>
        </argument>
    </arguments>
</virtualType>

Best Answer

You can create your own collection which will provide the items you like.

Create a new collection. Sample\Sample\Model\ResourceModel\Posts\Grid\Collection

that collection should:

  • a. Implement the Magento\Framework\Api\Search\SearchResultInterface. Check the functions of that Interface and put them in your collection

  • b. Better extend your already existing Collection: Sample\Sample\Model\ResourceModel\Posts\Collection

So the new collection should be like that:

<?php
namespace Sample\Sample\Model\ResourceModel\Posts;

class Collection extends \Sample\Sample\Model\ResourceModel\Posts\Collection implements 
    \Magento\Framework\Api\Search\SearchResultInterface
{

    protected $_idFieldName = 'entity_id';

    /**
     *
     * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory            
     * @param \Psr\Log\LoggerInterface $logger            
     * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy            
     * @param \Magento\Framework\Event\ManagerInterface $eventManager            
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager            
     * @param mixed|null $mainTable            
     * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $eventPrefix            
     * @param mixed $eventObject            
     * @param mixed $resourceModel            
     * @param string $model            
     * @param null $connection            
     * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb|null $resource
     *            @SuppressWarnings(PHPMD.ExcessiveParameterList)
     *            
     */
    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 = null, \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null)
    {
        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
        $this->logger = $logger;
        $this->_eventPrefix = $eventPrefix;
        $this->_eventObject = $eventObject;
        $this->_init($model, $resourceModel);
        $this->setMainTable($mainTable);
        $this->storeManager = $storeManager;
    }

    /**
     *
     * @return \Magento\Framework\Api\Search\AggregationInterface
     */
    public function getAggregations()
    {
        return $this->aggregations;
    }

    /**
     *
     * @param \Magento\Framework\Api\Search\AggregationInterface $aggregations            
     * @return void
     */
    public function setAggregations($aggregations)
    {
        $this->aggregations = $aggregations;
    }

    /**
     *
     * @return \Magento\Framework\Api\Search\SearchCriteriaInterface|null
     */
    public function getSearchCriteria()
    {
        return $this->searchCriteria;
    }

    /**
     *
     * @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria            
     * @return $this @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function setSearchCriteria(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
    {
        $this->searchCriteria = $searchCriteria;
        return $this;
    }

    /**
     * Get total count.
     *
     * @return int
     */
    public function getTotalCount()
    {
        return $this->getSize();
    }

    /**
     * Set total count.
     *
     * @param int $totalCount            
     * @return $this @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function setTotalCount($totalCount)
    {
        return $this;
    }

    /**
     * Set items list.
     *
     * @param \Magento\Framework\Api\ExtensibleDataInterface[] $items            
     * @return $this @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function setItems(array $items = null)
    {
        return $this;
    }

    /**
     * This is the function that will add the filter
     */
    protected function _beforeLoad()
    {
        parent::_beforeLoad();
        $this->addFieldToFilter('is_approved',['eq'=>true]);
        return $this;
    }
}
  • Check the last function named _beforeLoad() This adds the filter you like

then go the di.xml and replace:

<virtualType name="Sample\Sample\Model\ResourceModel\Posts\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
    <arguments>
        <argument name="mainTable" xsi:type="string">sample_sample_posts</argument>
        <argument name="resourceModel" xsi:type="string">Sample\Sample\Model\ResourceModel\Posts</argument>
        <argument name="default_filter" xsi:type="array">
            <item name="id" xsi:type="string">0</item>
        </argument>
    </arguments>
</virtualType>

with:

<type name="Sample\Sample\Model\ResourceModel\Posts\Grid\Collection">
    <arguments>
        <argument name="mainTable" xsi:type="string">sample_sample_posts</argument>
        <argument name="resourceModel" xsi:type="string">Sample\Sample\Model\ResourceModel\Posts</argument>            
    </arguments>
</type>

You can now have full control of the collection. You can find a similar example here: https://github.com/magento/magento2/blob/develop/app/code/Magento/Sales/Model/ResourceModel/Grid/Collection.php