#StackBounty: #magento2 #magento2.3 #customer-attribute #shipping-address #customer-address Magento 2.3 – Customer address attribute no…

Bounty: 50

I have created a custom custom_address attribute “a_mobile_phone”. I can save the attribute in the admin and the customer address edit form.

I have added this attribute to the checkout address form with no issue but it is not saving in the database.

My attribut is used in form :
enter image description here

I have a plugin :

//Vendor/Module/etc/frontend/di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <type name="MagentoCheckoutBlockCheckoutLayoutProcessor">
            <plugin name="add-mobile-phone-field"
                    type="VendorModulePluginLayoutProcessorPlugin" sortOrder="10"/>
        </type>
    </config>

My file :

//Vendor/Module/Plugin/LayoutProcessorPlugin.php
public function afterProcess(
        MagentoCheckoutBlockCheckoutLayoutProcessor $subject,
        array  $jsLayout
    ) {
        $customAttributeCode = 'a_mobile_phone';

        $customField = [
            'component' => 'Magento_Ui/js/form/element/abstract',
            'config' => [
                // customScope is used to group elements within a single form (e.g. they can be validated separately)
                'customScope' => 'shippingAddress.custom_attributes',
                'customEntry' => null,
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/input',
                'tooltip' => [
                    'description' => 'Pour la livraison',
                ],
            ],
            'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
            'label' => 'Téléphone portable',
            'provider' => 'checkoutProvider',
            'sortOrder' => 200,
            'validation' => [
                'required-entry' => true
            ],
            'options' => [],
            'filterBy' => null,
            'customEntry' => null,
            'required' => true,
            'visible' => true,
            'value' => '' // value field is used to set a default value of the attribute
        ];

        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $customField;

        return $jsLayout;
    }

My fieldset :

//Vendor/Module/etc/fieldset.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:DataObject/etc/fieldset.xsd">
    <scope id="global">
        <fieldset id="sales_convert_quote_address">
            <field name="a_mobile_phone">
                <aspect name="to_order_address" />
                <aspect name="to_customer_address" />
            </field>
        </fieldset>
    </scope>
</config>

The mixin :

//Vendor/Module/view/frontend/requirejs-config.js
var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/action/set-shipping-information': {
                'Vendor_Module/js/action/set-shipping-information-mixin': true
            }
        }
    }
};

The mixin file :

//Vendor/Module/view/frontend/web/js/action/set-shipping-information-mixin.js
define([
    'jquery',
    'mage/utils/wrapper',
    'Magento_Checkout/js/model/quote'
], function ($, wrapper, quote) {
    'use strict';

    return function (setShippingInformationAction) {

        return wrapper.wrap(setShippingInformationAction, function (originalAction) {
            var shippingAddress = quote.shippingAddress();
            if (shippingAddress['extension_attributes'] === undefined) {
                shippingAddress['extension_attributes'] = {};
            }

            shippingAddress['extension_attributes']['a_mobile_phone'] = jQuery('[name="a_mobile_phone"]').val();

            return originalAction();
        });
    };
});

The extension attribute :

//Vendor/Module/etc/extension_attributes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="MagentoSalesApiDataOrderAddressInterface">
        <attribute code="a_mobile_phone" type="string" />
    </extension_attributes>
    <extension_attributes for="MagentoCustomerApiDataAddressInterfacee">
        <attribute code="a_mobile_phone" type="string" />
    </extension_attributes>
    <extension_attributes for="MagentoQuoteApiDataAddressInterface">
        <attribute code="a_mobile_phone" type="string" />
    </extension_attributes>
    <extension_attributes for="MagentoCheckoutApiDataShippingInformationInterface">
        <attribute code="a_mobile_phone" type="string" />
    </extension_attributes>
</config>

With all this my attribute is displayed in the checkout.
When I set the value in a new address I have the code displayed by the knockoutJs.
enter image description here

But my biggest issue is that the attribut value is not save in the DB when I pass the order.

