3

I have added product name column in my custom ui grid. In which data displayed properly but not filtered grid by product name.

Note : I set product name with comma separated in ui grid column.

Here is my code of listing file.

vendor/module/view/adminhtml/ui_component/vendor_module_grid_listing.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">vendor_module_grid_listing.vendor_module_grid_listing_data_source</item>
            <item name="deps" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing_data_source</item>
        </item>
        <item name="spinner" xsi:type="string">vendor_module_grid_columns</item>
        <item name="buttons" xsi:type="array">
            <item name="add" xsi:type="array">
                <item name="name" xsi:type="string">add</item>
                <item name="label" xsi:type="string" translate="true">Add Data Grid</item>
                <item name="class" xsi:type="string">primary</item>
                <item name="url" xsi:type="string">*/*/add/comptype/grid</item>
            </item>
        </item>
    </argument>
    <dataSource name="vendor_module_grid_listing_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Vendor\Module\Ui\Component\Listing\Grid\DataProvider</argument>
            <argument name="name" xsi:type="string">vendor_module_grid_listing_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">entity_id</argument>
            <argument name="requestFieldName" xsi:type="string">entity_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" class="\Vendor\Module\Ui\Component\Listing\Column\Bookmark">
            <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="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">vendor_module_grid_listing</item>
                    </item>
                </item>
            </argument>
        </bookmark>
        <columnsControls name="columns_controls"/>
        <component 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">vendor_module_grid_listing.vendor_module_grid_listing.vendor_module_grid_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>
        </component>
        <filterSearch name="fulltext">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="provider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing_data_source</item>
                    <item name="chipsProvider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing.listing_top.listing_filters_chips</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_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="columnsProvider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing.vendor_module_grid_columns</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.filters</item>
                    </item>
                    <item name="templates" xsi:type="array">
                        <item name="filters" xsi:type="array">
                            <item name="select" xsi:type="array">
                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
                                <item name="template" xsi:type="string">ui/grid/filters/elements/ui-select</item>
                            </item>
                        </item>
                    </item>
                    <item name="childDefaults" xsi:type="array">
                        <item name="provider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing.listing_top.listing_filters</item>
                        <item name="imports" xsi:type="array">
                            <item name="visible" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing.vendor_module_grid_columns.${ $.index }:visible</item>
                        </item>
                    </item>
                </item>
            </argument>
        </filters>
        <massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing.vendor_module_grid_columns.ids</item>
                    <item name="indexField" xsi:type="string">entity_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="*/*/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>
            <action name="edit">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">edit</item>
                        <item name="label" xsi:type="string" translate="true">Edit</item>
                        <item name="callback" xsi:type="array">
                            <item name="provider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing.vendor_module_grid_columns_editor</item>
                            <item name="target" xsi:type="string">editSelected</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">vendor_module_grid_listing.vendor_module_grid_listing.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.paging</item>
                    </item>
                    <item name="selectProvider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing.vendor_module_grid_columns.ids</item>
                </item>
            </argument>
        </paging>
    </container>
    <columns name="vendor_module_grid_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">vendor_module_grid_listing.vendor_module_grid_listing.listing_top.bookmarks</item>
                    <item name="namespace" xsi:type="string">current</item>
                </item>
                <item name="editorConfig" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing.vendor_module_grid_columns.ids</item>
                    <item name="enabled" xsi:type="boolean">false</item>
                    <item name="indexField" xsi:type="string">entity_id</item>
                    <item name="clientConfig" xsi:type="array">
                        <item name="saveUrl" xsi:type="url" path="*/*/inlineEdit"/>
                        <item name="validateBeforeSave" xsi:type="boolean">false</item>
                    </item>
                </item>
                <item name="childDefaults" xsi:type="array">
                    <item name="fieldAction" xsi:type="array">
                        <item name="provider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_listing.vendor_module_grid_columns_editor</item>
                        <item name="target" xsi:type="string">startEdit</item>
                        <item name="pagrids" xsi:type="array">
                            <item name="0" xsi:type="string">${ $.$data.rowIndex }</item>
                            <item name="1" xsi:type="boolean">true</item>
                        </item>
                    </item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">vendor_module_grid_listing.vendor_module_grid_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">entity_id</item>
                </item>
            </argument>
        </selectionsColumn>
        <column name="entity_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 name="sortOrder" xsi:type="number">20</item>
                </item>
            </argument>
        </column>

        <column name="status">
            <argument name="data" xsi:type="array">
               <item name="options" xsi:type="array">
                    <item name="0" xsi:type="array">
                        <item name="label" xsi:type="string">Enabled</item>
                        <item name="value" xsi:type="string">1</item>
                    </item>
                    <item name="1" xsi:type="array">
                        <item name="label" xsi:type="string">Disabled</item>
                        <item name="value" xsi:type="string">0</item>
                    </item>
                </item>
               <item name="config" xsi:type="array">
                   <item name="editor" xsi:type="string">select</item>
                   <item name="filter" xsi:type="string">select</item>
                   <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
                   <item name="dataType" xsi:type="string">select</item>
                   <item name="label" xsi:type="string" translate="true">Status</item>
                   <item name="sortOrder" xsi:type="number">70</item>
               </item>
            </argument>
        </column>

        <column name="product_name" component="Magento_Ui/js/grid/columns/select">
            <settings>
                <filter>select</filter>
                <options class="Vendor\Module\Ui\Component\Listing\Column\ProductName"/>
                <dataType>select</dataType>
                <label translate="true">Product</label>
            </settings>
        </column>
        <actionsColumn name="actions" class="Vendor\Module\Ui\Component\Listing\Column\RamActions">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="indexField" xsi:type="string">entity_id</item>
                    <item name="sortOrder" xsi:type="number">100</item>
                </item>
            </argument>
        </actionsColumn>
    </columns>
