How to hide fields with toggle checkbox in ui_component Magento 2

The question:

I have a toggle checkbox at product edit form:

enter image description here

Created as:

<field name="open_amount" formElement="checkbox">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="source" xsi:type="string">homeslider</item>
                        <item name="default" xsi:type="number">1</item>
                    </item>
                </argument>
                <settings>
                    <dataType>boolean</dataType>
                    <label translate="true">Open Amount</label>
                    <dataScope>status</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>
            <field name="min_val">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="label" xsi:type="string">Open Amount Min Value</item>
                        <item name="visible" xsi:type="boolean">true</item>
                        <item name="dataType" xsi:type="string">text</item>
                        <item name="formElement" xsi:type="string">input</item>
                        <item name="source" xsi:type="string">faq</item>
                    </item>
                </argument>
            </field>
            <field name="max_val">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="label" xsi:type="string">Open Amount Max Value</item>
                        <item name="visible" xsi:type="boolean">true</item>
                        <item name="dataType" xsi:type="string">text</item>
                        <item name="formElement" xsi:type="string">input</item>
                        <item name="source" xsi:type="string">faq</item>
                    </item>
                </argument>
            </field>

Can somebody show me how to add js component to show/hide both fields upon toggle on/off. Thanks

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Replace your form code with below

<field name="open_amount" formElement="checkbox">
          <argument name="data" xsi:type="array">
              <item name="config" xsi:type="array">
                  <item name="component" xsi:type="string">[Vendor]_[Module]/js/mycheckbox</item>
                  <item name="source" xsi:type="string">homeslider</item>
                  <item name="default" xsi:type="number">1</item>
              </item>
          </argument>
          <settings>
              <dataType>boolean</dataType>
              <label translate="true">Open Amount</label>
              <dataScope>status</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>
        <field name="min_val">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string">Open Amount Min Value</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="source" xsi:type="string">faq</item>
                </item>
            </argument>
        </field>
        <field name="max_val">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string">Open Amount Max Value</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="source" xsi:type="string">faq</item>
                </item>
            </argument>
        </field>

Make mycheckbox.js file in vendor/module/view/adminhtml/web/js

define([

   'underscore',

   'uiRegistry',

   'Magento_Ui/js/form/element/single-checkbox',

   'Magento_Ui/js/modal/modal',

   'ko'

], function (_, uiRegistry, select, modal, ko) {

   'use strict';

   return select.extend({


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

           this.fieldDepend(this.value());

           return this;

       },

       onUpdate: function (value)
       {
        console.log(value);

           var field_min_val = uiRegistry.get('index = min_val'); // get field

           var field_max_val = uiRegistry.get('index = max_val'); // get fieldset

           if (value == 0) {

               field_min_val.hide();

               field_max_val.hide();
           }

           else {

               field_min_val.show();

               field_max_val.show();

           }
           return this._super();

       },
       fieldDepend: function (value)

       {
           setTimeout( function(){
               var field_min_val = uiRegistry.get('index = min_val');

               var field_max_val = uiRegistry.get('index = max_val');

                if (value == 0) {

                   field_min_val.hide();

                   field_max_val.hide();
                }

               else {

                   field_min_val.show();

                   field_max_val.show();

               }

           });

       }
   });

});

Hope it will be helpful.

Method 2

No meed all that js files! this has worked for me as treat give a try using settings:

<field name="open_amount">
    <argument name="data" xsi:type="array">
        ....<!-- More Configuration-->
    </argument>
    <settings>
        <switcherConfig>
            <rules>
                <rule name="0">
                    <value>0</value>
                    <actions>
                        <action name="0">
                            <target>vendor_module_form_edit.vendor_module_form_edit.your_field_set_name.min_val</target>
                            <callback>show</callback>
                        </action>
                    </actions>
                </rule>
                <rule name="1">
                    <value>1</value>
                    <actions>
                        <action name="0">
                            <target>vendor_module_form_edit.vendor_module_form_edit.your_field_set_name.min_val</target>
                            <callback>hide</callback>
                        </action>
                    </actions>
                </rule>
            </rules>
            <enabled>true</enabled>
        </switcherConfig>
        <validation>
            <rule name="required-entry" xsi:type="boolean">true</rule>
        </validation>
    </settings>
</field>

Method 3

For the toggle field, single-checkbox.js file is responsible for this. so you need to extend the single-checkbox.js file in your custom module.

First, create a require-config.js file in below path.

app/code/Namespace/Modulename/view/adminhtml/requirejs-config.js

var config = {
'paths': {
    'fabric': 'Magedelight_Productlabel/js/fabric'
},    
map: {
    '*': {            
        'Magento_Ui/js/form/element/single-checkbox':'Namespace_Modulename/js/form/element/single-checkbox'
    }
},
'shim': {
    'fabric': {
        exports: 'fabric',
        'deps': ['jquery']
    }
}
};

Now create a single-checkbox.js file in below path. and add below code.

app/code/Namespace/Modulename/view/adminhtml/web/js/form/element/single-checkbox.js

