سؤال

i created admin grid using UI component when i try to search from full test search or keyword search i am not getting correct search data can any one help me on this rest all thing are working filters is working fine , sort is working only common search is not working app\code\Sugarcode\Test\view\adminhtml\ui_component\test_lists_listing.xml

<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Ui/etc/ui_configuration.xsd">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing_data_source</item>
            <item name="deps" xsi:type="string">test_lists_listing.test_lists_listing_data_source</item>
        </item>
        <item name="spinner" xsi:type="string">test_lists_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 New Info</item>
                <item name="class" xsi:type="string">primary</item>
                <item name="url" xsi:type="string">*/*/new</item>
            </item>
        </item>
    </argument>
    <dataSource name="test_lists_listing_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">ListsGridDataProvider</argument>
            <argument name="name" xsi:type="string">test_lists_listing_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">id</argument>
            <argument name="requestFieldName" xsi:type="string">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">
            <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="displayArea" xsi:type="string">dataGridActions</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">test_lists_listing</item>
                    </item>
                </item>
            </argument>
        </bookmark>
        <container 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">test_lists_listing.test_lists_listing.test_lists_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>
        </container>
        <filterSearch name="fulltext">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/search/search</item>
                    <item name="displayArea" xsi:type="string">dataGridFilters</item>
                    <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing_data_source</item>
                    <item name="chipsProvider" xsi:type="string">test_lists_listing.test_lists_listing.listing_top.listing_filters_chips</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">test_lists_listing.test_lists_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="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">test_lists_listing.test_lists_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">test_lists_listing.test_lists_listing.listing_top.listing_filters</item>
                        <item name="imports" xsi:type="array">
                            <item name="visible" xsi:type="string">test_lists_listing.test_lists_listing.listing_top.bookmarks:current.columns.${ $.index }.visible</item>
                        </item>
                    </item>
                </item>
            </argument>
            <filterRange name="id">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="dataScope" xsi:type="string">id</item>
                        <item name="label" xsi:type="string" translate="true">ID</item>
                        <item name="childDefaults" xsi:type="array">
                            <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.listing_top.listing_filters</item>
                        </item>
                    </item>
                </argument>
                <filterInput name="from">
                    <argument name="data" xsi:type="array">
                        <item name="config" xsi:type="array">
                            <item name="dataScope" xsi:type="string">from</item>
                            <item name="label" xsi:type="string" translate="true">from</item>
                            <item name="placeholder" xsi:type="string" translate="true">From</item>
                        </item>
                    </argument>
                </filterInput>
                <filterInput name="to">
                    <argument name="data" xsi:type="array">
                        <item name="config" xsi:type="array">
                            <item name="dataScope" xsi:type="string">to</item>
                            <item name="label" xsi:type="string" translate="true">to</item>
                            <item name="placeholder" xsi:type="string" translate="true">To</item>
                        </item>
                    </argument>
                </filterInput>
            </filterRange>
            <filterInput name="title">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="dataScope" xsi:type="string">title</item>
                        <item name="label" xsi:type="string" translate="true">Title</item>
                    </item>
                </argument>
            </filterInput>
            <filterRange name="created_at"  class="Magento\Ui\Component\Filters\Type\DateRange">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="dataScope" xsi:type="string">created_at</item>
                        <item name="label" xsi:type="string" translate="true">Created</item>
                        <item name="childDefaults" xsi:type="array">
                            <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.listing_top.listing_filters</item>
                        </item>
                    </item>
                </argument>
                <filterDate name="from">
                    <argument name="data" xsi:type="array">
                        <item name="config" xsi:type="array">
                            <item name="dataScope" xsi:type="string">from</item>
                            <item name="label" xsi:type="string" translate="true">From</item>
                            <item name="placeholder" xsi:type="string" translate="true">From</item>
                            <item name="dateFormat" xsi:type="string" translate="true">MM/dd/YYYY</item>
                        </item>
                    </argument>
                </filterDate>
                <filterDate name="to">
                    <argument name="data" xsi:type="array">
                        <item name="config" xsi:type="array">
                            <item name="dataScope" xsi:type="string">to</item>
                            <item name="label" xsi:type="string" translate="true">To</item>
                            <item name="placeholder" xsi:type="string" translate="true">To</item>
                            <item name="dateFormat" xsi:type="string" translate="true">MM/dd/YYYY</item>
                        </item>
                    </argument>
                </filterDate>
            </filterRange>  

            <filterSelect name="status">
                <argument name="optionsProvider" xsi:type="configurableObject">
                    <argument name="class" xsi:type="string">Sugarcode\Test\Model\Status</argument>
                </argument>
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="dataScope" xsi:type="string">status</item>
                        <item name="caption" xsi:type="string" translate="true">Select...</item>
                        <item name="label" xsi:type="string" translate="true">Status</item>
                    </item>
                </argument>
            </filterSelect>

        </filters>
        <massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns.ids</item>
                    <item name="displayArea" xsi:type="string">bottom</item>
                    <item name="actions" xsi:type="array">
                        <item name="delete" 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="string">test/lists/massDelete</item>
                            <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>
                        <item name="disable" xsi:type="array">
                            <item name="type" xsi:type="string">disable</item>
                            <item name="label" xsi:type="string" translate="true">Disable</item>
                            <item name="url" xsi:type="string">test/lists/massDisable</item>
                        </item>
                        <item name="enable" xsi:type="array">
                            <item name="type" xsi:type="string">enable</item>
                            <item name="label" xsi:type="string" translate="true">Enable</item>
                            <item name="url" xsi:type="string">test/lists/massEnable</item>
                        </item>                    </item>
                    <item name="indexField" xsi:type="string">id</item>
                </item>
            </argument>
        </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">test_lists_listing.test_lists_listing.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.paging</item>
                    </item>
                    <item name="selectProvider" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns.ids</item>
                    <item name="displayArea" xsi:type="string">bottom</item>
                    <item name="options" xsi:type="array">
                        <item name="20" xsi:type="array">
                            <item name="value" xsi:type="number">20</item>
                            <item name="label" xsi:type="string" translate="true">20</item>
                        </item>
                        <item name="30" xsi:type="array">
                            <item name="value" xsi:type="number">30</item>
                            <item name="label" xsi:type="string" translate="true">30</item>
                        </item>
                        <item name="50" xsi:type="array">
                            <item name="value" xsi:type="number">50</item>
                            <item name="label" xsi:type="string" translate="true">50</item>
                        </item>
                        <item name="100" xsi:type="array">
                            <item name="value" xsi:type="number">100</item>
                            <item name="label" xsi:type="string" translate="true">100</item>
                        </item>
                        <item name="200" xsi:type="array">
                            <item name="value" xsi:type="number">200</item>
                            <item name="label" xsi:type="string" translate="true">200</item>
                        </item>
                    </item>
                </item>
            </argument>
        </paging>
    </container>
    <columns name="test_lists_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">test_lists_listing.test_lists_listing.listing_top.bookmarks</item>
                    <item name="namespace" xsi:type="string">current</item>
                </item>
                <item name="childDefaults" xsi:type="array">
                    <item name="fieldAction" xsi:type="array">
                        <item name="provider" xsi:type="string">test_lists_listing.test_lists_listing.test_lists_columns.actions</item>
                        <item name="target" xsi:type="string">applyAction</item>
                        <item name="params" xsi:type="array">
                            <item name="0" xsi:type="string">edit</item>
                            <item name="1" xsi:type="string">${ $.$data.rowIndex }</item>
                        </item>
                    </item>
                    <item name="controlVisibility" xsi:type="boolean">true</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">test_lists_listing.test_lists_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>
        <column name="ids" class="Magento\Ui\Component\MassAction\Columns\Column">
            <argument name="data" xsi:type="array">
                <item name="js_config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/multiselect</item>
                </item>
                <item name="config" xsi:type="array">
                    <item name="indexField" xsi:type="string">id</item>
                    <item name="controlVisibility" xsi:type="boolean">false</item>
                </item>
            </argument>
        </column>
        <column name="id">
            <argument name="data" xsi:type="array">
                <item name="js_config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/column</item>
                </item>
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="sorting" xsi:type="string">asc</item>
                    <item name="align" xsi:type="string">left</item>
                    <item name="label" xsi:type="string" translate="true">ID</item>
                    <item name="sortOrder" xsi:type="number">1</item>
                </item>
                    <item name="sortOrder" xsi:type="number">1</item>
            </argument>
        </column>
        <column name="title">
            <argument name="data" xsi:type="array">
                <item name="js_config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/column</item>
                </item>
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="align" xsi:type="string">left</item>
                    <item name="label" xsi:type="string" translate="true">Title</item>
                </item>
            </argument>
        </column>

        <column name="status">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">Sugarcode\Test\Model\Status</item>
                <item name="js_config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
                </item>
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">select</item>
                    <item name="align" xsi:type="string">left</item>
                    <item name="label" xsi:type="string" translate="true">Status</item>
                    <item name="sortOrder" xsi:type="number">3</item>
                </item>
                    <item name="sortOrder" xsi:type="number">3</item>
            </argument>
        </column>

        <column name="creation_at">
            <argument name="data" xsi:type="array">
                <item name="js_config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
                </item>
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">date</item>
                    <item name="align" xsi:type="string">left</item>
                    <item name="label" xsi:type="string" translate="true">Created</item>
                    <item name="sortOrder" xsi:type="number">4</item>
                </item>
                    <item name="sortOrder" xsi:type="number">4</item>
            </argument>
        </column>
        <column name="actions" class="Sugarcode\Test\Ui\Component\Listing\Column\TestActions">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="draggable" xsi:type="boolean">false</item>
                    <item name="dataType" xsi:type="string">actions</item>
                    <item name="indexField" xsi:type="string">id</item>
                    <item name="align" xsi:type="string">left</item>
                    <item name="label" xsi:type="string" translate="true">Action</item>
                    <item name="data_type" xsi:type="string">actions</item>
                    <item name="filterable" xsi:type="boolean">false</item>
                    <item name="sortable" xsi:type="boolean">false</item>
                    <item name="sortOrder" xsi:type="number">5</item>
                </item>
                    <item name="sortOrder" xsi:type="number">5</item>
            </argument>
        </column>
    </columns>
</listing>

app\code\Sugarcode\Test\view\adminhtml\layout\test_lists_index.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
    <update handle="styles"/>
    <body>
        <referenceContainer name="content">
            <uiComponent name="test_lists_listing"/>
        </referenceContainer>
    </body>
</page>

i created data provider that is app\code\Sugarcode\Test\Model\Test\DataProvider.php

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Sugarcode\Test\Model\Test;

use Sugarcode\Test\Model\Resource\Test\CollectionFactory;
use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
use Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool;

/**
 * Class DataProvider
 */