What am I missing to save the attribut value ? I followed the magento doc for this : https://devdocs.magento.com/guides/v2.3/howdoi/checkout/checkout_new_field.html


Get this bounty!!!

#StackBounty: #magento2 #magento2.3 #custom-attributes #customer-attribute #eav-attributes Magento 2.X: Customer custom attribute is no…

Bounty: 50

I have an issue I can’t find why. I tried the issue on Magento 2.3.1 and 2.3.2.

I have created a module to add a new customer attribute. No issue for the moment. When I try to save the customer from the admin the value is not saved even when the field is in the admin form. Can you find my mistake?

enter image description here

namespace VendorModuleSetup;

use MagentoCustomerModelCustomer;
use MagentoFrameworkSetupModuleDataSetupInterface;
use MagentoFrameworkSetupModuleContextInterface;
use MagentoCustomerSetupCustomerSetupFactory;
use MagentoEavModelEntityAttributeSetFactory as AttributeSetFactory;

class UpgradeData implements MagentoFrameworkSetupUpgradeDataInterface
{
    private $customerSetupFactory;
    protected $eavConfig;
    private $attributeSetFactory;

    public function __construct(
        CustomerSetupFactory $customerSetupFactory,
        MagentoEavModelConfig $eavConfig,
        AttributeSetFactory $attributeSetFactory
    ) {
        $this->customerSetupFactory = $customerSetupFactory;
        $this->eavConfig = $eavConfig;
        $this->attributeSetFactory = $attributeSetFactory;

    }

    public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {

        if (version_compare($context->getVersion(), '1.0.1') < 0) {
            $customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
            $customerSetup->addAttribute(
                Customer::ENTITY,
                'exported_to_erp_at',
                [
                    'type' => 'varchar',
                    'label' => 'Exported to erp at',
                    'input' => 'text',
                    'required' => false,
                    'sort_order' => 88,
                    'visible' => true,
                    'system' => false,
                    'user_defined' => false,
                ]
            );

            $customerEntity = $customerSetup->getEavConfig()->getEntityType('customer');
            $attributeSetId = $customerEntity->getDefaultAttributeSetId();

            /** @var $attributeSet AttributeSet */
            $attributeSet = $this->attributeSetFactory->create();
            $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);

            $attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'exported_to_erp_at')
                ->addData([
                    'attribute_set_id' => $attributeSetId,
                    'attribute_group_id' => $attributeGroupId,
                    'used_in_forms' => ['adminhtml_customer'],
                ]);

            $attribute->save();

        }
    }
}

As I said I tried to save with no success from the admin so I tried in Code. No success either.

$customer = $this->_customerFactory->create()->load(46431);
        $customer->setData("exported_to_erp_at", "toto");
        $customer->setCustomAttribute("exported_to_erp_at", "toto");
        $customer->save();

    //should work
    $customer = $this->_customerRepository->getById(46431);
    $customer->setCustomAttribute("exported_to_erp_at", "toto");
    $this->_customerRepository->save($customer);

Do you have an idea?

EDIT

If this help I have not a clean installation. This is a migration with the magento migration tool from 1.7.x to 2.3.x


Get this bounty!!!

#StackBounty: #magento2 #customer-attribute #extension-attributes How to pass a attribute code dynamically in extension_attributes.xml

Bounty: 50

How to pass a attribute code dynamically in extension_attributes.xml
or how to save a custom field value in db in checkout page without extension_attributes

extension_attributes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="MagentoQuoteApiDataAddressInterface">
        <attribute code="How_to_pass_code_dynamically_here" type="string" />
        <attribute code="How_to_pass_code_dynamically_here" type="string" />
    </extension_attributes>
</config>

It should contain getters and setters of address attribute. In this case. <attribute_code="example"> setExample(), getExample()

attribute_code are given by admin dynamically in backend

