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>
2 Answers 2
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
-
Here, where can we have to register our data source ??Ravi Soni– Ravi Soni2019年12月23日 08:50:55 +00:00Commented Dec 23, 2019 at 8:50
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
Explore related questions
See similar questions with these tags.