Back to Top

Display dependent fields on Customer Account Edit Page

Updated 31 March 2023

Hello Friends!
In this blog, we will learn how we can display and update the dependent fields’ values on the customer account edit information page.
Before continuing on this blog, please check our Previous Blog, in which you will learn its previous steps.

To display the dependent fields on the customer account edit page, please follow the below steps.

1. Create customer_account_edit.xml file inside the <magento-root-dir>/app/code/Vendor/CustomModule/view/frontend/layout/ directory.

<?xml version="1.0"?>
<!--
/**
 * @author Vendor
 * @copyright Copyright (c) 2021 Vendor
 * @package Vendor_CustomModule
 */
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="form.additional.info">
            <block class="Vendor\CustomModule\Block\Customer\Form\EditCustomerAttributes"
                   name="attribute_customer_edit"
                   template="Vendor_CustomModule::customer_attributes.phtml"
                   cacheable="false" />
        </referenceContainer>
    </body>
</page>

2. Create customer_attributes.phtml file inside the <magento-root-dir>/app/code/Vendor/CustomModule/view/frontend/templates/ directory.

<?php
/**
 * Webkul Software.
 *
 * @category  Webkul
 * @package   Webkul_CustomModule
 * @author    Webkul
 * @copyright Webkul Software Private Limited (https://webkul.com)
 * @license   https://store.webkul.com/license.html
 */
$customerData = $block->getCustomerData();
$aadharNumber = $customerData["wk_custom_aadhaar_number"] ?? "";
$isAadhar = $customerData["wk_custom_want_to_add_aadhaar"] ?? 0;
?>
<legend class="legend"><span>Additional Information</span></legend>
<div class="field">
    <label for="wk_custom_want_to_add_aadhaar" class="label">
    <span><?= $block->escapeHtml(__('Do you want add your aadhar number?')) ?></span></label>
    <div class="control">
        <select name="wk_custom_want_to_add_aadhaar" id="wk_custom_want_to_add_aadhaar" class="select">
            <option value="1" <?= /* @noEscape*/ ($isAadhar==1)?'selected':'';?> ><?= $block->escapeHtml(__('Yes')) ?></option>
            <option value="0" <?= /*noEscape */ ($isAadhar==0)?'selected':'';?>><?= $block->escapeHtml(__('No')) ?></option>
        </select>
    </div>
</div>
<div class="field">
    <label class="label" for="Aadhaar Number">
        <span><?= /** @noEscape */ __('Aadhaar Number');?></span>
    </label>
    <div class="control">
        <input type="text" name="wk_custom_aadhaar_number" id="wk_custom_aadhaar_number" 
               title="<?= /** @noEscape */ __('Aadhaar Number');?>" class="input-text"
               maxlength="12"
        value="<?= /* @noEscape */ $aadharNumber ?>">
    </div>
</div>

3. Create EditCustomerAttributes.php file inside the <magento-root-dir>/app/code/Vendor/CustomModule/Block/Customer/Form/ directory.

<?php
namespace Vendor\CustomModule\Block\Customer\Form;

use Magento\Backend\Block\Template\Context;
use Magento\Framework\Registry;
use Magento\Framework\Data\FormFactory;
use Vendor\CustomModule\Block\Widget\Form\Renderer\Element;
use Vendor\CustomModule\Block\Widget\Form\Renderer\Fieldset;
use Magento\Eav\Model\Entity\Attribute;
use Magento\Customer\Model\AttributeMetadataDataProvider;
use Magento\Framework\ObjectManagerInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Block\Adminhtml\Form;
use Magento\Customer\Model\Session;
use Magento\Framework\DataObjectFactory;

class EditCustomerAttributes extends Form
{
    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var Session
     */
    private $session;

    /**
     * @var DataObjectFactory
     */
    private $dataObjectFactory;

    /**
     * @var Element
     */
    private $elementRenderer;

    /**
     * @var AttributeMetadataDataProvider
     */
    private $attributeMetadataDataProvider;

    /**
     * @var ObjectManagerInterface
     */
    private $objectManager;

    /**
     * @var  array
     */
    private $_customerData;

    /**
     * @var Fieldset
     */
    private $fieldsetRenderer;

    /**
     * Attributes constructor.
     *
     * @param Context $context
     * @param Registry $registry
     * @param Session $session
     * @param FormFactory $formFactory
     * @param Fieldset $fieldsetRenderer
     * @param Element $elementRenderer
     * @param ObjectManagerInterface $objectManager
     * @param DataObjectFactory $dataObjectFactory
     * @param AttributeMetadataDataProvider $attributeMetadataDataProvider
     * @param array $data
     */
    public function __construct(
        Context $context,
        Registry $registry,
        Session $session,
        FormFactory $formFactory,
        Fieldset $fieldsetRenderer,
        Element $elementRenderer,
        ObjectManagerInterface $objectManager,
        DataObjectFactory $dataObjectFactory,
        AttributeMetadataDataProvider $attributeMetadataDataProvider,
        array $data = []
    ) {
        parent::__construct($context, $registry, $formFactory, $data);
        $this->session           = $session;
        $this->fieldsetRenderer  = $fieldsetRenderer;
        $this->elementRenderer   = $elementRenderer;
        $this->objectManager     = $objectManager;
        $this->storeManager      = $context->getStoreManager();
        $this->dataObjectFactory = $dataObjectFactory;
        $this->attributeMetadataDataProvider = $attributeMetadataDataProvider;
    }

    /**
     * Check whether attribute is visible on front
     *
     * @param Attribute $attribute
     *
     * @return bool
     */
    public function isAttributeVisibleOnFront(Attribute $attribute)
    {
        $isVisibleOnFront = $attribute->getData('is_system');
        return (!$isVisibleOnFront && $attribute->getIsVisible());
    }

