0

Is there a way to make some listing select in filter to depend on some other select? I have seen this done on frontend checkout but that's a form not a list.

The idea is to make two columns searchable by select values but second select values are filtered by first option's value.

I tried something like this (similar to checkout implementation) but it does not work.

<column name="customer_id">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">Module\Module\Model\Config\Source\Customers</item>
        <item name="config" xsi:type="array">
            <item name="filter" xsi:type="string">select</item>
            <item name="label" xsi:type="string" translate="true">Customer</item>
            <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
            <item name="dataType" xsi:type="string">select</item>
            <item name="dataScope" xsi:type="string">customer</item>
            <item name="sortOrder" xsi:type="number">75</item>
            <item name="sortable" xsi:type="boolean">false</item>
        </item>
    </argument>
</column>

<column name="address_id">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">Module\Module\Model\Config\Source\Address</item>
        <item name="config" xsi:type="array">
            <item name="filter" xsi:type="string">select</item>
            <item name="label" xsi:type="string" translate="true">Address</item>
            <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/select</item>
            <item name="dataType" xsi:type="string">select</item>
            <item name="dataScope" xsi:type="string">address_id</item>
            <item name="sortOrder" xsi:type="number">75</item>
            <item name="sortable" xsi:type="boolean">false</item>
            <item name="filterBy" xsi:type="array">
                <item name="target" xsi:type="string">${ $.provider }:${ $.parentScope }.customer_id</item>
                <item name="field" xsi:type="string">customer_id</item>
            </item>
        </item>
    </argument>
</column>
  • Did you solved this issue? – Rohan Hapani Nov 8 at 6:09
  • @RohanHapani see my answer below. Maybe there is some error because I edited my code before I copied (I had to rename/delete some stuff). – Artis Z Nov 8 at 9:01
0

Feels like hacky solution but it works:

Ui component listing:

<filters name="listing_filters">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="columnsProvider" xsi:type="string">grid_listing.grid_listing.grids_columns</item>
                <item name="storageConfig" xsi:type="array">
                    <item name="provider" xsi:type="string">grid_listing.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/select-custom</item>
                            <item name="template" xsi:type="string">ui/grid/filters/elements/select-custom</item>
                        </item>
                    </item>
                </item>
                <item name="childDefaults" xsi:type="array">
                    <item name="provider" xsi:type="string">grid_listing.grid_listing.listing_top.listing_filters</item>
                    <item name="imports" xsi:type="array">
                        <item name="visible" xsi:type="string">grid_listing.grid_listing.grid_columns.${ $.index }:visible</item>
                    </item>
                </item>
            </item>
            <item name="observers" xsi:type="array">
                <item name="column" xsi:type="string">column</item>
            </item>
        </argument>
    <filterSelect name="address_id" provider="${ $.parentName }">
        <settings>
            <options class="Vendor\Module\Model\Config\Source\Address"/>
            <label translate="true">Address</label>
            <dataScope>address_id</dataScope>
            <imports>
                <link name="visible">ns = ${ $.ns }, componentType = column, index = ${ $.index }:visible</link>
            </imports>
        </settings>
    </filterSelect>
    <filterSelect name="customer_id" provider="${ $.parentName }">
        <settings>
            <options class="Vendor\Module\Model\Config\Source\Customers"/>
            <label translate="true">Customer</label>
            <dataScope>customer_id</dataScope>
            <imports>
                <link name="visible">ns = ${ $.ns }, componentType = column, index = ${ $.index }:visible</link>
            </imports>
        </settings>
    </filterSelect>
</filters>

js:

define([
    'Magento_Ui/js/form/element/select',
    'jquery',
    'uiRegistry',
    'mage/url'
], function (Select, $, uiRegistry, url) {
    'use strict';

    function parseOptions(nodes, captionValue) {
        var caption,
            value;

        nodes = _.map(nodes, function (node) {
            value = node.value;

            if (value === null || value === captionValue) {
                if (_.isUndefined(caption)) {
                    caption = node.label;
                }
            } else {
                return node;
            }
        });

        return {
            options: _.compact(nodes),
            caption: _.isString(caption) ? caption : false
        };
    }

    function findFirst(data) {
        var value;

        data.some(function (node) {
            value = node.value;

            if (Array.isArray(value)) {
                value = findFirst(value);
            }

            return !_.isUndefined(value);
        });

        return value;
    }

    function indexOptions(data, result) {
        var value;

        result = result || {};

        data.forEach(function (item) {
            value = item.value;

            if (Array.isArray(value)) {
                indexOptions(value, result);
            } else {
                result[value] = item;
            }
        });

        return result;
    }

    return Select.extend({

        initialize: function () {
            self = this;
            this._super();

            if (this.customEntry) {
                registry.get(this.name, this.initInput.bind(this));
            }

            if (this.filterBy) {
                this.initFilter();
            }

            // filter and update address select

            if (this.inputName == 'address_id' && this.source.filters.customer_id !== undefined) {

                this.filterBy = {
                    field: 'customer_id',
                    target: 'customer_id'
                }

                this.customerFilter(this.source.filters.customer_id, 'customer_id');
            }

            return this;
        },

        customerFilter: function (value, field) {
            var source = this.initialOptions,
                result;

            result = _.filter(source, function (item) {
                return item[field] === value || item.value === '';
            });

            this.setOptions(result);
        },

        onUpdate: function () {
            var self = this;

            this.bubble('update', this.hasChanged());

            this.validate();

            // filter and update address select

            if (this.inputName == 'customer_id') {

                var address = uiRegistry.get(this.parentName + '.' + 'address_id'),
                    options = address.indexedOptions,
                    source = address.initialOptions,
                    result;

                result = _.filter(source, function (item) {
                    return item[self.inputName] === self.value();
                });

                address.setOptions(result);
            }
        }
    });
});

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.