code:

 $attributeCollection = $this->helper->getUserDefinedAttribures();
       if ($attributeCollection->getSize() > 0) 
       {
         foreach ($attributeCollection as $attribute)    
         {
          if ($this->helper->isAttribureForCheckoutRegister($attribute- 
          >getAttributeCode()))
         {

           $customAttributeCode = $attribute->getAttributeCode();
            var_dump($customAttributeCode);

          }
        }
    }

image:

enter image description here

I have created a customer attribute which created dynamically from backend its fine works in customer_account_create and customer_account_edit and I stuck at saving customer attribute field data in after saving address information in the checkout form. After filling shipping address, shipping and press next button method I m getting the following error

message: “Internal Error. Details are available in Magento log file. Report ID: webapi-5d3aa1ebbf82a”

Exception log: ‘Report ID: webapi-5d3aa1ebbf82a; Message: Property “TestAge” does not have corresponding setter in class “MagentoQuoteApiDataAddressExtensionInterface”.’ in D:wamp64wwwm2magentovendormagentoframeworkWebapiErrorProcessor

and I followed this link

app/code/Cm/CustomerAttribute/etc/frontend/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">
    <type name="MagentoCheckoutBlockOnepage">
        <arguments>
            <argument name="layoutProcessors" xsi:type="array">
                <item name="cm__fields_layoutprocessor" xsi:type="object">CmCustomerAttributeBlockCheckoutLayoutProcessor</item>
            </argument>
        </arguments>
    </type>
</config>

app/code/ Cm/CustomerAttribute/Block/Checkout/LayoutProcessor.php

<?php
namespace CmCustomerAttributeBlockCheckout;

class LayoutProcessor
{
    protected $customerSession;
    protected $resultPageFactory;
    public function __construct(CmCustomerAttributeHelperCustomerattribute $helper,
    MagentoCustomerApiCustomerRepositoryInterface $customerRepositoryInterface,
    MagentoCustomerModelSession $customerSession)
    {
        $this->helper = $helper;
        $this->customerRepositoryInterface = $customerRepositoryInterface;
        $this->customerSession = $customerSession;
    }
    public function afterProcess(
        MagentoCheckoutBlockCheckoutLayoutProcessor $subject,
        $jsLayout
    ) {
        $attributeCollection = $this->helper->getUserDefinedAttribures();

       if ($attributeCollection->getSize() > 0) 
       {
         foreach ($attributeCollection as $attribute)

         {
        if ($this->helper->isAttribureForCheckoutRegister($attribute->getAttributeCode()))
        {
        $frontEndLabel = $attribute->getStoreLabel($this->helper->getStoreId());

        $customAttributeCode = $attribute->getAttributeCode();
      if($this->customerSession->isLoggedIn()) {

        $customerId =$this->customerSession->getCustomer()->getId();
         $customer =$this->customerRepositoryInterface->getById($customerId);
        $customerAttr = $customer->getCustomAttribute($customAttributeCode)->getValue();
        }
        else
        {
          $customerAttr = NULL;
        }
        $fieldRequiredClass = ($attribute->getIsRequired()) ? 'true' : '' ;
        if($fieldRequiredClass == '')
        {
            $fieldRequiredClass = false;
        }
        $fieldFrontendClass = ($attribute->getFrontendClass()) ? $attribute->getFrontendClass() : '';
        $fieldInput =$attribute->getFrontendInput();
        $attributeId = $attribute->getAttributeId();
        $objectManager = MagentoFrameworkAppObjectManager::getInstance();

        $attributeOptionAll = $objectManager->create(MagentoEavModelResourceModelEntityAttributeOptionCollection::class)
                                    ->setPositionOrder('asc')
                                    ->setAttributeFilter($attributeId)
                                    ->setStoreFilter()
                                    ->load();
        $opt_val = array();
        $allOptions=array();


        foreach ($attributeOptionAll->getData() as $key => $v) 
        {
          // $allid = $v['attribute_id'];
          $opt_val['value'] = $v['option_id'];
          $opt_val['label'] = $v['value'];
          $allOptions[] = $opt_val;
      }
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $this->addNewField($customAttributeCode,$frontEndLabel, $fieldRequiredClass,  $fieldFrontendClass,$fieldInput,  $allOptions, $customerAttr );

        }
      }
    }
    return $jsLayout;
    }

