4

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>
7

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

5

Vanilla out of the box can achieve default filter

Inject below configs to your listing component, e.g., your_ui_component.xml

<listing ...>
    <listingToolbar ...>
        <filters ...>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="applied" xsi:type="array">
                        <item name="is_approved" xsi:type="string">1</item>
                    </item>
                </item>
            </argument>
        </filters>
    </listingToolbar>
</listing>

Flush bookmark cache

delete from ui_bookmark;

You will also need to flush Magento cache as you have modified di.xml or your_ui_component.xml

php bin/magento cache:flush

NOTE: injection can be done in different froms. For example, it can also be done with setting <filters class="YourVirtualType" /> and in di.xml inject the data.config.applied array to <virtualType name="YourVirtualType" /> to achieve sharing.

How does it work

Ui component is just a js class and data is injected from your setup or from bookmark (i.e., a data storage)

mysql> select * from ui_bookmark order by bookmark_id desc limit 1\G
*************************** 1. row ***************************
bookmark_id: 39
    user_id: 1
  namespace: product_listing
 identifier: current
    current: 0
      title: NULL
     config: {"current":{"columns":{"entity_id":{"visible":true,"sorting":"asc"},"name":{"visible":true,"sorting":false},"sku":{"visible":true,"sorting":false},"price":{"visible":true,"sorting":false},"websites":{"visible":true,"sorting":false},"qty":{"visible":true,"sorting":false},"short_description":{"visible":false,"sorting":false},"special_price":{"visible":false,"sorting":false},"cost":{"visible":false,"sorting":false},"weight":{"visible":false,"sorting":false},"meta_title":{"visible":false,"sorting":false},"meta_keyword":{"visible":false,"sorting":false},"meta_description":{"visible":false,"sorting":false},"url_key":{"visible":false,"sorting":false},"msrp":{"visible":false,"sorting":false},"ids":{"visible":true,"sorting":false},"type_id":{"visible":true,"sorting":false},"attribute_set_id":{"visible":true,"sorting":false},"visibility":{"visible":true,"sorting":false},"status":{"visible":true,"sorting":false},"manufacturer":{"visible":false,"sorting":false},"color":{"visible":false,"sorting":false},"custom_design":{"visible":false,"sorting":false},"page_layout":{"visible":false,"sorting":false},"country_of_manufacture":{"visible":false,"sorting":false},"custom_layout":{"visible":false,"sorting":false},"tax_class_id":{"visible":false,"sorting":false},"gift_message_available":{"visible":false,"sorting":false},"actions":{"visible":true,"sorting":false},"thumbnail":{"visible":true,"sorting":false},"special_from_date":{"visible":false,"sorting":false},"special_to_date":{"visible":false,"sorting":false},"news_from_date":{"visible":false,"sorting":false},"news_to_date":{"visible":false,"sorting":false},"custom_design_from":{"visible":false,"sorting":false},"custom_design_to":{"visible":false,"sorting":false}},"displayMode":"grid","paging":{"options":{"20":{"value":20,"label":20},"30":{"value":30,"label":30},"50":{"value":50,"label":50},"100":{"value":100,"label":100},"200":{"value":200,"label":200}},"value":20},"positions":{"ids":0,"entity_id":1,"thumbnail":2,"name":3,"type_id":4,"attribute_set_id":5,"sku":6,"price":7,"qty":8,"visibility":9,"status":10,"websites":11,"short_description":12,"special_price":13,"special_from_date":14,"special_to_date":15,"cost":16,"weight":17,"manufacturer":18,"meta_title":19,"meta_keyword":20,"meta_description":21,"color":22,"news_from_date":23,"news_to_date":24,"custom_design":25,"custom_design_from":26,"custom_design_to":27,"page_layout":28,"country_of_manufacture":29,"custom_layout":30,"url_key":31,"msrp":32,"tax_class_id":33,"gift_message_available":34,"actions":35},"filters":{"applied":{"placeholder":true,"status":"2"}}}}
 created_at: 0000-00-00 00:00:00
 updated_at: 0000-00-00 00:00:00
1 row in set (0.00 sec)

When you interact with the grid (e.g., moving columns order, filtering, etc...), Magento persists it into ui_bookmark with the same data structure you can inject.

If you look into config, you will find the filters data which offers a way to inject default filter.

{
  "current": {
    ...
    "filters": {
      "applied": {
        "placeholder": true,
        "status": "2"
      }
    }
  }
}

More details on what config you can inject, see vendor/magento/module-ui/view/base/web/js/grid/filters/filters.js

Catalog grid filtering with disabled products

The above is an example of catalog product grid filtering with disabled products

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.