1

I am struck in finding the solution for the below requirements

Assume drop down#1 and drop down#2 selection box in the Magento2 admin UI grid filters. If we select option in one drop down#1 then we have to filter option in drop down#2 based on drop down#1 selection value.

If anyone aware of the solution / any alternate to achieve this requirement, please help to share your feedback / suggestion.

enter image description here

Thanks is advance

2 Answers 2

1

The answer just a concept and i don't have enough time to provide full example, but hope this will help to understand a concept.

1. Custom Column Ui Component

You need to create a custom column element for your second filter and extend for example Magento_Ui/js/grid/columns/select. You still can use native template.

define([
    'Magento_Ui/js/grid/columns/select',
    'uiRegistry',
    'underscore'
], function (Select, registry, _) {
    'use strict';

    return Select.extend({
        defaults: {
            sourceFilter: '', // the name of primary filter
            sourceFilterUi: null,
            allOptions: [], // all available options
        },
        initConfig: function () {
            this._super();
            // maybe in some cases need to use defer for wait for element
            this.sourceFilterUi = registry.get(this.parent + '.' + this.sourceFilter);
            // store all options and reset applicable
            this.allOptions = this.options;
            this.options = [];
            // track source changes
            if (this.sourceFilterUi) {
                this.sourceFilterUi.value.subscribe(this.sourceChanged.bind(this));
            }
            // here you can add logic check source value and rebuild options (loaded from bookmark, etc)
        },
        sourceChanged: function(value) {
            // value might be undefined, string or array depends on parent source
            // store current value
            let old_value = this.values(), value;
            // generate applicable options
            let new options = [];
            _.each(this.allOptions, function(option) {
                if (option.parent == value) {
                    options.push(option);
                }
                if (old_value == option.value) {
                    value = option.value;
                }
            });


            // update options
            this.options(options);
            
            // restore value after update options
            if (value) {
                this.value(value);
            }
        }
    });
});

2. Filter in listing

You need to define custom filter for listing and disable original filter

<?xml version="1.0"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <listingToolbar name="listing_top">
        <filters name="listing_filters">
            <filterSelect name="second_filter" provider="${ $.parentName }" 
                          component="Acme_StackExchange/js/grid/filters/elements/select-deps">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="sourceFilter" xsi:type="string" translate="true">first_filter</item>
                    </item>
                </argument>
                <settings>
                    <options class="Acme\StackExchange\Ui\Component\Listing\Columns\Second\Options"/>
                    <!-- ... -->
                </settings>
        </filters>
    </listingToolbar>
</listing>

3. Create custom options with relations

// ...
class Options implements OptionSourceInterface
{
    // ...
    public function toOptionArray(): array
    {
        return [
            [
                'label'  => __('Label'),
                'value'  => 'value',
                'parent' => 'parent',
            ],
            // ...
        ];
    }
}
6
  • thank you for your time and help Victor. Let me try and let you know. thanks once again.
    – raheem.unr
    Jun 24 at 5:54
  • Appreciate your help Victor. Your solution got worked. I just fixed some issue in the code and posted below. I hope it will help others too.
    – raheem.unr
    Jun 24 at 21:43
  • I didn't have enough time to test and just wrote the concept here without testing ) and i'm happy that it works. Feel free to update question or my answer with working example. Please keep comments in comments Jun 24 at 21:55
  • I can understand Victor. Thanks once again. Just posted the code with working examples.
    – raheem.unr
    Jun 24 at 22:31
  • Thank you, please update your answer with code block. Based on your answer, I found one critical typo mistake in my answer, just fixed typo. Hope this can also help anybody else. Jun 24 at 22:37
1

Credit to Victor, just refactored the code with working examples

define(
    [
        'Magento_Ui/js/form/element/select',
        'uiRegistry',
        'underscore'
    ],
    function (Select, registry, _) {
        'use strict';
    
        return Select.extend({
            defaults: {
                parent: '${ $.parentName }',
                sourceFilter: '',
                sourceFilterUi: null,
                allOptions: []
            },
            initConfig: function () {
                this._super();
                this.sourceFilterUi = registry.get(this.parent+'.'+this.sourceFilter);
                this.allOptions = this.options;
                if (!this.sourceFilterUi || (this.sourceFilterUi == undefined)) {
                    return;
                }
                this.sourceFilterUi.value.subscribe(this.setFilteredOptions.bind(this));
            },
            setFilteredOptions: function (parent) {
                if (parent == undefined) {
                    return;
                }
                var filteredOptions = [];
                _.each(this.allOptions, function (option) {
                    if (option.parent == parent) {
                        filteredOptions.push(option);
                    }
                });
                this.options(filteredOptions);
            }
        });
    }
);
1
  • Thanks dottancohen for updated the block
    – raheem.unr
    Jun 27 at 5:20

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.