</listing>

vendor\module\Ui\Component\Listing\Column\GetProductName.php

public function prepareDataSource(array $dataSource)
{
    if (isset($dataSource['data']['items'])) {
        foreach ($dataSource['data']['items'] as $key => $value) {
            $name = '';
            $ProData = $this->ProductCollFactory->create()->addFieldToSelect('product_id')->addFieldToFilter('product_id', ['eq' => $value['entity_id']]);
            foreach ($ProData as $keyPro => $product) {
                $product = $this->_productFactory->create()->load($product->getProductId());
                $name .= $product->getName() . ", ";
            }
            $dataSource['data']['items'][$key]['product_name'] = rtrim($name, ', ');
        }
    }
    return $dataSource;
}
  • have you checked adding <item name="filter" xsi:type="string">text</item> ? – Rutvee Sojitra May 14 at 6:20
  • @RutveeSojitra Yes, I have checked. When I apply filter it shows me an error like "Something went wrong with processing the default view and we have restored the filter to its original state." – Emipro Technologies Pvt. Ltd. May 14 at 6:24
  • Have you join your collection with catalog_product_entity? Because search will be done only on our collection table... means our collection only made for our custom table ... search will work only on custom table – Rutvee Sojitra May 14 at 6:28
  • @RutveeSojitra I have stored product id's in my custom table and also I have checked by joining custom product table with main collection table but it doesn't work. – Emipro Technologies Pvt. Ltd. May 14 at 7:08
  • Is there any way to apply a filter on that column which is added by data source? – Emipro Technologies Pvt. Ltd. May 14 at 7:10
1

In case you are using custom filter you can create custom filter strategy in your DataProvider:

Declare it in the di.xml:

<type name="Vendor\Module\Ui\DataProvider\YourCustomDataProvider">
    <arguments>
        <argument name="addFilterStrategies" xsi:type="array">
            <item name="methods" xsi:type="object">Vendor\Module\Ui\DataProvider\YourCustomDataProvider\YourCustomFilterStrategy</item>
        </argument>
    </arguments>
</type>

Create that filter strategy class:

<?php

namespace Vendor\Module\Ui\DataProvider\YourCustomDataProvider;


use Magento\Framework\Data\Collection;
use Vendor\Model\Model\ResourceModel\YourCustom\Collection as RealCollection;
use Magento\Ui\DataProvider\AddFilterToCollectionInterface;

/**
 * Class YourCustomFilterStrategy
 */
class YourCustomFilterStrategy implements AddFilterToCollectionInterface
{
    /**
     * @param Collection|RealCollection $collection
     * @param string $field
     * @param null $condition
     */
    public function addFilter(Collection $collection, $field, $condition = null)
    {
        if (isset($condition['eq'])) {
            //$collection->addShippingMethodFilter($condition['eq']);
            // Your custom filter for that field here in any collection or in collection 
            // which used as main for the data provider (the `RealCollection` in my example)
        }
    }
}

Note: in my example custom filter in the collection looks like this:

/**
 * @param string $method
 * @return $this
 */
public function addShippingMethodFilter($method)
{
    $conditions = [
        $this->_translateCondition(
            DeliveryOptionInterface::KEY_METHODS,
            [
                ['like' => $method],
                ['like' => '%,' . $method],
                ['like' => $method . ',%'],
                ['like' => '%,' . $method . ',%'],
                ['null' => true]
            ]
        ),
        $this->_translateCondition(
            DeliveryOptionInterface::KEY_SHIPPING_METHODS_CHOICE_LIMITER,
            [
                ['eq' => DeliveryOptionInterface::SHIPPING_METHODS_CHOICE_LIMIT_ALL_METHODS]
            ]
        )
    ];

    $resultCondition = '(' . implode(') ' . Select::SQL_OR . ' (', $conditions) . ')';
    $this->_select->where($resultCondition, null, Select::TYPE_CONDITION);

    return $this;
}

It filters a data in the collection by comma-separated shipping methods. Just write custom filter according your needs. I think it should take products collection by ID's with name attribute, then filter it by name as a string. In result you can take all suitable product ID's which could be used in your collection as a filter, like: $collection->addFieldToFilter('product_id', ['in' => $productIds]) or like in my example with a wildcard (%) symbol.

Your DataProvider should be modified as well:

First add the filter strategies attribute in the constructor:

