Dependent Fields In UI-Component Forms In Magento 2

Written by Mahesh Makwana

Aug 01, 2021

Dependent Fields In UI-Component Forms In Magento 2

There are many times we need some form fields are hide and show dependents on other form fields. These dependent form fields provide user fill only require data in the form. In UI-component, we manage form field hide show based on component JS. Here we show you a few examples for dependents form fields. If f you have been in search of top-notch Magento web development consultancy or hire Magento developer, contact Dolphin Web Solution today and get expert assistance!

Read more : create Ui Form and Ui grid in Magento 2

Step-1: Add the below code

Add the below code at app/code/Dolphin/DependentFieldsDemo/view/adminhtml/ui_component/YourUiFormFileName.xml

..........

<field name="slider_type">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">Dolphin\DependentFieldsDemo\Model\Config\Source\SliderTypes</item>
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">int</item>
            <item name="component" xsi:type="string">Dolphin_DependentFieldsDemo/js/form/element/slider-type</item>
            <item name="label" xsi:type="string" translate="true">Change Option</item>
            <item name="formElement" xsi:type="string">select</item>
            <item name="source" xsi:type="string">slider_type</item>
            <item name="dataScope" xsi:type="string">slider_type</item>
            <item name="sortOrder" xsi:type="number">10</item>
        </item>
    </argument>
</field>
<field name="select_type">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">Dolphin\DependentFieldsDemo\Model\Config\Source\ProductType</item>
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">int</item>
            <item name="label" xsi:type="string" translate="true">Select Type</item>
            <item name="formElement" xsi:type="string">select</item>
            <item name="source" xsi:type="string">select_type</item>
            <item name="dataScope" xsi:type="string">select_type</item>
            <item name="sortOrder" xsi:type="number">20</item>
        </item>
    </argument>
</field>
<field name="text_input">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">text</item>
            <item name="label" xsi:type="string" translate="true">Text Input</item>
            <item name="formElement" xsi:type="string">input</item>
            <item name="source" xsi:type="string">text_input</item>
            <item name="dataScope" xsi:type="string">text_input</item>
            <item name="sortOrder" xsi:type="number">30</item>
        </item>
    </argument>
</field>

..........

Here we add <item name=”component” xsi:type=”string”>Dolphin_DependentFieldsDemo/js/form/element/slider-type</item> this line which is add js to form field. And we Manage other form fields based on Value change of based field where we add component JS.

Step-2: Create slider-type.js

Create slider-type.js at app/code/Dolphin/DependentFieldsDemo/view/adminhtml/web/js/form/element

define([
    'jquery',
    'underscore',
    'uiRegistry',
    'Magento_Ui/js/form/element/select'
], function ($, _, uiRegistry, select) {
    'use strict';
    return select.extend({

        initialize: function (){
            var status = this._super().initialValue;
            this.fieldDepend(status);
            return this;
        },


        /**
         * On value change handler.
         *
         * @param {String} value
         */
        onUpdate: function (value) {

            this.fieldDepend(value);
            return this._super();
        },

        /**
         * Update field dependency
         *
         * @param {String} value
         */
        fieldDepend: function (value) {
            setTimeout(function () {
                console.log(value);
                var selectType = uiRegistry.get('index = select_type');
                var textInput = uiRegistry.get('index = text_input');

                // for home page silder
                if (value == "home") {
                    selectType.hide();
                    textInput.hide();
                } else {
                    selectType.show();
                    textInput.show();
                }
            }, 500);
            return this;
        }
    });
});

Now you show the below output:

The above is example is simple to hide show files base on the value of the select option. Now we make some complex of it. We are creating three form fields: a customer that shows a list of customers, the second is an order that shows selected customer’s orders, and the last one is ordered items that show selected order’s items.

Step-1: Add the below code

Add the below code at app/code/Dolphin/DependentFieldsDemo/view/adminhtml/ui_component/YourUiFormFileName.xml

..........

 <field name="customer_id"  formElement="select" component="Dolphin_DependentFieldsDemo/js/components/select-customer" >
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="filterOptions" xsi:type="boolean">true</item>
            <item name="multiple" xsi:type="boolean">false</item>
            <item name="showCheckbox" xsi:type="boolean">true</item>
            <item name="disableLabel" xsi:type="boolean">true</item>
            <item name="mapper" xsi:type="object">Dolphin\DependentFieldsDemo\Model\Mapper</item>
            <item name="sortOrder" xsi:type="number">10</item>
        </item>
    </argument>
    <settings>
        <required>true</required>
        <validation>
            <rule name="required-entry" xsi:type="boolean">true</rule>
        </validation>
        <elementTmpl>ui/grid/filters/elements/ui-select</elementTmpl>
        <label translate="true">Select Customer</label>
        <dataScope>data.customer</dataScope>
        <componentType>field</componentType>
        <listens>
            <link name="${ $.namespace }.${ $.namespace }:responseData">setParsed</link>
        </listens>
    </settings>
    <formElements>
        <select>
            <settings>
                <options class="Dolphin\DependentFieldsDemo\Ui\Component\Create\Form\Customer\CustomerOptions"/>
            </settings>
        </select>
    </formElements>
