5

I have created 3 Product Attributes, I want to make Start Date and End Date attribute to depend on Enable Attribute.

When i make Enable to Yes both the Date Attribute should be displayed how can i do that?

I have created a modifier class but no luck!

enter image description here

3
  • Have you resolved your query? Apr 12, 2019 at 3:43
  • Hi Ashish Viradiya, was your problem resolved? I am facing the same issue. Please help me if you got the answer. May 30, 2019 at 6:43
  • @MeetaliGupta please find my answer below. Jun 3, 2019 at 6:58

5 Answers 5

7

Use below solution:

We have used 3 product attributes:

  1. testenable
  2. startdate
  3. enddate

view/adminhtml/layout/catalog_product_edit.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="main.col">
            <block class="Magento\Framework\View\Element\Template" template="Vendor_Module::form_scripts.phtml"
                   name="test_form_scripts"/>
        </referenceContainer>
    </body>
</page>

view/adminhtml/layout/catalog_product_new.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="main.col">
            <block class="Magento\Framework\View\Element\Template" template="Vendor_Module::form_scripts.phtml" name="test_form_scripts"/>
        </referenceContainer>
    </body>
</page>

view/adminhtml/templates/form_scripts.phtml

<script>
   require([
       'jquery',
       'Vendor_Module/js/form',
       'domReady!'
   ], function ($, form) {
       $(document).ready(function () {
           setTimeout(function () {

                // START: in case if you have created custom group add data-index of that group or else remove the code
               $(document).on('click', 'div[data-index="dates-index-test"]', function() {
                   form.showHideAttr();
               });
               // END

               $(document).on('change', '[name="product[testenable]"]', function() {
                   form.showHideAttr();
               });
               form.showHideAttr();//This is added to trigger based on // the original value after just the page is loaded. since if it is //disabled by default it doesnt gets triggered
           },7000);
       });
   });
</script>

view/adminhtml/web/js/form.js

define(['jquery'], function ($) {
    var testShowHide = {
        showHideAttr: function () {
            var action = $('[name="product[testenable]"]').val();
            if (action!=null) {
                switch (action) {
                    case 'yes':
                        this.showFields('div[data-index="startdate"]');
                        this.showFields('div[data-index="enddate"]');
                        break;
                    case 'no':
                        this.hideFields('div[data-index="startdate"]');
                        this.hideFields('div[data-index="enddate"]');
                        break;
                }
            } else {
                this.hideFields('div[data-index="startdate"]');
                this.hideFields('div[data-index="enddate"]');
            }
        },

        hideFields: function (names) {
            $(names).toggle(false);
        },

        showFields: function (names) {
            $(names).toggle(true);
        }
    };
    return testShowHide;
});
6

The solution from website webkul works with dropdown, textbox but does not works with radio buttons as Ashish Viradiya has shown in the screenshot.

The exact problem is on this line "'!${$.provider}:' . self::DATA_SCOPE_PRODUCT . '.field_main:value'"

.field_main:value does not work with radio buttons

3

For example: You have two attribute of product: field_main and field_sub. Your attribute field_sub is dependent on field_main attribute’s value. Now, you need to add following code in your plugin:

In app/code/Vendor/Module/etc/adminhtml/di.xml

    <?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
        <arguments>
            <argument name="modifiers" xsi:type="array">
                <item name="field_sub" xsi:type="array">
                    <item name="class" xsi:type="string">Vendor\Module\Ui\DataProvider\Product\Form\Modifier\FieldSub</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                </item>
            </argument>
        </arguments>
    </virtualType>
</config>

Now define your attribute’s data provider:

create file at path:

Vendor\Module\Ui\DataProvider\Product\Form\Modifier\FieldSub.php

<?php

namespace Vendor\Module\Ui\DataProvider\Product\Form\Modifier;

use Magento\Framework\Stdlib\ArrayManager;

class FieldSub extends \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier
{
    /**
     * @var ArrayManager
     * @since 101.0.0
     */
    protected $arrayManager;

    public function __construct(
        ArrayManager $arrayManager
    ) {
        $this->arrayManager = $arrayManager;
    }

    public function modifyMeta(array $meta)
    {
        $meta = $this->customizeFieldSub($meta);

        return $meta;
    }

    public function modifyData(array $data)
    {
        return $data;
    }

    protected function customizeFieldSub(array $meta)
    {
        $weightPath = $this->arrayManager->findPath('field_sub', $meta, null, 'children');

        if ($weightPath) {
            $meta = $this->arrayManager->merge(
                $weightPath . static::META_CONFIG_PATH,
                $meta,
                [
                    'dataScope' => 'field_sub',
                    'validation' => [
                        'required-entry' => true,
                        'validate-zero-or-greater' => true
                    ],
                    'additionalClasses' => 'admin__field-small',
                    'imports' => [
                        'disabled' => '!${$.provider}:' . self::DATA_SCOPE_PRODUCT
                            . '.field_main:value'
                    ]
                ]
            );
        }
        return $meta;
    }
}

In di.xml we map the field’s data provider.

In fieldSub.php file, modifyMeta() calls to modify the attribute, in this function we added additional checks to our field, which are:

  • data_scope: is the name of the field (field code)
  • validation: validations which we want to apply on our filed.
  • additionalClasses : if want to add additional class to our field.
  • imports: in this we pass the attributes value, like: disabled, product-id, or any other attribute to add in element.

After this flush the cache, and your field (field_sub) will be dependent on other field’s (field_main) value.

enter image description here

Reference: https://webkul.com/blog/depend-attribute-field-attributes-field-admin-form-magento2/

I hope this will help

5
  • this can not work in product attribute. Apr 11, 2019 at 11:35
  • @AshishViradiya please check, updated my answer Apr 12, 2019 at 3:42
  • i want to hide the field and it should be work after save. Apr 15, 2019 at 6:51
  • Hi @Muhamma Hasham, I need to show both the field but when the enable is yes that I need to make the another filed required. How can I do this? May 28, 2019 at 11:45
  • this solution doesn't worl Jul 8, 2021 at 13:05
1

the webkul reference works for me but I have to remapping the values for the main dropdown field inside the modifier, i.e.:

 'options' => [
                        [
                            'value' => 0
                        ],
                        [
                            'value' => 1
                        ],
                    ]

The main field it's anyway an int type with select frontend component. Anyone the same issue?

0

I think the webkul reference only links slave field to master field's initial value; it doesn't dynamically update slave field visibility/disability on master field toggling. For this, you must not import master field data source value but the :checked value of the uiElement linked to master field instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.