4

I actually have two new inputs in my customer address, admin, shipping and billing address, but i want just to show them in the billing address of each payment method, I am trying to hide them via xml but it doesn't works, I have the following code:

My install script:

$customerSetup = $this->_customerSetupFactory->create(['setup' => $setup]);
$attributesInfo = [
        'want_bill' => [
            'label'         => 'Want to bill',
            'input'         => 'checkbox',
            'required'      => 0,
            'sort_order'    => 400,
            'visible'       => true,
            'system'        => 0
        ],
        'rfc'       => [
            'label'         => 'RFC',
            'input'         => 'text',
            'required'      => 0,
            'sort_order'    => 410,
            'visible'       => true,
            'system'        => 0
        ],
];

foreach ($attributesInfo as $attributeCode => $attributeParams) {
    $customerSetup->addAttribute('customer_address', $attributeCode, $attributeParams);
}

foreach ($attributesInfo as $attributeCode => $attributeParams) {
    $customAttribute = $customerSetup->getEavConfig()->getAttribute('customer_address', $attributeCode);
    $customAttribute->setData(
        'used_in_forms',
        ['adminhtml_customer_address', 'customer_address_edit', 'customer_register_address']
    );
    $customAttribute->save();
}

When I run:

bin/magento setup:upgrade

Everything works fine and I can show the inputs in the customer address in admin and also in the shipping and billing address.

I need to delete or hide those inputs from the shipping address form, for that I am trying this:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="shipping-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="shippingAddress" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="shipping-address-fieldset" xsi:type="array">
                                                            <item name="want_bill" xsi:type="array">
                                                                <item name="visible" xsi:type="boolean">false</item>
                                                            </item>
                                                            <item name="rfc" xsi:type="array">
                                                                <item name="visible" xsi:type="boolean">false</item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

But those inputs still showing.

How can I hide them?

2 Answers 2

5

Please check below code to save custom address attribute in customer,checkout shipping and billing form and also save in order table.

Module Name : Ccc_Checkout

Script to create custom attribute for address and order

app/code/Ccc/Checkout/Setup/UpgradeData.php

<?php
namespace Ccc\Checkout\Setup;

use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Eav\Model\Config;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;

class UpgradeData implements UpgradeDataInterface
{

    private $eavSetupFactory;

    /**
     * @var Config
     */
    private $eavConfig;

    /**
     * @var AttributeSetFactory
     */
    private $attributeSetFactory;

    public function __construct(
        Config $eavConfig,
        EavSetupFactory $eavSetupFactory,
        AttributeSetFactory $attributeSetFactory
    )
    {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->eavConfig            = $eavConfig;
        $this->attributeSetFactory  = $attributeSetFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function upgrade(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $setup->startSetup();
        if (version_compare($context->getVersion(), '0.0.2','<')) { 
            $this->addUnitNumberFieldToAddress($setup);
        }
        if (version_compare($context->getVersion(), '0.0.3','<')) { 
            $this->updateUnitAttribute($setup);
        }
        $setup->endSetup();


    }

    /**
    * put your comment there...
    * 
    * @param mixed $setup
    */
    protected function addUnitNumberFieldToAddress($setup)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
        $eavSetup->addAttribute('customer_address', 'unit_number', [
            'type' => 'varchar',
            'input' => 'text',
            'label' => 'Unit Number',
            'visible' => true,
            'required' => false,
            'user_defined' => true,
            'system'=> false,
            'group'=> 'General',
            'sort_order' => 71,
            'global' => true,
            'visible_on_front' => true,
        ]);       

        $customAttribute = $this->eavConfig->getAttribute('customer_address', 'unit_number');

        $customAttribute->setData(
            'used_in_forms',
            ['adminhtml_customer_address','customer_address_edit','customer_register_address'] 
        );
        $customAttribute->save();


        $installer = $setup;


        $installer->getConnection()->addColumn(
            $installer->getTable('quote_address'),
            'unit_number',
            [
                'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 
                'length' => 255,
                'comment' => 'Unit Number'
            ]
        );

        $installer->getConnection()->addColumn(
            $installer->getTable('sales_order_address'),
            'unit_number',
            [
                'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 
                'length' => 255,
                'comment' => 'Unit Number'
            ]
        );
    }

    public function updateUnitAttribute($setup)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
        $eavSetup->updateAttribute('customer_address', 'unit_number', 'sort_order', '71');
    }
}

app/code/Ccc/Checkout/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="Magento\Checkout\Block\Checkout\LayoutProcessor">
      <plugin disabled="false" name="BillingLayoutProcessor" sortOrder="99" type="Ccc\Checkout\Plugin\Block\Checkout\LayoutProcessor"/>
  </type>
  <type name="Magento\Quote\Model\BillingAddressManagement">
    <plugin disabled="false" name="Ccc_Checkout_Plugin_Magento_Quote_Model_BillingAddressManagement" sortOrder="10" type="Ccc\Checkout\Plugin\Magento\Quote\Model\BillingAddressManagement"/>
  </type>
  <type name="Magento\Quote\Model\Quote\Address\BillingAddressPersister">
    <plugin disabled="false" name="BillingAddressSave" sortOrder="10" type="Ccc\Checkout\Plugin\Magento\Quote\Model\Quote\Address\BillingAddressPersister"/>
  </type>
  <type name="Magento\Quote\Model\ShippingAddressManagement">
    <plugin disabled="false" name="Ccc_Checkout_Plugin_Magento_Quote_Model_ShippingAddressManagement" sortOrder="10" type="Ccc\Checkout\Plugin\Magento\Quote\Model\ShippingAddressManagement"/>
  </type>
</config>

app/code/Ccc/Checkout/etc/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
     <event name="sales_model_service_quote_submit_success">
        <observer name="custome_address_attribute_save" instance="Ccc\Checkout\Observer\SaveUnitNumberInOrder"/>
    </event>
</config>

app/code/Ccc/Checkout/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="Magento\Quote\Api\Data\AddressInterface">
        <attribute code="unit_number" type="string"/>
    </extension_attributes>
</config>

Create Plugin to display custom attribute in checkout billing and shipping form

app/code/Ccc/Checkout/Plugin/Block/Checkout/LayoutProcessor

<?php
namespace Ccc\Checkout\Plugin\Block\Checkout;
use \Magento\Checkout\Block\Checkout\LayoutProcessor as MageLayoutProcessor;
class LayoutProcessor
{
   protected $_customAttributeCode = 'unit_number';
    public function afterProcess(MageLayoutProcessor $subject, $jsLayout)
    {
        if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
        ['payment']['children']['payments-list']['children'])) 
        {
            foreach ($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['payments-list']['children'] as $key => $payment) 
            {                
                $paymentCode = 'billingAddress'.str_replace('-form','',$key);
                $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']['children']['payments-list']['children'][$key]['children']['form-fields']['children'][$this->_customAttributeCode] = $this->getUnitNumberAttributeForAddress($paymentCode);                
            } 

        }   

         if(isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset'])
        ){
            $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$this->_customAttributeCode] = $this->getUnitNumberAttributeForAddress('shippingAddress');
         }

        return $jsLayout;     
    }   

    public function getUnitNumberAttributeForAddress($addressType)
    {        
        return $customField = [
            'component' => 'Magento_Ui/js/form/element/abstract',
            'config' => [                
                'customScope' => $addressType.'.custom_attributes',
                'customEntry' => null,
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/input'
            ],
            'dataScope' => $addressType.'.custom_attributes' . '.' . $this->_customAttributeCode,
            'label' => 'Unit Number',
            'provider' => 'checkoutProvider',
            'sortOrder' => 71,
            'validation' => [
               'required-entry' => false
            ],
            'options' => [],
            'filterBy' => null,
            'customEntry' => null,
            'visible' => true,
        ];
    }    
}

To save custom attribute in checkout

app/code/Ccc/Checkout/Plugin/Magento/Quote/Model/ShippingAddressManagement

<?php
namespace Ccc\Checkout\Plugin\Magento\Quote\Model;

class ShippingAddressManagement
{
    protected $logger;

    public function __construct(
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->logger = $logger;
    }

    public function beforeAssign(
        \Magento\Quote\Model\ShippingAddressManagement $subject,
        $cartId,
        \Magento\Quote\Api\Data\AddressInterface $address
    ) {

        $extAttributes = $address->getExtensionAttributes();        
        if (!empty($extAttributes)) {
            try {
                $address->setUnitNumber($extAttributes->getUnitNumber());
            } catch (\Exception $e) {
                $this->logger->critical($e->getMessage());
            }
        }
    }
}

app/code/Ccc/Checkout/Plugin/Magento/Quote/Model/BillingAddressManagement

<?php
namespace Ccc\Checkout\Plugin\Magento\Quote\Model;

class BillingAddressManagement
{

    protected $logger;

    public function __construct(
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->logger = $logger;
    }

    public function beforeAssign(
        \Magento\Quote\Model\BillingAddressManagement $subject,
        $cartId,
        \Magento\Quote\Api\Data\AddressInterface $address,
        $useForShipping = false
    ) {

        $extAttributes = $address->getExtensionAttributes();
        if (!empty($extAttributes)) {
            try {
                $address->setUnitNumber($extAttributes->getUnitNumber());
            } catch (\Exception $e) {
                $this->logger->critical($e->getMessage());
            }
        }
    }
}

app/code/Ccc/Checkout/Ccc/Checkout/Plugin/Magento/Quote/Model/Quote/Address

<?php
namespace Ccc\Checkout\Plugin\Magento\Quote\Model\Quote\Address;

class BillingAddressPersister
{

    protected $logger;

    public function __construct(
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->logger = $logger;
    }

    public function beforeSave(
        \Magento\Quote\Model\Quote\Address\BillingAddressPersister $subject,
        $quote,
        \Magento\Quote\Api\Data\AddressInterface $address,
        $useForShipping = false
    ) {

        $extAttributes = $address->getExtensionAttributes();
        if (!empty($extAttributes)) {
            try {
                $address->setUnitNumber($extAttributes->getUnitNumber());
            } catch (\Exception $e) {
                $this->logger->critical($e->getMessage());
            }
        }
    }
}

To set custom attribute in extension attribute

app/code/Ccc/Checkout/view/frontend/requirejs-config.js

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

app/code/Ccc/Checkout/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/Ccc/Checkout/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/Ccc/Checkout/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);
        });
    };
});

To save custom attribute in orders

app/code/Ccc/Checkout/Observer/SaveUnitNumberInOrder.php

<?php
namespace Ccc\Checkout\Observer;

class SaveUnitNumberInOrder implements \Magento\Framework\Event\ObserverInterface
{
    public function execute(\Magento\Framework\Event\Observer $observer) {
        $order = $observer->getEvent()->getOrder();
        $quote = $observer->getEvent()->getQuote();
         if ($quote->getBillingAddress()) {
              $order->getBillingAddress()->setUnitNumber($quote->getBillingAddress()->getExtensionAttributes()->getUnitNumber());
          }
          if (!$quote->isVirtual()) {            
              $order->getShippingAddress()->setUnitNumber($quote->getShippingAddress()->getUnitNumber());
          }
        return $this;
    }
}

To display custom attribute in customer account you need to overright customer edit.phtml file from vendor to your theme like below :

app/design/frontend/custom_theme/theme_name/Magento_Customer/templates/address/edit.phtml

<div class="field unit_number">
            <label class="label" for="unit_number"><span><?php echo $block->escapeHtml(__('Unit Number')) ?></span></label>
            <div class="control">

                <input type="text" name="unit_number" value="<?= $block->escapeHtmlAttr($block->getAddress()->getCustomAttribute('unit_number') ? $block->getAddress()->getCustomAttribute('unit_number')->getValue() : '') ?>" title="<?= $block->escapeHtmlAttr($block->getAddress()->getCustomAttribute('unit_number') ? $block->getAddress()->getCustomAttribute('unit_number')->getValue() : '') ?>" class="input-text <?= $block->escapeHtmlAttr($block->getAddress()->getCustomAttribute('unit_number') ? $block->getAddress()->getCustomAttribute('unit_number')->getValue() : '') ?>" id="unit_number">
            </div>
        </div>
0

Seem your xml config is incorrect. You missed <item name="children" xsi:type="array"> node before your custom field nodes. It should be:

   <?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="checkout.root">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="components" xsi:type="array">
                        <item name="checkout" xsi:type="array">
                            <item name="children" xsi:type="array">
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="shipping-step" xsi:type="array">
                                            <item name="children" xsi:type="array">
                                                <item name="shippingAddress" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="shipping-address-fieldset" xsi:type="array">
                                                            <item name="children" xsi:type="array">  <!-- Missing children node here-->
                                                                <!--Remove fields-->
                                                                <item name="want_bill" xsi:type="array">
                                                                    <item name="visible" xsi:type="boolean">false</item>
                                                                </item>
                                                                <item name="rfc" xsi:type="array">
                                                                    <item name="visible" xsi:type="boolean">false</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Your Answer

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

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