    private function addNewField($customAttributeCode, $frontEndLabel, $fieldRequiredClass,  $fieldFrontendClass, $fieldInput, $allOptions, $customerAttr  )
    {
        if($fieldInput == 'text')
        {
            $fieldInputType = 'input';
            $fieldAbstract =  'abstract';
        }
        elseif ($fieldInput == 'date') {
           $fieldInputType = 'date'; 
           $fieldAbstract =  'date';
        }
        elseif ($fieldInput == 'select') {
           $fieldInputType = 'select'; 
           $fieldAbstract =  'select';
        }

        elseif ($fieldInput == 'boolean') {
           $fieldInputType = 'select'; 
           $fieldAbstract =  'select';
           $allOptions = [
                 ['value' => '0', 'label' => 'No'],
                 ['value' => '1', 'label' => 'Yes']
               ];

        }
         elseif ($fieldInput == 'textarea') {
           $fieldInputType = 'textarea'; 
           $fieldAbstract =  'textarea';

        }
        $customField = [
            'component' => 'Magento_Ui/js/form/element/'.$fieldAbstract.'',
            'config' => [
                'customScope' => 'shippingAddress.custom_attributes',
                'customEntry' => null,
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/'.$fieldInputType.'',
                'rows' => 5
                // 'tooltip' => [
                //     'description' => 'this is what the field is for',
                // ],
            ],
            'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
            'label' => $frontEndLabel,
            'provider' => 'checkoutProvider',
            'sortOrder' => 1000,
            'validation' => [$fieldFrontendClass => true , 
                'required-entry' => $fieldRequiredClass],
            'options' =>  $allOptions,
            'filterBy' => null,
            'customEntry' => null,
            'visible' => true,
            'value' => $customerAttr
        ];

         return $customField;
    }
}

app/code/Cm/CustomerAttribute/view/frontend/requirejs-config.js

 var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/action/set-billing-address': {
                'Cm_CustomerAttribute/js/action/set-billing-address-mixin': true
            },
            'Magento_Checkout/js/action/set-shipping-information': {
                'Cm_CustomerAttribute/js/action/set-shipping-information-mixin': true
            },
            'Magento_Checkout/js/action/create-shipping-address': {
                'Cm_CustomerAttribute/js/action/create-shipping-address-mixin': true
            },
            'Magento_Checkout/js/action/place-order': {
                'Cm_CustomerAttribute/js/action/set-billing-address-mixin': true
            },
            'Magento_Checkout/js/action/create-billing-address': {
                'Cm_CustomerAttribute/js/action/set-billing-address-mixin': true
            }
        }
    }
};

app/code/Cm/CustomerAttribute/view/frontend/web/js/action/create-shipping-address-mixin.js

define([
    'jquery',
    'mage/utils/wrapper',
    'Magento_Checkout/js/model/quote'
], function ($, wrapper,quote) {
    'use strict';

    return function (setShippingInformationAction) {
        return wrapper.wrap(setShippingInformationAction, function (originalAction, messageContainer) {

            if (messageContainer.custom_attributes != undefined) {
                $.each(messageContainer.custom_attributes , function( key, value ) {
                    messageContainer['custom_attributes'][key] = {'attribute_code':key,'value':value};
                });
            }

            return originalAction(messageContainer);
        });
    };
});

app/code/Cm/CustomerAttribute/view/frontend/web/js/action/set-billing-address-mixin.js

