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;
}
有帮助吗?

解决方案

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.

其他提示

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

许可以下: CC-BY-SA归因
scroll top