My goal is to overwrite the billing-address.js
component so that I can add some custom bindings to a certain element on the billing-information.html
template.
I figured out that the module-checkout/block/checkout/LayoutProcessor.php
processPaymentConfiguration
method is responsible in initializing the billing-address
js component.
module-checkout/block/checkout/LayoutProcessor.php
/**
* Inject billing address component into every payment component
*
* @param array $configuration list of payment components
* @param array $elements attributes that must be displayed in address form
* @return array
*/
private function processPaymentConfiguration(array &$configuration, array $elements)
{
$output = [];
foreach ($configuration as $paymentGroup => $groupConfig) {
foreach ($groupConfig['methods'] as $paymentCode => $paymentComponent) {
if (empty($paymentComponent['isBillingAddressRequired'])) {
continue;
}
$output[$paymentCode . '-form'] = [
'component' => 'Magento_Checkout/js/view/billing-address',
'displayArea' => 'billing-address-form-' . $paymentCode,
'provider' => 'checkoutProvider',
'deps' => 'checkoutProvider',
'dataScopePrefix' => 'billingAddress' . $paymentCode,
'sortOrder' => 1,
'children' => [
'form-fields' => [
'component' => 'uiComponent',
'displayArea' => 'additional-fieldsets',
'children' => $this->merger->merge(
$elements,
'checkoutProvider',
'billingAddress' . $paymentCode,
[
'country_id' => [
'sortOrder' => 115,
],
'region' => [
'visible' => false,
],
'region_id' => [
'component' => 'Magento_Ui/js/form/element/region',
'config' => [
'template' => 'ui/form/field',
'elementTmpl' => 'ui/form/element/select',
'customEntry' => 'billingAddress' . $paymentCode . '.region',
],
'validation' => [
'validate-select' => true,
],
'filterBy' => [
'target' => '${ $.provider }:${ $.parentScope }.country_id',
'field' => 'country_id',
],
],
'postcode' => [
'component' => 'Magento_Ui/js/form/element/post-code',
'validation' => [
'required-entry' => true,
],
],
'company' => [
'validation' => [
'min_text_length' => 0,
],
],
'fax' => [
'validation' => [
'min_text_length' => 0,
],
],
'telephone' => [
'config' => [
'tooltip' => [
'description' => 'For delivery questions.',
],
],
],
]
),
],
],
];
}
unset($configuration[$paymentGroup]['methods']);
}
return $output;
}
My intention is to overwrite the processPaymentConfiguration
method and redefine the component to point to the component in my custom module. Something along the lines of...
How I want to modify the processPaymentConfiguration
method
/**
* Inject billing address component into every payment component
*
* @param array $configuration list of payment components
* @param array $elements attributes that must be displayed in address form
* @return array
*/
private function processPaymentConfiguration(array &$configuration, array $elements)
{
$output = [];
foreach ($configuration as $paymentGroup => $groupConfig) {
foreach ($groupConfig['methods'] as $paymentCode => $paymentComponent) {
if (empty($paymentComponent['isBillingAddressRequired'])) {
continue;
}
$output[$paymentCode . '-form'] = [
'component' => 'MilkJarCookies_OrderDeliveryDate/js/view/billing-address',
'displayArea' => 'billing-address-form-' . $paymentCode,
'provider' => 'checkoutProvider',
'deps' => 'checkoutProvider',
'dataScopePrefix' => 'billingAddress' . $paymentCode,
'sortOrder' => 1,
'children' => [
'form-fields' => [
'component' => 'uiComponent',
'displayArea' => 'additional-fieldsets',
'children' => $this->merger->merge(
$elements,
'checkoutProvider',
'billingAddress' . $paymentCode,
[
'country_id' => [
'sortOrder' => 115,
],
'region' => [
'visible' => false,
],
'region_id' => [
'component' => 'Magento_Ui/js/form/element/region',
'config' => [
'template' => 'ui/form/field',
'elementTmpl' => 'ui/form/element/select',
'customEntry' => 'billingAddress' . $paymentCode . '.region',
],
'validation' => [
'validate-select' => true,
],
'filterBy' => [
'target' => '${ $.provider }:${ $.parentScope }.country_id',
'field' => 'country_id',
],
],
'postcode' => [
'component' => 'Magento_Ui/js/form/element/post-code',
'validation' => [
'required-entry' => true,
],
],
'company' => [
'validation' => [
'min_text_length' => 0,
],
],
'fax' => [
'validation' => [
'min_text_length' => 0,
],
],
'telephone' => [
'config' => [
'tooltip' => [
'description' => 'For delivery questions.',
],
],
],
]
),
],
],
];
}
unset($configuration[$paymentGroup]['methods']);
}
return $output;
}
Here is the catch... I have already created a LayoutProcessorPlugin
since I needed to introduce new fields into the checkout shipping page.
Contents of my di.xml file
<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="order-delivery-date"
type="MilkJarCookies\OrderDeliveryDate\Block\Plugin\Checkout\LayoutProcessorPlugin" sortOrder="10"/>
</type>
</config>
The LayoutProcessorPlugin.php
below adds a date, time slot and special instructions fields.
MilkJarCookies/OrderDeliveryDate/Block/Plugin/Checkout/LayoutProcessorPlugin.php
namespace MilkJarCookies\OrderDeliveryDate\Block\Plugin\Checkout;
use Bss\OrderDeliveryDate\Block\Plugin\Checkout\LayoutProcessorPlugin as BaseLayoutProcessorPlugin;
class LayoutProcessorPlugin extends BaseLayoutProcessorPlugin
{
protected $_helper;
const DELIVERY_FORM_DISPLAY_AT_SHIPPING_ADDRESS = 0;
const DELIVERY_FORM_DISPLAY_AT_SHIPPING_METHOD = 1;
const DELIVERY_FORM_DISPLAY_AT_REVIEW_PAYMENTS = 2;
public function __construct(
\MilkJarCookies\OrderDeliveryDate\Helper\Data $helper
) {
$this->_helper = $helper;
}
public function afterProcess(
\Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
array $jsLayout
) {
$container = null;
if(!$this->_helper->isEnabled()) return $jsLayout;
if($this->_helper->getDisplayAt() == self::DELIVERY_FORM_DISPLAY_AT_SHIPPING_ADDRESS) {
$container = 'shipping-address-fieldset';
} elseif($this->_helper->getDisplayAt() == self::DELIVERY_FORM_DISPLAY_AT_SHIPPING_METHOD) {
$container = 'before-shipping-method-form';
}
// before place order
if($this->_helper->getDisplayAt() == self::DELIVERY_FORM_DISPLAY_AT_REVIEW_PAYMENTS){
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children']['payments-list']['children']['before-place-order']['children']['shipping_arrival_date'] = [
'component' => 'MilkJarCookies_OrderDeliveryDate/js/form/element/abstract',
'config' => [
'customScope' => 'shippingAddress',
'template' => 'ui/form/field',
'elementTmpl' => 'MilkJarCookies_OrderDeliveryDate/form/element/date',
'options' => [],
// 'disabled' => true,
'id' => 'shipping-arrival-date',
'class' => 'test'
],
'dataScope' => 'shippingAddress.shipping_arrival_date',
'label' => 'Delivery Date',
'provider' => 'checkoutProvider',
'visible' => true,
'validation' => [],
'sortOrder' => 200,
'id' => 'shipping-arrival-date'
];
}else{
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
['shippingAddress']['children'][$container]['children']['shipping_arrival_date'] = [
'component' => 'MilkJarCookies_OrderDeliveryDate/js/form/element/abstract',
'config' => [
'customScope' => 'shippingAddress',
'template' => 'ui/form/field',
'elementTmpl' => 'MilkJarCookies_OrderDeliveryDate/form/element/date',
'options' => [],
// 'disabled' => true,
'id' => 'shipping-arrival-date'
],
'dataScope' => 'shippingAddress.shipping_arrival_date',
'label' => 'Delivery Date',
'provider' => 'checkoutProvider',
'visible' => true,
'validation' => [],
'sortOrder' => 200,
'id' => 'shipping-arrival-date'
];
}
if($this->_helper->getTimeSlot()){
// before place order
if($this->_helper->getDisplayAt() == self::DELIVERY_FORM_DISPLAY_AT_REVIEW_PAYMENTS){
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children']['payments-list']['children']['before-place-order']['children']['delivery_time_slot'] = [
'component' => 'MilkJarCookies_OrderDeliveryDate/js/form/element/select',
'config' => [
'customScope' => 'shippingAddress',
'template' => 'ui/form/field',
'elementTmpl' => 'MilkJarCookies_OrderDeliveryDate/form/element/select',
'id' => 'delivery-time-slot'
],
'caption' => 'Please select delivery time slot',
'dataScope' => 'shippingAddress.delivery_time_slot',
'label' => 'Delivery Time Slot',
'provider' => 'checkoutProvider',
'visible' => true,
'validation' => [],
'options' => $this->_helper->getTimeSlot(),
'sortOrder' => 201,
'id' => 'delivery-time-slot',
];
}else{
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
['shippingAddress']['children'][$container]['children']['delivery_time_slot'] = [
'component' => 'MilkJarCookies_OrderDeliveryDate/js/form/element/select',
'config' => [
'customScope' => 'shippingAddress',
'template' => 'ui/form/field',
'elementTmpl' => 'MilkJarCookies_OrderDeliveryDate/form/element/select',
'id' => 'delivery-time-slot'
],
'caption' => 'Please select delivery time slot',
'dataScope' => 'shippingAddress.delivery_time_slot',
'label' => 'Delivery Time Slot',
'provider' => 'checkoutProvider',
'visible' => true,
'validation' => [],
'options' => $this->_helper->getTimeSlot(),
'sortOrder' => 201,
'id' => 'delivery-time-slot',
];
}
}
// before place order
if($this->_helper->getDisplayAt() == self::DELIVERY_FORM_DISPLAY_AT_REVIEW_PAYMENTS){
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children']['payments-list']['children']['before-place-order']['children']['shipping_arrival_comments'] = [
'component' => 'Magento_Ui/js/form/element/textarea',
'config' => [
'customScope' => 'shippingAddress',
'template' => 'ui/form/field',
'elementTmpl' => 'ui/form/element/textarea',
'id' => 'shipping-arrival-comments',
'rows' => 5
],
'dataScope' => 'shippingAddress.shipping_arrival_comments',
'label' => 'Special Instructions',
'provider' => 'checkoutProvider',
'visible' => true,
'validation' => [],
'sortOrder' => 202,
'id' => 'shipping-arrival-comments'
];
}else{
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
['shippingAddress']['children'][$container]['children']['shipping_arrival_comments'] = [
'component' => 'Magento_Ui/js/form/element/textarea',
'config' => [
'customScope' => 'shippingAddress',
'template' => 'ui/form/field',
'elementTmpl' => 'ui/form/element/textarea',
'id' => 'shipping-arrival-comments',
'rows' => 5
],
'dataScope' => 'shippingAddress.shipping_arrival_comments',
'label' => 'Special Instructions',
'provider' => 'checkoutProvider',
'visible' => true,
'validation' => [],
'sortOrder' => 202,
'id' => 'shipping-arrival-comments'
];
}
return $jsLayout;
}
}
In short: I am not quite sure how I can utilize the LayoutProcessorPlugin
to overwrite the processPaymentConfiguration
method or how to correctly overwrite that method so that I can overwrite the billing-address.js
component.