Magento – Magento2 – Radio button group on checkout page

checkoutmagento2

On the checkout page I want to add a radio button group with these options:

  • Individual
  • Company

Based on these options additional fields will be show. How can I add a radio button group to the checkout page?

I already created an InstallData.php file that can add fields:

/**
 * Installs DB schema for a module
 *
 * @param ModuleDataSetupInterface $setup
 * @param ModuleContextInterface   $context
 *
 * @return void
 */
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
    $setup->startSetup();

    /** @var CustomerSetup $customerSetup */
    $customerSetup  = $this->customerSetupFactory->create([ 'setup' => $setup ]);

    // Todo: add Radio button group
}

I already inserted other fields with this function, but I cannot find out how to add a radio button group.

Best Answer

This can be accomplished with a layoutproccessor, create it in your 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="namespace_checkout_layout_processor" type="Namespace\Module\Plugin\Block\LayoutProcessor" sortOrder="1"/>
    </type>
</config>

and your layoutprocessor

<?php

namespace Namespace\Module\Plugin\Block;

use Magento\Customer\Model\AttributeMetadataDataProvider;
use Magento\Ui\Component\Form\AttributeMapper;
use Magento\Checkout\Block\Checkout\AttributeMerger;
use Magento\Checkout\Model\Session as CheckoutSession;

class LayoutProcessor
{
    /**
     * @var AttributeMetadataDataProvider
     */
    public $attributeMetadataDataProvider;

    /**
     * @var AttributeMapper
     */
    public $attributeMapper;

    /**
     * @var AttributeMerger
     */
    public $merger;

    /**
     * @var CheckoutSession
     */
    public $checkoutSession;

    /**
     * @var null
     */
    public $quote = null;

    /**
     * LayoutProcessor constructor.
     *
     * @param AttributeMetadataDataProvider $attributeMetadataDataProvider
     * @param AttributeMapper $attributeMapper
     * @param AttributeMerger $merger
     * @param CheckoutSession $checkoutSession
     */
    public function __construct(
        AttributeMetadataDataProvider $attributeMetadataDataProvider,
        AttributeMapper $attributeMapper,
        AttributeMerger $merger,
        CheckoutSession $checkoutSession
    ) {
        $this->attributeMetadataDataProvider = $attributeMetadataDataProvider;
        $this->attributeMapper = $attributeMapper;
        $this->merger = $merger;
        $this->checkoutSession = $checkoutSession;
    }


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

        return $jsLayout;
    }


    protected function getSwitchField()
    {
        $customAttributeCode = 'switch_field';
        $customField = [
            'component' => 'Namespace_Module/js/view/form/element/radio',
            'config' => [
                'customScope' => 'shippingAddress.custom_attributes',
                'customEntry' => null,
                'template' => 'ui/form/field',
                'elementTmpl' => 'Namespace_Module/form/element/radio'
            ],
            'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
            'label' => __('Order Type'),
            'provider' => 'checkoutProvider',
            'sortOrder' => 0,
            'validation' => [
                'required-entry' => false
            ],
            'options' => [],
            'filterBy' => null,
            'customEntry' => null,
            'visible' => true,
        ];

        return $customField;
    }
}

Your Namespace_Module/js/view/form/element/radio.js file:

define([
    'Magento_Ui/js/form/element/abstract',
    'jquery'
], function(Abstract, $) {
    'use strict';

    return Abstract.extend({
        initialize: function () {
            this._super();

            return this;
        },

        /**
         * Handle radio click, return true to check te radio
         */
        click: function(data, event) {
            this.change(event.target.value);

            return true;
        },

        /**
         * Change value of radio
         */
        change: function(value) {
            if (value === 'business') {
                // logic
            } else if (value === 'private') {
                // logic
            }
        }
    });
});

And your Namespace_Module/form/element/radio.html :

<div class="switch-field" afterRender="change('private')">
    <div class="switch">
        <input type="radio" name="order_type" id="radio-private" value="private" checked="checked" data-bind="click: click">
        <label for="radio-private" data-bind="i18n: 'Private'"></label>
    </div>
    <div class="switch">
        <input type="radio" name="order_type" id="radio-business" value="business" data-bind="click: click">
        <label for="radio-business" data-bind="i18n: 'Business'"></label>
    </div>
</div>
Related Topic