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

asked Jun 23, 2022 at 17:40

2 Answers 2

3

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',
 ],
 // ...
 ];
 }
}
answered Jun 23, 2022 at 23:21
6
  • thank you for your time and help Victor. Let me try and let you know. thanks once again. Commented Jun 24, 2022 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. Commented Jun 24, 2022 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 Commented Jun 24, 2022 at 21:55
  • I can understand Victor. Thanks once again. Just posted the code with working examples. Commented Jun 24, 2022 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. Commented Jun 24, 2022 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);
 }
 });
 }
);
dotancohen
1,1306 silver badges21 bronze badges
answered Jun 24, 2022 at 22:28
1
  • Thanks dottancohen for updated the block Commented Jun 27, 2022 at 5:20

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.