Add a New Input Form to Checkout in Magento 2

Add a New Input Form to Checkout in Magento 2

Customizing Magento 2 checkout is the most sought after topic in the Magento community. Because of its excessive importance, every merchant wants the checkout page to collect all necessary information while at the same time be compact and user friendly.

Customization is the hallmark of Magento. It’s ability to customize almost everything makes it stand out among competitors. When it comes to the checkout page, you can add a new field, a custom template, a new checkout step, a custom payment method, customize the view of an existing checkout step, and do other customizations.

In this article, we will see how to add a new input form to Magento 2 checkout. Such a form can be added to any of the checkout steps: Shipping Information, Review and Payment Information, or custom. Before proceeding to the steps, keep in mind the following.

Switch to developer mode while you do customizations.

Do not edit the default Magento code. Instead, add your customizations in a separate module. For your checkout customization to be applied correctly, your custom module should depend on the Magento_Checkout module.

Quick Solution: Magento 2 Custom Checkout Fields Extension

Step 1: Create the JS implementation of the form UI component

In your /view/frontend/web/js/view/ directory, create a custom-checkout-form.js file implementing the form.
/*global define*/
define([
 'Magento_Ui/js/form/form'
], function(Component) {
 'use strict';
 return Component.extend({
 initialize: function () {
 this._super();
 // component initialization logic
 return this;
 },

 /**
 * Form submit handler
 *
 * This method can have any name.
 */
 onSubmit: function() {
 // trigger form validation
 this.source.set('params.invalid', false);
 this.source.trigger('customCheckoutForm.data.validate');

 // verify that form data is valid
 if (!this.source.get('params.invalid')) {
 // data is retrieved from data provider by value of the customScope property
 var formData = this.source.get('customCheckoutForm');
 // do something with form data
 console.dir(formData);
 }
 }
 });
});

Step 2: Create the HTML template

Add the knockout.js HTML template for the form component under the /view/frontend/web/template directory called custom-checkout-form.html.
<div>
 <form id="custom-checkout-form" class="form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
 <fieldset class="fieldset">
 <legend data-bind="i18n: 'Custom Checkout Form'"></legend>
 <!-- ko foreach: getRegion('custom-checkout-form-fields') -->
 <!-- ko template: getTemplate() --><!-- /ko -->
 <!--/ko-->
 </fieldset>
 <button type="reset">
 <span data-bind="i18n: 'Reset'"></span>
 </button>
 <button type="button" data-bind="click: onSubmit" class="action">
 <span data-bind="i18n: 'Submit'"></span>
 </button>
 </form>
</div>

Step 3: Declare the form in the checkout page layout

Create a checkout_index_index.xml layout update in the /view/frontend/layout/
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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="before-form" xsi:type="array">
               <item name="children" xsi:type="array">
                <item name="custom-checkout-form-container" xsi:type="array">
 <!-- Add this item to configure your js file -->
                 <item name="component" xsi:type="string">VendorName_ModuleName/js/view/custom-checkout-form</item>
                   <item name="config" xsi:type="array">
 <!-- And this to add your html template -->
                    <item name="template" xsi:type="string">VendorName_ModuleName/custom-checkout-form</item>
 </item>
                      <item name="children" xsi:type="array">
 <!-- Here we will add the form fields -->
                  </item>
               </item>
             </item>
            </item>
          </item>
        </item>
       </item>
      </item>
    </item>
   </item>
 </item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>     

Add Static Fields