define([
    'jquery',
    'mage/utils/wrapper',
    'Magento_Checkout/js/model/quote'
], function ($, wrapper,quote) {
    'use strict';

    return function (setBillingAddressAction) {
        return wrapper.wrap(setBillingAddressAction, function (originalAction, messageContainer) {

            var billingAddress = quote.billingAddress();

            if(billingAddress != undefined) {

                if (billingAddress['extension_attributes'] === undefined) {
                    billingAddress['extension_attributes'] = {};
                }

                if (billingAddress.customAttributes != undefined) {
                    $.each(billingAddress.customAttributes, function (key, value) {

                        if($.isPlainObject(value)){
                            value = value['value'];
                        }

                        billingAddress['extension_attributes'][key] = value;
                    });
                }

            }

            return originalAction(messageContainer);
        });
    };
});

app/code/Cm/CustomerAttribute/view/frontend/web/js/action/set-shipping-information-mixin.js

define([
    'jquery',
    'mage/utils/wrapper',
    'Magento_Checkout/js/model/quote'
], function ($, wrapper,quote) {
    'use strict';

    return function (setShippingInformationAction) {
        return wrapper.wrap(setShippingInformationAction, function (originalAction, messageContainer) {

            var shippingAddress = quote.shippingAddress();

            if (shippingAddress['extension_attributes'] === undefined) {
                shippingAddress['extension_attributes'] = {};
            }

            if (shippingAddress.customAttributes != undefined) {
                $.each(shippingAddress.customAttributes , function( key, value ) {

                    if($.isPlainObject(value)){
                        value = value['value'];
                    }

                    shippingAddress['customAttributes'][key] = value;
                    shippingAddress['extension_attributes'][key] = value;

                });
            }

            return originalAction(messageContainer);
        });
    };
});

app/code/Cm/CustomerAttribute/etc/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">
         <type name="MagentoCheckoutModelShippingInformationManagement">
         <plugin name="Cm_CustomerAttribute::ShippingInformationManagement" 
 type="CmCustomerAttributePluginCheckoutModelShippingInformationManagement" sortOrder="1"/>
          </type>
      </config>

app/code/Cm/CustomerAttribute/Plugin/Checkout/Model/ShippingInformationManagement.php

   <?php
    namespace CmCustomerAttributePluginCheckoutModel;

  class ShippingInformationManagement
{
    /**
     * @param MagentoCheckoutModelShippingInformationManagement $subject
     * @param $cartId
     * @param MagentoCheckoutApiDataShippingInformationInterface $addressInformation
     */
     protected $helper;
     protected $quoteRepository;
     public function __construct(

    BootsgridCustomerAttributeHelperCustomerattribute $helper,
     MagentoQuoteModelQuoteRepository $quoteRepository
    ) {

        $this->helper = $helper;
         $this->quoteRepository = $quoteRepository;
    }


    public function beforeSaveAddressInformation(
        MagentoCheckoutModelShippingInformationManagement $subject,
        $cartId,
        MagentoCheckoutApiDataShippingInformationInterface $addressInformation
    ) {
       $extensionAttributes = $addressInformation->getShippingAddress();
       $custAttributes = $extensionAttributes->getExtensionAttributes();
       if($custAttributes )
       {
         $quote = $this->quoteRepository->getActive($cartId);


        $customField = $custAttributes->getTestTextarea();
        $cus = $custAttributes->getTestAge();
        $quote->setTestAge($cus);
        $quote->setTestTextarea($customField);



      }
        // error_log(print_r($custAttributes,1));
    }
}

How to save the customer_field dynamically in sales_order and quote order in magento 2

image:

enter image description here
When using extension_attributes.xml file its saved into db but i want to pass a attribute_code dynamically in the xml file

etc/extension_attributes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="MagentoQuoteApiDataAddressInterface">
        <attribute code="test_age" type="string" /> * how to pass "test_age" dynamically *
        <attribute code="test_textarea" type="string" />
    </extension_attributes>
</config>

enter image description here


Get this bounty!!!

#StackBounty: #magento2 #customer-attribute #savedata How to save customer attributes dynamically in the checkout register page in mage…

Bounty: 50

I have create a customer attributes which created dynamically from backend its fine works in customer_account_create and customer_account_edit and i was stucked to
saved a customer attributes field data in after save address information in checkout form.

and i followed this link