</field>
<field name="order_id">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="component" xsi:type="string">Dolphin_DependentFieldsDemo/js/components/select-order</item>
            <item name="label" xsi:type="string" translate="true">Select Order</item>
            <item name="visible" xsi:type="boolean">true</item>
            <item name="dataType" xsi:type="string">text</item>
            <item name="mapper" xsi:type="object">Dolphin\DependentFieldsDemo\Model\Mapper</item>
            <item name="formElement" xsi:type="string">select</item>
            <item name="source" xsi:type="string">order_id</item>
            <item name="sortOrder" xsi:type="number">20</item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="boolean">true</item>
            </item>
        </item>
    </argument>
    <settings>
        <dataScope>data.order_id</dataScope>
        <listens>
            <link name="${ $.namespace }.${ $.namespace }:responseData">setParsed</link>
        </listens>
    </settings>
</field>
<field name="order_for">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="label" xsi:type="string">Select Item</item>
            <item name="visible" xsi:type="boolean">true</item>
            <item name="dataType" xsi:type="string">text</item>
            <item name="formElement" xsi:type="string">select</item>
            <item name="sortOrder" xsi:type="number">30</item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="boolean">true</item>
            </item>
        </item>
    </argument>
</field>

..........

Step-2: create a customer option

create a customer option CustomerOptions.php at app/code/Dolphin/DependentFieldsDemo/Ui/Component/Create/Form/Customer

<?php

namespace Dolphin\DependentFieldsDemo\Ui\Component\Create\Form\Customer;

use Magento\Customer\Model\ResourceModel\Customer\CollectionFactory as CustomerCollectionFactory;
use Magento\Framework\Data\OptionSourceInterface;

class CustomerOptions implements OptionSourceInterface
{

    protected $customerCollectionFactory;
    protected $_orderCollectionFactory;
    protected $customerTree;

    public function __construct(
        CustomerCollectionFactory $customerCollectionFactory,
        \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory
    ) {
        $this->customerCollectionFactory = $customerCollectionFactory;
        $this->_orderCollectionFactory = $orderCollectionFactory;
    }
    public function toOptionArray()
    {
        return $this->getCustomerTree();
    }
    protected function getCustomerTree()
    {
        $customerById = [];
        if ($this->customerTree === null) {
            $collection = $this->customerCollectionFactory->create();
            if (count($collection)) {
                $collection->addNameToSelect();
                foreach ($collection as $customer) {
                    $customerId = $customer->getEntityId();
                    $Ordercollection = $this->_orderCollectionFactory->create();
                    $Ordercollection->addFieldToFilter('customer_id', $customerId);
                    if (count($Ordercollection)) {
                        if (!isset($customerById[$customerId])) {
                            $customerById[$customerId] = [
                                'value' => $customerId,
                            ];
                            $customerById[$customerId]['label'] = $customer->getName() .
                            " ( " . $customer->getEmail() . ")";
                        }
                    }
                }
                $cust_count = count($customerById);
                if ($cust_count == 0) {
                    $options[] = [
                        'label' => 'You have no Order',
                        'value' => '',
                    ];
                    return $options;
                }
                $this->customerTree = $customerById;
                return $this->customerTree;
            } else {
                $options[] = [
                    'label' => 'You have no Oreder',
                    'value' => '',
                ];
                return $options;
            }
        }
    }
}

Now we create a Mapper file that provides order Ids and Order’s items options.

You also like to use this extension: Quick order Extension

Step-3: create Mapper.php

create Mapper.php at app/code/Dolphin/DependentFieldsDemo/Model

<?php

namespace Dolphin\DependentFieldsDemo\Model;

class Mapper
{
    public $map;
    public $map1;
    protected $_orderCollectionFactory;
    protected $orderRepository;

