1

I have a dynamic field ui-component inside an admin form that contains a few columns. And I also have a toggle field outside the dynamic rows.
I want to show/hide a column inside the dynamic fields based on the state of the toggle.
I was able to make the column hide but the header still remains.

Here is my code

My toggle definition

    <field name="aggregate" formElement="checkbox">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="source" xsi:type="string">entity</item>
                <item name="default" xsi:type="number">0</item>
            </item>
        </argument>
        <settings>
            <dataType>text</dataType>
            <label translate="true">Aggregate</label>
            <dataScope>aggregate</dataScope>
        </settings>
        <formElements>
            <checkbox>
                <settings>
                    <valueMap>
                        <map name="false" xsi:type="number">0</map>
                        <map name="true" xsi:type="number">1</map>
                    </valueMap>
                    <prefer>toggle</prefer>
                </settings>
            </checkbox>
        </formElements>
    </field>

here is my dynamic rows component. the component contains more fields, but I added only the one in question.

    <dynamicRows name="fields_serialized">
        <settings>
            <addButtonLabel translate="true">Add Row</addButtonLabel>
            <additionalClasses>
                <class name="admin__field-wide">true</class>
            </additionalClasses>
            <componentType>dynamicRows</componentType>
            <dndConfig>
                <param name="enabled" xsi:type="boolean">true</param>
            </dndConfig>
        </settings>
        <container name="record">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true" />
                    <item name="isTemplate" xsi:type="boolean">true</item>
                    <item name="is_collection" xsi:type="boolean">true</item>
                    <item name="showFallbackReset" xsi:type="boolean">true</item>
                </item>
            </argument>
            <field name="aggregate" formElement="select" component="Magento_Ui/js/form/element/ui-select">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="source" xsi:type="string">fields_serialized</item>
                        <item name="filterOptions" xsi:type="boolean">true</item>
                        <item name="chipsEnabled" xsi:type="boolean">true</item>
                        <item name="disableLabel" xsi:type="boolean">true</item>
                        <item name="multiple" xsi:type="boolean">false</item>
                    </item>
                </argument>
                <settings>
                    <elementTmpl>ui/grid/filters/elements/ui-select</elementTmpl>
                    <dataType>text</dataType>
                    <label translate="true">Aggregation</label>
                    <dataScope>aggregate</dataScope>
                    <validation>
                        <rule name="required-entry" xsi:type="boolean">true</rule>
                    </validation>
                    <componentType>field</componentType>
                    <imports>
                        <link name="visible">[path.to.toogle.component.here].aggregate:checked</link> 
                    </imports>
                </settings>
                <formElements>
                    <select>
                        <settings>
                            <options class="SourceModelClassHere"/>
                        </settings>
                    </select>
                </formElements>
            </field>
        </container>
    </dynamicRows>

the imports part in the record works nicely to show/hide the column inside the rows but it leaves the header.

<imports>
    <link name="visible">[path.to.toogle.component.here].aggregate:checked</link> 
</imports>

When changing the state of the main toggle I get something like this:

toggle off

Initially it looks like this

enter image description here

1 Answer 1

1

I didn't find a way to do it without creating new component. So I created a new component:

define(
    ['Magento_Ui/js/dynamic-rows/dynamic-rows', 'ko'],
    function (DynamicRows, ko) {
        return DynamicRows.extend({
            initObservable: function () {
                var self = this;
                this.aggregate = ko.observable(false);
                this._super();
                this.aggregate.subscribe(function (value) {
                    self.setAggregate(value);
                });
                return this;
            },
            setAggregate: function (value) {
                var labels = this.labels();
                labels.map(function (label) {
                    if (label.name === 'aggregate') {
                        label.visible(value);
                    }
                });
            },
            initHeader: function () {
                this._super();
                this.setAggregate(this.aggregate());
            }
        });
    }
);

and declared my dynamic rows as an instance of the component above and added an import link to it

<dynamicRows name="fields_serialized" component="[Namespace]_[Module]/js/dynamic-rows">
    ....
    <settings>
        <imports>
            <link name="aggregate">path.to.toogle.field.aggregate:checked</link>
        </imports>
    </settings>
</dynamicRows>

I know that the check "if (label.name === 'aggregate') {" is not that clean, and does not make the component very reusable, but it can be improved by adding the columns that should be hidden via the xml config.

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.