app/code/ Cm/CustomerAttribute/Model/Plugin/Checkout/LayoutProcessor.php

  <?php
namespace CmCustomerAttributePluginCheckoutBlockCheckout;

class LayoutProcessor
{
    public function __construct(CmCustomerAttributeHelperCustomerattribute $helper)
    {
        $this->helper = $helper;
    }
    public function afterProcess(
        MagentoCheckoutBlockCheckoutLayoutProcessor $subject,
        $jsLayout
    ) {
        $attributeCollection = $this->helper->getUserDefinedAttribures();

       if ($attributeCollection->getSize() > 0) 
       {
         foreach ($attributeCollection as $attribute)

         {
        if ($this->helper->isAttribureForCheckoutRegister($attribute->getAttributeCode()))
        {
        $frontEndLabel = $attribute->getStoreLabel($this->helper->getStoreId());
        $customAttributeCode = $attribute->getAttributeCode();
        $fieldRequiredClass = ($attribute->getIsRequired()) ? 'true' : '' ;
        if($fieldRequiredClass == '')
        {
            $fieldRequiredClass = false;
        }
        $fieldFrontendClass = ($attribute->getFrontendClass()) ? $attribute->getFrontendClass() : '';
        $fieldInput =$attribute->getFrontendInput();
        $attributeId = $attribute->getAttributeId();
        $objectManager = MagentoFrameworkAppObjectManager::getInstance();

        $attributeOptionAll = $objectManager->create(MagentoEavModelResourceModelEntityAttributeOptionCollection::class)
                                    ->setPositionOrder('asc')
                                    ->setAttributeFilter($attributeId)
                                    ->setStoreFilter()
                                    ->load();
        $opt_val = array();
        $allOptions=array();


        foreach ($attributeOptionAll->getData() as $key => $v) 
        {
          // $allid = $v['attribute_id'];
          $opt_val['value'] = $v['option_id'];
          $opt_val['label'] = $v['value'];
          $allOptions[] = $opt_val;
      }
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $this->addNewField($customAttributeCode,$frontEndLabel, $fieldRequiredClass,  $fieldFrontendClass,$fieldInput,  $allOptions );

        }
      }
    }
    return $jsLayout;
    }

    private function addNewField($customAttributeCode, $frontEndLabel, $fieldRequiredClass,  $fieldFrontendClass, $fieldInput, $allOptions  )
    {
        if($fieldInput == 'text')
        {
            $fieldInputType = 'input';
            $fieldAbstract =  'abstract';
        }
        elseif ($fieldInput == 'date') {
           $fieldInputType = 'date'; 
           $fieldAbstract =  'date';
        }
        elseif ($fieldInput == 'select') {
           $fieldInputType = 'select'; 
           $fieldAbstract =  'select';
        }
        elseif ($fieldInput == 'multiselect') {
           $fieldInputType = 'multiselect'; 
           $fieldAbstract =  'multiselect';

        }
        elseif ($fieldInput == 'boolean') {
           $fieldInputType = 'select'; 
           $fieldAbstract =  'select';
           $allOptions = [
                 ['value' => '0', 'label' => 'No'],
                 ['value' => '1', 'label' => 'Yes']
               ];

        }
         elseif ($fieldInput == 'textarea') {
           $fieldInputType = 'textarea'; 
           $fieldAbstract =  'textarea';

        }
        $customField = [
            'component' => 'Magento_Ui/js/form/element/'.$fieldAbstract.'',
            'config' => [
                'customScope' => 'shippingAddress.custom_attributes',
                'customEntry' => null,
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/'.$fieldInputType.'',
                // 'tooltip' => [
                //     'description' => 'this is what the field is for',
                // ],
            ],
            'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
            'label' => $frontEndLabel,
            'provider' => 'checkoutProvider',
            'sortOrder' => 1000,
            'validation' => [$fieldFrontendClass => true , 
                'required-entry' => $fieldRequiredClass],
            'options' =>  $allOptions,
            'filterBy' => null,
            'customEntry' => null,
            'visible' => true,
        ];

         return $customField;
    }
}

image:

enter image description here


Get this bounty!!!

#StackBounty: #magento2 #customer-attribute #savedata How to save a dynamic customer attributes in checkout register page in magento 2?

Bounty: 50

app/code/ Cm/CustomerAttribute/Model/Plugin/Checkout/LayoutProcessor.php

    <?php
namespace CmCustomerAttributeModelPluginCheckout;

class LayoutProcessor
{
    /**
     * @param MagentoCheckoutBlockCheckoutLayoutProcessor $subject
     * @param array $jsLayout
     * @return array
     */
     public function __construct(CmCustomerAttributeHelperCustomerattribute $helper)
    {
        $this->helper = $helper;
    }

    public function afterProcess(
        MagentoCheckoutBlockCheckoutLayoutProcessor $subject,
        array  $jsLayout
    ) {

 $attributeCollection = $this->helper->getUserDefinedAttribures();

    if ($attributeCollection->getSize() > 0) 
    {
         foreach ($attributeCollection as $attribute)

       {
        if ($this->helper->isAttribureForCheckoutRegister($attribute->getAttributeCode()))
        {
        $frontEndLabel = $attribute->getStoreLabel($this->helper->getStoreId());
        $attributeCode = $attribute->getAttributeCode();
        $getAttributeCodeFunction = "get" .  str_replace(' ', '', ucwords(str_replace('_', ' ', $attribute->getAttributeCode

())));
        $fieldRequiredClass = ($attribute->getIsRequired()) ? 'true' : '' ;
        if($fieldRequiredClass == '')
        {
            $fieldRequiredClass = false;
        }
        $fieldFrontendClass = ($attribute->getFrontendClass()) ? $attribute->getFrontendClass() : '';
        $fieldInput =$attribute->getFrontendInput();
        if($fieldInput == 'text')
        {
            $fieldInputType = 'input';
            $fieldAbstract =  'abstract';
            $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children'][$attributeCode] = [
            'component' => 'Magento_Ui/js/form/element/'.$fieldAbstract.'',
            'config' => [
                'customScope' => 'shippingAddress.custom_attributes',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/'.$fieldInputType.'',
                'id' => $attributeCode
            ],
            'dataScope' => 'shippingAddress.custom_attributes.'.$attributeCode.'',
            'label' => $frontEndLabel,
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' =>[$fieldFrontendClass => true, 
                'required-entry' => $fieldRequiredClass],
            'sortOrder' => 250,
            'id' => $attributeCode
        ];
        }
        elseif ($fieldInput == 'date') {
           $fieldInputType = 'date'; 
           $fieldAbstract =  'date';
           $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children'][$attributeCode] = [
            'component' => 'Magento_Ui/js/form/element/'.$fieldAbstract.'',
            'config' => [
                'customScope' => 'shippingAddress.custom_attributes',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/'.$fieldInputType.'',
                'id' => $attributeCode
            ],
            'dataScope' => 'shippingAddress.custom_attributes.'.$attributeCode.'',
            'label' => $frontEndLabel,
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' =>[$fieldFrontendClass => true , 
                'required-entry' => $fieldRequiredClass],
            'sortOrder' => 250,

            'id' => $attributeCode
        ];
        }
        elseif ($fieldInput == 'select') {
           $fieldInputType = 'select'; 
           $fieldAbstract =  'select';

        $attributeId = $attribute->getAttributeId();
        $objectManager = MagentoFrameworkAppObjectManager::getInstance();

        $attributeOptionAll = $objectManager->create(MagentoEavModelResourceModelEntityAttributeOptionCollection::class)
                                    ->setPositionOrder('asc')
                                    ->setAttributeFilter($attributeId)
                                    ->setStoreFilter()
                                    ->load();
        $opt_val = array();
        $allOptions=array();


        foreach ($attributeOptionAll->getData() as $key => $v) 
        {
          // $allid = $v['attribute_id'];
          $opt_val['value'] = $v['option_id'];
          $opt_val['label'] = $v['value'];
          $allOptions[] = $opt_val;
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children'][$attributeCode] = [
            'component' => 'Magento_Ui/js/form/element/'.$fieldAbstract.'',
            'config' => [
                'customScope' => 'shippingAddress.custom_attributes',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/'.$fieldInputType.'',
                'id' => $attributeCode
            ],
            'dataScope' => 'shippingAddress.custom_attributes.'.$attributeCode.'',
            'label' => $frontEndLabel,
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' =>[$fieldFrontendClass => true , 
                'required-entry' => $fieldRequiredClass],
            'sortOrder' => 250,
             'options' =>  $allOptions,  
            'id' => $attributeCode
        ];

        }
        }
        elseif ($fieldInput == 'multiselect') {
           $fieldInputType = 'input'; 
           $fieldAbstract =  'abstract';

        $attributeId = $attribute->getAttributeId();
        $objectManager = MagentoFrameworkAppObjectManager::getInstance();

        $attributeOptionAll = $objectManager->create(MagentoEavModelResourceModelEntityAttributeOptionCollection::class)
                                    ->setPositionOrder('asc')
                                    ->setAttributeFilter($attributeId)
                                    ->setStoreFilter()
                                    ->load();
        $opt_val = array();
        $allOptions=array();


        foreach ($attributeOptionAll->getData() as $key => $v) 
        {
          // $allid = $v['attribute_id'];
          $opt_val['value'] = $v['option_id'];
          $opt_val['label'] = $v['value'];
          $allOptions[] = $opt_val;
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children'][$attributeCode] = [
            'component' => 'Magento_Ui/js/form/element/'.$fieldAbstract.'',
            'config' => [
                'customScope' => 'shippingAddress.custom_attributes',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/'.$fieldInputType.'',
                'id' => $attributeCode
            ],
            'dataScope' => 'shippingAddress.custom_attributes.'.$attributeCode.'',
            'label' => $frontEndLabel,
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' =>[$fieldFrontendClass => true , 
                'required-entry' => $fieldRequiredClass],
            'sortOrder' => 250,
             // 'options' =>  $allOptions,  
            'id' => $attributeCode
        ];

        }
        }
        elseif ($fieldInput == 'boolean') {
           $fieldInputType = 'select'; 
           $fieldAbstract =  'select';
           $allOptions = [
                 ['value' => '0', 'label' => 'No'],
                 ['value' => '1', 'label' => 'Yes']
               ];
           $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children'][$attributeCode] = [
            'component' => 'Magento_Ui/js/form/element/'.$fieldAbstract.'',
            'config' => [
                'customScope' => 'shippingAddress.custom_attributes',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/'.$fieldInputType.'',
                'id' => $attributeCode
            ],
            'dataScope' => 'shippingAddress.custom_attributes.'.$attributeCode.'',
            'label' => $frontEndLabel,
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' =>[$fieldFrontendClass => true, 
                'required-entry' => $fieldRequiredClass],
            'sortOrder' => 250,
             'options' =>  $allOptions,  
            'id' => $attributeCode
        ];

        }
         elseif ($fieldInput == 'textarea') {
           $fieldInputType = 'textarea'; 
           $fieldAbstract =  'abstract';
           $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children'][$attributeCode] = [
            'component' => 'Magento_Ui/js/form/element/'.$fieldAbstract.'',
            'config' => [
                'customScope' => 'shippingAddress.custom_attributes',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/'.$fieldInputType.'',
                'id' => $attributeCode
            ],
            'dataScope' => 'shippingAddress.custom_attributes.'.$attributeCode.'',
            'label' => $frontEndLabel,
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' =>[$fieldFrontendClass => true, 
                'required-entry' => $fieldRequiredClass],
            'sortOrder' => 250,
            'id' => $attributeCode
        ];

        }



       }
      }
     }
     return $jsLayout;  
    }


}

image:

enter image description here


Get this bounty!!!