class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
    /**
     * @var \Magento\Cms\Model\Resource\Block\Collection
     */
    protected $collection;

    /**
     * @var FilterPool
     */
    protected $filterPool;

    /**
     * @param string $name
     * @param string $primaryFieldName
     * @param string $requestFieldName
     * @param CollectionFactory $collectionFactory
     * @param FilterPool $filterPool
     * @param array $meta
     * @param array $data
     */
    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        CollectionFactory $collectionFactory,
        FilterPool $filterPool,
        array $meta = [],
        array $data = []
    ) {
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
        $this->collection = $collectionFactory->create();
        $this->filterPool = $filterPool;
    }

    /**
     * @return \Magento\Cms\Model\Resource\Block\Collection
     */
    protected function getCollection()
    {
        return $this->collection;
    }

    /**
     * @inheritdoc
     */
    public function addFilter($condition, $field = null, $type = 'regular')
    {
        $this->filterPool->registerNewFilter($condition, $field, $type);
    }

    /**
     * Get data
     *
     * @return array
     */
    public function getData()
    {
        $this->filterPool->applyFilters($this->collection);
        return $this->collection->toArray();
    }

    /**
     * Retrieve count of loaded items
     *
     * @return int
     */
    public function count()
    {
        $this->filterPool->applyFilters($this->collection);
        return $this->collection->count();
    }
    public function addFieldToSearchFilter($field, $condition = null)
    {
        $field = $this->_getMappedField($field);
        $this->_select->orWhere($this->_getConditionSql($field, $condition));
        return $this;
    }
}

my model collection is app\code\Sugarcode\Test\Model\Resource\Test\Collection.php

<?php
namespace Sugarcode\Test\Model\Resource\Test;

class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
{

    protected function _construct()
    {
        $this->_init('Sugarcode\Test\Model\Test', 'Sugarcode\Test\Model\Resource\Test');
    }

    /**
     * @return \Magento\Cms\Model\Resource\Block\Collection
     */
    protected function _afterLoad()
    {
        $this->walk('afterLoad');
        parent::_afterLoad();
    }

    /**
     * @param string|array $field
     * @param string|int|array|null $condition
     * @return \Magento\Cms\Model\Resource\Block\Collection
     */
    public function addFieldToFilter($field, $condition = null)
    {

        return parent::addFieldToFilter($field, $condition);
    }



    /**
     * Returns pairs block_id - title
     *
     * @return array
     */
    public function toOptionArray()
    {
        return $this->_toOptionArray('id', 'title');
    }

    /**


    /**
     * Get SQL for get record count.
     * Extra GROUP BY strip added.
     *
     * @return \Magento\Framework\DB\Select
     */
    public function getSelectCountSql()
    {
        $countSelect = parent::getSelectCountSql();

        $countSelect->reset(\Zend_Db_Select::GROUP);

        return $countSelect;
    }