    public function __construct(
        \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory,
        \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
    ) {
        $this->_orderCollectionFactory = $orderCollectionFactory;
        $this->orderRepository = $orderRepository;
        $this->map = $this->makeMap();
        $this->map1 = $this->makeMapItem();
    }
    private function makeMap()
    {
        if ($this->map == null) {
            $this->map = $this->buildMap();
        }
        return $this->map;
    }
    private function makeMapItem()
    {
        if ($this->map1 == null) {
            $this->map1 = $this->buildMapItems();
        }
        return $this->map1;
    }
    private function buildMap()
    {
        $order = $this->_orderCollectionFactory->create()
            ->addAttributeToSelect('*');
        $items = [];
        $options = [];
        $result = [];
        foreach ($order->getData() as $attribute) {
            if ($attribute['customer_id'] != '') {
                $result[$attribute['customer_id']][] = [
                    'label' => $attribute['increment_id'], 'value' => $attribute['increment_id'],
                ];
            }
        }
        return $result;
    }

    private function buildMapItems()
    {
        $result = [];
        $orderCollection = $this->_orderCollectionFactory->create()
            ->addAttributeToSelect('*');
        foreach ($orderCollection as $attribute) {
            if ($attribute->getCustomerId() != '') {
                $order_id = $attribute->getEntityId();
                $increment_id = $attribute->getIncrementId();
                $order_data = $this->orderRepository->get($order_id);
                if (!empty($order_data)) {
                    foreach ($order_data->getAllItems() as $value) {
                        $result[$increment_id][] = [
                            'label' => $value->getName(), 'value' => $value->getProductId(),
                        ];
                    }
                }
            }
        }
        return $result;
    }
}

Now we add component JS files

Step-4: For customers create

For customer create select-customer.js at app/code/Dolphin/DependentFieldsDemo/view/adminhtml/web/js/components

define([
    'Magento_Ui/js/form/element/ui-select',
    'uiRegistry',
], function (Select,uiRegistry) {
    'use strict';
    return Select.extend({
         defaults: {
            mapper: []
        },

         initialize: function (){

            var order_id = uiRegistry.get('index = order_id');
            var order_for  = uiRegistry.get('index = order_for');
            order_id.hide();
            order_for.hide();
            return this._super();
            return this.setDependentOptions(this.value());

        },

        setParsed: function (data) {
            var option = this.parseData(data);
            if (data.error) {
                return this;
            }
            this.options([]);
            this.setOption(option);
            this.set('newOption', option);
        },

        onUpdate: function (value) {
           var order_id_1 = uiRegistry.get('index = order_id');
           var order_for_1  = uiRegistry.get('index = order_for');
           order_id_1.show();
           order_for_1.show();
           this.setDependentOptions(value);
           return this._super();
        },

        setDependentOptions: function (value) {
           var options = this.mapper['map'][value];
           var field = uiRegistry.get('index = order_id');
           field.setOptions(options);
           return this;
        },

        parseData: function (data) {
            return {
                value: data.customer.entity_id,
                label: data.customer.name
            };
        }
    });
});

Step-5: For order create

For order create select-order.js at app/code/Dolphin/DependentFieldsDemo/view/adminhtml/web/js/components

define([
    'underscore',
    'uiRegistry',
    'Magento_Ui/js/form/element/select',
], function (_, uiRegistry, select) {
    'use strict';
    return select.extend({
        defaults: {
            mapper: []
        },

        setParsed: function (data) {
            var option = this.parseData(data);
            if (data.error) {
                return this;
            }
            this.options([]);
            this.setOption(option);
            this.set('newOption', option);
        },

        onUpdate: function (value) {
            this.setDependentOptions(value);
            return this._super();
        },

        setDependentOptions: function (value) {
            var options = this.mapper['map1'][value];
            var field = uiRegistry.get('index = order_for');
            field.setOptions(options);
            return this;
        },

        parseData: function (data) {
            return {
                value: data.order_id.increment_id,
                label: data.order_id.get_name
            };
        }
    });
});

After creating and updating the above files run Magento commands:

php bin/magento setup:upgrade
php bin/magento setup:static-content:deploy -f
php bin/magento cache:clean

Now you show the below output:

Dependent Fields

 

You also like this to read

I hope this helps you. For any doubts regarding this topic, please write your doubts in the comments section.

Mahesh Makwana

Author

We can help you with

  • Dedicated Team
  • Setup Extended Team
  • Product Development
  • Custom App Development

Schedule a Developer Interview And Get 7 Days Risk-Free Trial

Fill out This Form and one of Our Technical Experts will Contact you Within 12 Hours.

    Google
    |

    4.8

    Google
    |

    4.8

    Google
    |

    4.9

    Google
    |

    4.8

    Google
    |

    4.9

    Copyright © 2024 DOLPHIN WEB SOLUTION. All rights reserved.

    TO TOP