    protected function _prepareForm()
    {
        /** @var \Magento\Framework\Data\Form $form */
        $form = $this->_formFactory->create();
        $type = 'customer_account_edit';

        $attributes = $this->attributeMetadataDataProvider->loadAttributesCollection(
            'customer',
            $type
        );

        if (!$attributes || !$attributes->getSize()) {
            return;
        }
        $fieldset = $form->addFieldset(
            'group-fields-customer-attributes',
            [
                'class' => 'user-defined',
                'legend' => __('Additional Information')
            ]
        );
        $fieldset->setRenderer($this->fieldsetRenderer);

        $this->_setFieldset($attributes, $fieldset);
        $this->prepareDependentAttributes($attributes, $fieldset);

        $this->setForm($form);
    }

    /**
     * @inheritdoc
     */
    protected function _initFormValues()
    {
        if ($form = $this->getForm()) {
            if ($this->getCustomerData()) {
                $form->addValues($this->getCustomerData());
            }
            /** @var \Magento\Customer\Block\Form\Register $registerForm */
            $registerForm = $this->getLayout()->getBlock('customer_form_register');
            if (is_object($registerForm) && $registerForm->getFormData() instanceof \Magento\Framework\DataObject) {
                $form->addValues($registerForm->getFormData()->getData());
            }
        }

        return parent::_initFormValues();
    }

    /**
     * Set Fieldset to Form
     *
     * @param array|\Magento\Customer\Model\ResourceModel\Form\Attribute\Collection $attributes
     * $attributes - attributes that will be added
     * @param \Magento\Framework\Data\Form\Element\Fieldset $fieldset
     * @param array $exclude
     * @return void
     */
    protected function _setFieldset($attributes, $fieldset, $exclude = [])
    {
        $this->_addElementTypes($fieldset);

        foreach ($attributes as $attribute) {
            /** @var $attribute \Magento\Eav\Model\Entity\Attribute */
            if (!$this->isAttributeVisibleOnFront($attribute)) {
                continue;
            }
            $attribute->setStoreId($this->storeManager->getStore()->getId());

            if ($inputType = $attribute->getFrontend()->getInputType()) {
                $rendererClass = $attribute->getFrontend()->getInputRendererClass();
                
                if ($inputType == "boolean" || $inputType == "date" || $inputType == "datetime") {
                    $fieldType = 'Webkul\CustomModule\Block\Data\Form\Element\\' . ucfirst($inputType);
                } else {
                    $fieldType = 'Magento\Framework\Data\Form\Element\\' . ucfirst($inputType);
                }
                
                if (!empty($rendererClass)) {
                    $fieldType = $inputType . '_' . $attribute->getAttributeCode();
                    $fieldset->addType($fieldType, $rendererClass);
                }

                $data = [
                    'name' => $attribute->getAttributeCode(),
                    'label' => $attribute->getStoreLabel(),
                    'class' => $attribute->getFrontend()->getClass(),
                    'required' => $attribute->getIsRequired() || $attribute->getRequiredOnFront(),
                    'note' => $attribute->getNote()
                ];
                
                $element = $fieldset->addField(
                    $attribute->getAttributeCode(),
                    $fieldType,
                    $data
                )->setEntityAttribute(
                    $attribute
                );

                $element->setValue($attribute->getDefaultValue());
                $element->setRenderer($this->elementRenderer);
                $element->setAfterElementHtml($this->_getAdditionalElementHtml($element));

                /* add options format */
                $this->_applyTypeSpecificConfig($inputType, $element, $attribute);
            }
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function _applyTypeSpecificConfig($inputType, $element, Attribute $attribute)
    {
        switch ($inputType) {
            case 'select':
                $element->addElementValues($attribute->getSource()->getAllOptions(true, false));
                break;
            case 'multiselect':
                $element->addElementValues($attribute->getSource()->getAllOptions(false, false));
                $element->setCanBeEmpty(true);
                break;
            default:
                break;
        }
    }

    /**
     * @param \Magento\Customer\Model\ResourceModel\Form\Attribute\Collection $attributes
     * @param \Magento\Framework\Data\Form\Element\Fieldset $fieldset
     */
    protected function prepareDependentAttributes($attributes, $fieldset)
    {
        $depends = [];
        $attributeIds = $attributes->getColumnValues('attribute_id');
        if (empty($attributeIds)) {
            return;
        }
        //you can add array options dynamically as per your need
        $depends[] = [
            'parent_attribute_id' => 163,
            'parent_attribute_code' => 'wk_custom_want_to_add_aadhaar',
            'parent_option_id' => 1,
            'depend_attribute_id' => 162,
            'depend_attribute_code' => 'wk_custom_aadhaar_number'
        ];
        
        if (!empty($depends)) {
            $fieldset->setData('depends', $depends);
        }
    }

    /**
     * @return array
     */
    private function getCustomerData()
    {
        if (!isset($this->_customerData)) {
            $this->_customerData = [];
            if ($this->session->isLoggedIn()) {
                $this->_customerData = $this->session->getCustomer()->getData();
            }
        }

        return $this->_customerData;
    }
}

4. Now, see the result in the following image.

Searching for an experienced
Magento 2 Company ?
Find out More
Account-Informat-1-1

Hope this will be helpful. Thanks ­čÖé

Previous Blog: Create Dependent Attribute Fields on Customer Registration Form

Next Blog: Add Custom Column in Customer Grid

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


2 comments

  • Daniel
    • Khushboo Sahu (Moderator)
  • Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home