The following code sample shows the configuration of the custom-checkout-form-container form, defined in the previous step. It contains four fields: a text input, a select, a checkbox, and a date field.
            <item name="custom-checkout-form-container" xsi:type="array">
 ...
             <item name="children" xsi:type="array">
              <item name="custom-checkout-form-fieldset" xsi:type="array">
              <!-- uiComponent is used as a wrapper for form fields (its template will render all children as a list) -->
               <item name="component" xsi:type="string">uiComponent</item>
               <!-- the following display area is used in template (see below) -->
                <item name="displayArea" xsi:type="string">custom-checkout-form-fields</item>
                 <item name="children" xsi:type="array">
                  <item name="text_field" xsi:type="array">
                   <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item>
                    <item name="config" xsi:type="array">
                    <!-- customScope is used to group elements within a single form (e.g. they can be validated separately) -->
                     <item name="customScope" xsi:type="string">customCheckoutForm</item>
                      <item name="template" xsi:type="string">ui/form/field</item>
                       <item name="elementTmpl" xsi:type="string">ui/form/element/input</item>
                 </item>
                        <item name="provider" xsi:type="string">checkoutProvider</item>
                         <item name="dataScope" xsi:type="string">customCheckoutForm.text_field</item>
                          <item name="label" xsi:type="string" translate="true">Text Field</item>
                           <item name="sortOrder" xsi:type="string">1</item>
                            <item name="validation" xsi:type="array">
                             <item name="required-entry" xsi:type="string">true</item>
                     </item>
              </item>
                          <item name="checkbox_field" xsi:type="array">
                           <item name="component" xsi:type="string">Magento_Ui/js/form/element/boolean</item>
                           <item name="config" xsi:type="array">
                           <!--customScope is used to group elements within a single form (e.g. they can be validated separately)-->
                            <item name="customScope" xsi:type="string">customCheckoutForm</item>
                             <item name="template" xsi:type="string">ui/form/field</item>
                              <item name="elementTmpl" xsi:type="string">ui/form/element/checkbox</item>
               </item>
                          <item name="provider" xsi:type="string">checkoutProvider</item>
                           <item name="dataScope" xsi:type="string">customCheckoutForm.checkbox_field</item>
                            <item name="label" xsi:type="string" translate="true">Checkbox Field</item>
                              <item name="sortOrder" xsi:type="string">3</item>
                 </item>
                            <item name="select_field" xsi:type="array">
                             <item name="component" xsi:type="string">Magento_Ui/js/form/element/select</item>
                              <item name="config" xsi:type="array">
                              <!--customScope is used to group elements within a single form (e.g. they can be validated separately)-->
                                <item name="customScope" xsi:type="string">customCheckoutForm</item>
                                  <item name="template" xsi:type="string">ui/form/field</item>
                                   <item name="elementTmpl" xsi:type="string">ui/form/element/select</item>
                  </item>
                                   <item name="options" xsi:type="array">
                                     <item name="0" xsi:type="array">
                                      <item name="label" xsi:type="string" translate="true">Please select value</item>
                                       <item name="value" xsi:type="string"></item>
                   </item>
                                       <item name="1" xsi:type="array">
                                        <item name="label" xsi:type="string" translate="true">Value 1</item>
                                         <item name="value" xsi:type="string">value_1</item>
                     </item>
                                         <item name="2" xsi:type="array">
                                           <item name="label" xsi:type="string" translate="true">Value 2</item>
                                              <item name="value" xsi:type="string">value_2</item>
                          </item>
                    </item>
 <!-- value element allows to specify default value of the form field -->
                               <item name="value" xsi:type="string">value_2</item>
                                 <item name="provider" xsi:type="string">checkoutProvider</item>
                                  <item name="dataScope" xsi:type="string">customCheckoutForm.select_field</item>
                                   <item name="label" xsi:type="string" translate="true">Select Field</item>
                                    <item name="sortOrder" xsi:type="string">2</item>
                   </item>
                                       <item name="date_field" xsi:type="array">
                                        <item name="component" xsi:type="string">Magento_Ui/js/form/element/date</item>
                                          <item name="config" xsi:type="array">
                                            <!--customScope is used to group elements within a single form (e.g. they can be validated separately)-->
                                               <item name="customScope" xsi:type="string">customCheckoutForm</item>
                                                <item name="template" xsi:type="string">ui/form/field</item>
                                                    <item name="elementTmpl" xsi:type="string">ui/form/element/date</item>
                            </item>
                                               <item name="provider" xsi:type="string">checkoutProvider</item>
                                                  <item name="dataScope" xsi:type="string">customCheckoutForm.date_field</item>
                                                     <item name="label" xsi:type="string" translate="true">Date Field</item>
                                                         <item name="validation" xsi:type="array">
                                                            <item name="required-entry" xsi:type="string">true</item>
              </item>
           </item>
        </item>
      </item>
  </item>
 </item>

Now flush cache for the changes to take effect.

The above code samples will add a custom form with four fields in the Shipping Information step.

Feel free to get in touch in case you have any issue in your Magento 2 store.

Recommended Articles: