6

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>
asked Mar 2, 2017 at 0:31

2 Answers 2

14

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

answered Apr 28, 2017 at 17:55
1
  • Here, where can we have to register our data source ?? Commented Dec 23, 2019 at 8:50
12

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

answered Jun 13, 2017 at 0:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.