/**
 * Construct
 *
 * @param string $name
 * @param string $primaryFieldName
 * @param string $requestFieldName
 * @param OrderAddressCollectionFactory $collectionFactory
 * @param \Magento\Framework\App\RequestInterface $request
 * @param \Magento\Framework\Api\FilterBuilder $filterBuilder
 * @param \Magento\Ui\DataProvider\AddFilterToCollectionInterface[] $addFilterStrategies
 * @param array $meta
 * @param array $data
 */
public function __construct(
    $name,
    $primaryFieldName,
    $requestFieldName,
    OrderAddressCollectionFactory $collectionFactory,
    \Magento\Framework\App\RequestInterface $request,
    \Magento\Framework\Api\FilterBuilder $filterBuilder,
    array $addFilterStrategies = [],
    array $meta = [],
    array $data = []
) {
    parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
    $this->collection             = $collectionFactory->create();
    $this->request                = $request;
    $this->filterBuilder          = $filterBuilder;
    $this->addFilterStrategies    = $addFilterStrategies;
}

Note: Do not copy it as-is, because this is just an example, use own construct method with $addFilterStrategies argument added!

and update the addFilter method this way:

/**
 * {@inheritdoc}
 */
public function addFilter(\Magento\Framework\Api\Filter $filter)
{
    if (isset($this->addFilterStrategies[$filter->getField()])) {
        $this->addFilterStrategies[$filter->getField()]
            ->addFilter(
                $this->getCollection(),
                $filter->getField(),
                [$filter->getConditionType() => $filter->getValue()]
            );
    } else {
        parent::addFilter($filter);
    }
}

You can add any filter

PS: do not forget to update all namespaces, classnames, arguments, etc. according your module. PPS: This way you can add as many custom filters to your collection as you want, each in custom class.

0

You want a text input?

Why don't you use a select instead?

    <column name="product_name" component="Magento_Ui/js/grid/columns/select">
        <settings>
            <filter>select</filter>
            <options class="Vendor\Module\Ui\Component\Listing\Column\ProductName"/>
            <dataType>select</dataType>
            <label translate="true">Product</label>
        </settings>
    </column>

And the

app/code/Vendor/Module/Ui/Component/Listing/Column/ProductName.php

<?php
namespace Vendor\Module\Ui\Component\Listing\Column;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\Search\SearchCriteriaBuilder;
use Magento\Framework\Api\Search\SearchCriteriaBuilderFactory;
use Magento\Framework\Data\OptionSourceInterface;

/**
 * Class Options
 */
class ProductName implements OptionSourceInterface
{
    /**
     * @var array
     */
    protected $options = [];

    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;

    /**
     * @var SearchCriteriaBuilderFactory
     */
    protected $searchCriteriaBuilderFactory;
    /**
     * @var FilterBuilder
     */
    protected $filterBuilder;

    /**
     * ProductName constructor.
     *
     * @param ProductRepositoryInterface   $productRepository
     * @param SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory
     * @param FilterBuilder                $filterBuilder
     */
    public function __construct(
        ProductRepositoryInterface $productRepository,
        SearchCriteriaBuilderFactory $searchCriteriaBuilderFactory,
        FilterBuilder $filterBuilder
    ) {
        $this->productRepository = $productRepository;
        $this->filterBuilder = $filterBuilder;
        $this->searchCriteriaBuilderFactory = $searchCriteriaBuilderFactory;
    }

    /**
     * @return array|null
     */
    public function toOptionArray()
    {
        if (empty($this->options)) {
            /** @var SearchCriteriaBuilder $searchCriteria */
            $searchCriteria = $this->searchCriteriaBuilderFactory->create();
            $productIds = [];

            //I suppose you have your table which has product_id in it.
            //Get your collection
            //Get all the product ids

            if (!count($productIds)) {
                return [];
            }

            $productIdFilter = $this->filterBuilder
                ->setField('entity_id')
                ->setValue($productIds)
                ->setConditionType('in')
                ->create();
            $criteria = $searchCriteria->addFilter($productIdFilter)->create();
            $productList = $this->productRepository->getList($criteria);

            if (!$productList->getTotalCount()) {
                return [];
            }

            foreach ($productList->getItems() as $productData) {
                $this->options[] = [
                    'value' => $productData->getId(),
                    'label' => $productData->getName()
                ];
            }
        }
        return $this->options;
    }
}

  • I have checked your code. It gives me following error. Fatal error: Uncaught ArgumentCountError: Too few arguments to function Magento\Framework\Api\SearchCriteriaBuilder::addFilter(), 1 passed in – Emipro Technologies Pvt. Ltd. May 14 at 9:35
  • @EmiproTechnologiesPvt.Ltd. The namespace is wrong, I have updated the code. The namespace of SearchCriteriaBuilderFactory is "Magento\Framework\Api\Search\SearchCriteriaBuilderFactory" – Luci May 14 at 11:11
  • Yes, Data displayed but filter not working. I have created a grid using eav structure In which product id's stored in a flat table. Is there need to anything special for join eav collection data with flat table data? – Emipro Technologies Pvt. Ltd. May 14 at 11:31

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.