1

How to create Custom option programatically in which both are drop-down and they are dependent on each other . Dependent in the sense , changing value of second drop-down option based on the value of first drop-down

  • 1
    Answer is here magento.stackexchange.com/questions/294983/… – Msquare Feb 19 at 3:34
  • Can u tell me that where will be the selected drop-down values be saved? Does it saved as an attribute value ? and in which table in DB? – Mr Zid Feb 19 at 6:42
  • These save in your custom table. And this fields name must be same as table column name. – Msquare Feb 19 at 8:03
5

we are create three form fields.

    <field name="customer_id"  formElement="select" component="Vendorename_Modulename/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">Vendorename\Modulename\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="Vendorename\Modulename\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">Vendorename_Modulename/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">Vendorename\Modulename\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>

Now Create an customer Option

Vendorename\Modulename\Ui\Component\Create\Form\Customer

CustomerOptions.php

<?php

namespace Vendorename\Modulename\Ui\Component\Create\Form\Customer;

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

class CustomerOptions implements OptionSourceInterface
{

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

    public function __construct(
        CustomerCollectionFactory $customerCollectionFactory,
        \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory,
        RequestInterface $request
    ) {
        $this->customerCollectionFactory = $customerCollectionFactory;
        $this->_orderCollectionFactory = $orderCollectionFactory;
        $this->request = $request;
    }
    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 which provide a order Id and Order items options.

Vendorename\Modulename\Model

Mapper.php

<?php

namespace Vendorename\Modulename\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->getIncrementId();
                $order_data = $this->orderRepository->get($order_id);
                if (!empty($order_data)) {
                    foreach ($order_data->getAllItems() as $value) {
                        $result[$order_id][] = [
                            'label' => $value->getName(), 'value' => $value->getProductId(),
                        ];
                    }
                }
            }
        }
        return $result;
    }
}

Now we add Jquery files

for customer

Vendorename/Modulename/view/adminhtml/web/js/components

select-customer.js

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
            };
        }
    });
});

for order

Vendorename/Modulename/view/adminhtml/web/js/components

select-order

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
            };
        }
    });
});
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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