15

I want to create a link to a custom grid in my admin with pre-defined filters. The grid is made with a UI Listing Component (XML) and it has a column called form_id that is setup like this:

<column name="form_id">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="filter" xsi:type="string">textRange</item>
            <item name="label" xsi:type="string" translate="true">Form id</item>
        </item>
    </argument>
</column>

The grid works just fine. I can apply the filter and everything works well. The grid gets nicely updated with a XHR request.

However... I want to be able to have a filters' value pre-defined at some point. For example, I want to be able to open the grid when it's filtered on ID=3.

So I already tried loading the page with the same URL parameters as the XHR-request, as well as simply adding the only required parameters:

?namespace=form_response_listing&search=&filters[placeholder]=true&filters[form_id][from]=3&filters[form_id][to]=3&paging[pageSize]=20&paging[current]=1

As well as:

?filters[form_id][from]=3&filters[form_id][to]=3

Both with no success. So how Can I pre-fill filters by using the URL?

Edit:

I'm not sure if this is a duplicate of the other question (as mentioned in the comments below). In my case, I'm using a virtual type as collection for my grid:

<virtualType name="Vendor\Module\Model\ResourceModel\Response\Grid\Collection"
             type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
    <arguments>
        <argument name="mainTable" xsi:type="string">vendormodule_form_response</argument>
        <argument name="resourceModel" xsi:type="string">Vendor\Module\Model\ResourceModel\Response</argument>
    </arguments>
</virtualType>

So it's not that I have a physical Block class for my grid widget, it's purely created with a UI Component listing XML.

Nevertheless, I'll check anyway if the question referred to will help my use case.

5
  • Possible duplicate of To add default filter to grid in Magento2? Jan 18, 2017 at 13:51
  • 2
    @RaphaelatDigitalPianism I don't think this is a duplicate. The question you linked talks about grids build in an old fashion way. Something between grid blocks and ui-components. It was basically something where you still had grid blocks but they were configured in an xml file instead of prepareColumns method.
    – Marius
    Jan 18, 2017 at 14:02
  • @Marius vote retracted ;) Jan 18, 2017 at 14:03
  • 1
    I edited my question, since I also don't think this is a duplicate (I've done my research ;-)) Jan 18, 2017 at 14:05
  • @Giel Berkers I am getting same issue Feb 21, 2019 at 4:52

1 Answer 1

12

Here is what I found out so far.
This is not complete but it can take you on the right path.
I conducted my tests by modifying the cms page listing ui component.
I added this

<item name="filter_url_params" xsi:type="array">
    <item name="page_id" xsi:type="string">*</item>
</item>

in cms_page_listing.xml inside the dataSource node inside the data/config argument. So now it looks like this

<dataSource name="cms_page_listing_data_source">
    <argument name="dataProvider" xsi:type="configurableObject">
        <argument name="class" xsi:type="string">Magento\Cms\Ui\Component\DataProvider</argument>
        <argument name="name" xsi:type="string">cms_page_listing_data_source</argument>
        <argument name="primaryFieldName" xsi:type="string">page_id</argument>
        <argument name="requestFieldName" xsi:type="string">id</argument>
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
                <item name="update_url" xsi:type="url" path="mui/index/render"/>
                <item name="storageConfig" xsi:type="array">
                    <item name="indexField" xsi:type="string">page_id</item>
                </item>
                <item name="filter_url_params" xsi:type="array"><!-- my addition -->
                    <item name="page_id" xsi:type="string">*</item>
                </item>
            </item>
        </argument>
    </argument>
</dataSource>

This allows me to call the url ROOT/admin/cms/page/index/key/<form_key_here>/?page_id=2.
And I see only the page with id 2.
But it does not work for range filters and the filter value is not filled in. It still shows as blank.

Now here is why this is possible.

The dataProvider class for cms pages is Magento\Cms\Ui\Component\DataProvider.
This one extends Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider.
This last one contains a protected method called prepareUpdateUrl

protected function prepareUpdateUrl()
{
    if (!isset($this->data['config']['filter_url_params'])) {
        return;
    }
    foreach ($this->data['config']['filter_url_params'] as $paramName => $paramValue) {
        if ('*' == $paramValue) {
            $paramValue = $this->request->getParam($paramName);
        }
        if ($paramValue) {
            $this->data['config']['update_url'] = sprintf(
                '%s%s/%s',
                $this->data['config']['update_url'],
                $paramName,
                $paramValue
            );
            $this->addFilter(
                $this->filterBuilder->setField($paramName)->setValue($paramValue)->setConditionType('eq')->create()
            );
        }
    }
}

What this does is to check in the ui component config if there is an element called filter_url_params. If there is, it takes all the values inside it and checks the request for values matching what's defined in filter_url_params.
But by default it works only with eq.

What you can try is to have a custom dataSource for your component where you rewrite the method prepareUpdateUrl and make it take into account all the request variables you need and maybe add paging to it and range filtering.

Side note: This is a very interesting question. I'm sure a lot of people will need this in the future.

13
  • Thank you @Marius for your answer. This works for my situation, because the link always needs to filter by one ID, not by a range (the range is more or less a feature, but not required by my URL). Your answer as well as your explanation helped me a lot! Jan 18, 2017 at 15:09
  • 1
    @Marius can i use the url like this ROOT/admin/cms/page/index/page_id/2/key/<form_key_here>, because i'm using $this->urlBuilder->getUrl(static::URL_PATH,[ 'page_id' => $item['id']]) in UiCompnent/Listing/Column
    – simple guy
    Mar 13, 2017 at 4:47
  • how do I use more than one param to filter, i.e. ROOT/admin/cms/page/index/param_1/val1/param_2/val2/param_3/val3/key/<form_key_here> giving three params under <item name="filter_url_params" xsi:type="array"> works for individual filters but not collectively.
    – Shathish
    Aug 30, 2017 at 18:32
  • @Marius ! U R A LIFE SAVER !
    – Zorox
    Aug 31, 2017 at 16:23
  • @Marius : Do you have idea, how to use the functionality for multiple url param like ROOT/admin/cms/page/index/param_1/val1/param_2/val2/param_3/‌​val3/key/<form_key_h‌​ere> as already specified by Shathish
    – Ashish Raj
    Sep 27, 2017 at 16:29

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.