define([
    'Magento_Ui/js/form/element/abstract',
    'underscore',
    'mage/translate'
], function (AbstractField, _, $t) {
    'use strict';

    return AbstractField.extend({
        defaults: {
            template: 'ui/form/components/single/field',
            checked: false,
            initialChecked: false,
            multiple: false,
            prefer: 'checkbox', // 'radio' | 'checkbox' | 'toggle'
            valueMap: {},

            templates: {
                radio: 'ui/form/components/single/radio',
                checkbox: 'ui/form/components/single/checkbox',
                toggle: 'ui/form/components/single/switcher'
            },

            listens: {
                'checked': 'onCheckedChanged',
                'value': 'onExtendedValueChanged'
            }
        },

        /**
         * @inheritdoc
         */
        initConfig: function (config) {
            this._super();

            if (!config.elementTmpl) {
                if (!this.prefer && !this.multiple) {
                    this.elementTmpl = this.templates.radio;
                } else if (this.prefer === 'radio') {
                    this.elementTmpl = this.templates.radio;
                } else if (this.prefer === 'checkbox') {
                    this.elementTmpl = this.templates.checkbox;
                } else if (this.prefer === 'toggle') {
                    this.elementTmpl = this.templates.toggle;
                } else {
                    this.elementTmpl = this.templates.checkbox;
                }
            }

            if (this.prefer === 'toggle' && _.isEmpty(this.toggleLabels)) {
                this.toggleLabels = {
                    'on': $t('Yes'),
                    'off': $t('No')
                };
            }

            if (typeof this.default === 'undefined' || this.default === null) {
                this.default = '';
            }

            if (typeof this.value === 'undefined' || this.value === null) {
                this.value = _.isEmpty(this.valueMap) || this.default !== '' ? this.default : this.valueMap.false;
                this.initialValue = this.value;
            } else {
                this.initialValue = this.value;
            }

            if (this.multiple && !_.isArray(this.value)) {
                this.value = []; // needed for correct observable assignment
            }

            this.initialChecked = this.checked;

            return this;
        },

        /**
         * @inheritdoc
         */
        initObservable: function () {
            return this
                ._super()
                .observe('checked');
        },

        /**
         * Get true/false key from valueMap by value.
         *
         * @param {*} value
         * @returns {Boolean|undefined}
         */
        getReverseValueMap: function getReverseValueMap(value) {
            var bool = false;

            _.some(this.valueMap, function (iValue, iBool) {
                if (iValue === value) {
                    bool = iBool === 'true';

                    return true;
                }
            });

            return bool;
        },

        /**
         * @inheritdoc
         */
        setInitialValue: function () {
            if (_.isEmpty(this.valueMap)) {
                this.on('value', this.onUpdate.bind(this));
            } else {
                this._super();
                this.checked(this.getReverseValueMap(this.value()));
            }

            return this;
        },

        /**
         * Handle dataScope changes for checkbox / radio button.
         *
         * @param {*} newExportedValue
         */
        onExtendedValueChanged: function (newExportedValue) {
            var isMappedUsed = !_.isEmpty(this.valueMap),
                oldChecked = this.checked.peek(),
                oldValue = this.initialValue,
                newChecked;

            if (this.multiple) {
                newChecked = newExportedValue.indexOf(oldValue) !== -1;
            } else if (isMappedUsed) {
                newChecked = this.getReverseValueMap(newExportedValue);
            } else if (typeof newExportedValue === 'boolean') {
                newChecked = newExportedValue;
            } else {
                newChecked = newExportedValue === oldValue;
            }

            if (newChecked !== oldChecked) {
                this.checked(newChecked);
            }
        },

        /**
         * Handle checked state changes for checkbox / radio button.
         *
         * @param {Boolean} newChecked
         */
        onCheckedChanged: function (newChecked) {
            var isMappedUsed = !_.isEmpty(this.valueMap),
                oldValue = this.initialValue,
                newValue;
            console.log('called');            
            if (isMappedUsed) {
                newValue = this.valueMap[newChecked];
            } else {
                newValue = oldValue;
            }

            if (!this.multiple && newChecked) {
                this.value(newValue);
            } else if (!this.multiple && !newChecked) {
                if (typeof newValue === 'boolean') {
                    this.value(newChecked);
                } else if (newValue === this.value.peek()) {
                    this.value('');
                }

                if (isMappedUsed) {
                    this.value(newValue);
                }
            } else if (this.multiple && newChecked && this.value.indexOf(newValue) === -1) {
                this.value.push(newValue);
            } else if (this.multiple && !newChecked && this.value.indexOf(newValue) !== -1) {
                this.value.splice(this.value.indexOf(newValue), 1);
            }
        },

        /**
         * @inheritdoc
         */
        onUpdate: function () {
            if (this.hasUnique) {
                this.setUnique();
            }

            return this._super();
        },

        /**
         * @inheritdoc
         */
        reset: function () {
            if (this.multiple && this.initialChecked) {
                this.value.push(this.initialValue);
            } else if (this.multiple && !this.initialChecked) {
                this.value.splice(this.value.indexOf(this.initialValue), 1);
            } else {
                this.value(this.initialValue);
            }

            this.error(false);

            return this;
        },

        /**
         * @inheritdoc
         */
        clear: function () {
            if (this.multiple) {
                this.value([]);
            } else {
                this.value('');
            }

            this.error(false);

            return this;
        }
    });
});

Run below command :

php bin/magento s:s:d -f
php bin/magento c:f

Then go to your admin form and check in the console you can see called

Now you need to get your toggle field value and hide/show your fields.

That’s all, I hope it helps!


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment