Saturday, June 15, 2019

Create "Full Name" field in checkout in Magento 2

The idea is to show a "Full Name" and to hide but NOT to remove "First Name" and "Last Name"

1. Create or Edit di.xml

/app/code/CustomVendor/CustomModule/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="Magento\Checkout\Block\Checkout\LayoutProcessor">
    <plugin name="checkout_custom_fields" type="CustomVendor\CustomModule\Plugin\Checkout\Model\LayoutProcessor" sortOrder="1"/>
</type>
</config>


2. Add the LayoutProcessor.php app/code/CustomVendor/CustomModule/Plugin/Checkout/Model/LayoutProcessor.php

 /**
 * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject
 * @param array $jsLayout
 * @return array
 */
public function afterProcess(
    \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
    array  $jsLayout
) {
    $shippingConfiguration = &$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
    ['children']['shippingAddress']['children']['shipping-address-fieldset']['children'];

    $shippingConfiguration = $this->setFullName($shippingConfiguration);

    return $jsLayout;
}

/**
 * Set "Full Name"
 * @param array $shippingConfiguration
 * @return array
 */
private function setFullName(array  $shippingConfiguration){

    $shippingConfiguration['full_name'] = [
        'component' => 'AdditionalProducts_AdditionalProductsModule/js/checkout/abstract',
        'config' => [
            'customScope' => 'shippingAddress',
            'template' => 'ui/form/field',
            'elementTmpl' => 'ui/form/element/input',
            'options' => [],
            'id' => 'full-name'
        ],
        'dataScope' => 'shippingAddress.full_name',
        'label' => __('Full Name'),
        'provider' => 'checkoutProvider',
        'visible' => true,
        'validation' => [
            'required-entry' => true
        ],
        'sortOrder' => 0,
        'id' => 'full-name',
    ];

    $shippingConfiguration = $this->makeTrackableFirstLastName($shippingConfiguration);

    return $shippingConfiguration;
}


/**
 * Track firstName and lastName
 * @param array $shippingConfiguration
 * @return array
 */
private function makeTrackableFirstLastName(array  $shippingConfiguration){
    $shippingConfiguration['firstname']['tracks']['value'] = true;
    $shippingConfiguration['lastname']['tracks']['value'] = true;

    return $shippingConfiguration;
}


3. Add abastract.js 
app/code/CustomVendor/CustomModule//view/frontend/web/js/checkout/abstract.js
define([
    'Magento_Ui/js/form/element/abstract',
    'mage/translate'
], function (AbstractField, $t) {
    'use strict';

    return AbstractField.extend({
        defaults: {
            modules: {
                firstname: '${ $.parentName }.firstname',
                lastname: '${ $.parentName }.lastname',
            }
        },

        hasChanged: function () {
            this._super();
            this.setFirstLastNameFromFullName();
        },

        /**
         * Extract from the 'Full Name' the 'First' and 'Last' Name
         */
        setFirstLastNameFromFullName : function(){
            var fullValue = this.value();
            var lastSpacePos = fullValue.lastIndexOf(" ");
            var nameLimit = 10;
            var lastNameLimit = 10;

            if (lastSpacePos > 0) { // Ignore values with no space character
                if(fullValue.substring(0, lastSpacePos).length < nameLimit){
                    // Update "firstName"
                    this.firstname().value(fullValue.substring(0, lastSpacePos));
                }
                if(fullValue.substring(lastSpacePos + 1).length < lastNameLimit){
                    // Update "lastName"
                    this.lastname().value(fullValue.substring(lastSpacePos + 1));
                }
            }else{
                if(fullValue.length < nameLimit){
                    // Update "firstName"
                    this.firstname().value(fullValue);
                }
            }
        },
    });
});




More Info see in here.

2 comments: