13

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.

  • Possible duplicate of To add default filter to grid in Magento2? – Raphael at Digital Pianism Jan 18 '17 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 '17 at 14:02
  • @Marius vote retracted ;) – Raphael at Digital Pianism Jan 18 '17 at 14:03
  • 1
    I edited my question, since I also don't think this is a duplicate (I've done my research ;-)) – Giel Berkers Jan 18 '17 at 14:05
  • @Giel Berkers I am getting same issue – bhargav shastri Feb 21 at 4:52
9

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.

  • 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! – Giel Berkers Jan 18 '17 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 '17 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 '17 at 18:32
  • @Marius ! U R A LIFE SAVER ! – Zorox Aug 31 '17 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 '17 at 16:29

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.