    public function addFieldToSearchFilter($field, $condition = null)
    {
        $field = $this->_getMappedField($field);
        $this->_select->orWhere($this->_getConditionSql($field, $condition));
        return $this;
    }

}

every thing is working fine except full search or common search do any one has any idea ?

هل كانت مفيدة؟

المحلول 2

TO make full text search or keyword search of admin grid you need to make or add index of the table

$connection->addIndex(
                    'testtable', //table name
                    'title',    // index name
                    [
                        'title'   // filed or column name 
                    ],
                    \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT //type of index
                );

Thank you @anton

نصائح أخرى

To enable fulltext search for custom grid you need to create fulltext index in your grid table. fulltext filter scans indexes list and builds query with fulltext condition only if index exists.

See example, how fulltext filter works, for Merchant Beta, Mainline

To make fulltext search work in magento 2 admin listing/grid you need to:

  1. Add index to the table you use for storing your listing/grid data
  2. Add addFilter method to you grid/listing DataProvider that calls it's collections addFieldToFilter or addAttributeToFilter method
  3. In your component xml file you can use just <filterSearch name="fulltext"/> node without description in listingToolbar

in your di.xml

add addFilterStrategies argument

<type name="Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider">
    <arguments>
        <argument name="addFilterStrategies" xsi:type="array">
            <item name="fulltext" xsi:type="object">Magento\CatalogSearch\Ui\DataProvider\Product\AddFulltextFilterToCollection</item>
        </argument>
    </arguments>
</type>

you can see in module catalog-search as your example

in ui_component/listing.xml you need add node filterSearch between listingToolbar

<filterSearch name="fulltext"/>
For Magento 2.3.4
- Added <filterSearch name="fulltext"/> node in listing.xml file.
- I added fulltext index in db_schema.xml file.

<index referenceId="UNIT6_COMPUTER_GAME_NAME_TYPE" indexType="fulltext">
    <column name="name"/>
    <column name="type"/>
</index>

- Executed below commands

sudo php bin/magento setup:db-declaration:generate-whitelist --module-name=Unit6_ComputerGames

sudo php bin/magento setup:upgrade

Full text search is working fine in admin grid.

TO make full text search or keyword search of admin grid for multiple column you need to use code like below

$connection->addIndex(
                    'tableName',
                    $installer->getIdxName(
                        'tableName',
                        ['field1','field2','field3'],
                        \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT
                    ),
                     ['field1','field2','field3'],
 \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_FULLTEXT
                );
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى magento.stackexchange
scroll top