How to save data from a checkout text form












0















I've tried multiple ways and sources of trying to save data in Magento 2.3 and I cannot think of what more I can try to get this working. I'm trying to add a simple textarea and save the data somehow but struggling to find documentation or tutorials that fully explain how to save submitted data at the checkout and why it is saved that way.



It's probably a much simpler fix than I think as I'm somewhat new to Magento, you can find all the files below.



set-shipping-information.js



/*jshint browser:true jquery:true*/
/*global alert*/
define([
'jquery',
'mage/utils/wrapper',
'Magento_Checkout/js/model/quote'
], function ($, wrapper, quote) {
'use strict';

return function (setShippingInformationAction) {

return wrapper.wrap(setShippingInformationAction, function (originalAction) {

let shippingAddress = quote.shippingAddress();

console.log(shippingAddress);
console.log(shippingAddress.customAttributes);

if (shippingAddress['extension_attributes'] === undefined) {
shippingAddress['extension_attributes'] = {};
}

// shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];

// shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];
// pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
return originalAction();
});
};
});


checkout_index_index.xml



<?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-shipping-method-form" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="displayArea" xsi:type="string">before-shipping-method-form</item>
<item name="children" xsi:type="array">


<item name="custom-checkout-form-container" xsi:type="array">
<item name="component" xsi:type="string">KingfisherDirect_Checkout/js/view/delivery-instructions</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">KingfisherDirect_Checkout/delivery-instructions</item>
</item>
<item name="sortOrder" xsi:type="string">3</item>
<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="textarea_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/textarea</item>
</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="dataScope" xsi:type="string">customCheckoutForm.textarea_field</item>
<!--<item name="label" xsi:type="string">Textarea Field</item>-->
<item name="sortOrder" xsi:type="string">1</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">Checkbox Field</item>
<item name="sortOrder" xsi:type="string">2</item>
</item>
</item>
</item>
</item>
</item>



</item>
</item>
</item>
</item>

</item>
</item>

</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>


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="MagentoQuoteApiDataOrderInterface">-->
<!--<attribute code="textarea_field" type="string" />-->
<!--</extension_attributes>-->
<extension_attributes for="MagentoQuoteApiDataAddressInterface">
<attribute code="checkbox_field" type="string" />
</extension_attributes>
</config>


TestProcessor.php



<?php
namespace KingfisherDirectCheckoutBlock;

use MagentoCheckoutBlockCheckoutLayoutProcessorInterface;

class TestProcessor implements LayoutProcessorInterface
{
/**
*
*
* @param array $jsLayout
*
* @return array
*/
public function process($jsLayout)
{
$customAttributeCode = 'checkbox_field';
$customField = [
'component' => 'Magento_Ui/js/form/element/abstract',
'config' => [
// customScope is used to group elements within a single form (e.g. they can be validated separately)
'customScope' => 'shippingAddress.custom_attributes',
'customEntry' => null,
'template' => 'ui/form/field',
'elementTmpl' => 'ui/form/element/input',
'tooltip' => [
'description' => 'this is what the field is for',
],
],
'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
'label' => 'Custom Attribute',
'provider' => 'checkoutProvider',
'sortOrder' => 0,
'validation' => [
'required-entry' => true
],
'options' => ,
'filterBy' => null,
'customEntry' => null,
'visible' => true,
];

$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $customField;

return $jsLayout;
}
}


di.xml



<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="MagentoCheckoutBlockOnepage">
<arguments>
<argument name="layoutProcessors" xsi:type="array">
<item name="test" xsi:type="object">KingfisherDirectCheckoutBlockTestProcessor</item>
</argument>
</arguments>
</type>
</config>









share|improve this question







New contributor




Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

























    0















    I've tried multiple ways and sources of trying to save data in Magento 2.3 and I cannot think of what more I can try to get this working. I'm trying to add a simple textarea and save the data somehow but struggling to find documentation or tutorials that fully explain how to save submitted data at the checkout and why it is saved that way.



    It's probably a much simpler fix than I think as I'm somewhat new to Magento, you can find all the files below.



    set-shipping-information.js



    /*jshint browser:true jquery:true*/
    /*global alert*/
    define([
    'jquery',
    'mage/utils/wrapper',
    'Magento_Checkout/js/model/quote'
    ], function ($, wrapper, quote) {
    'use strict';

    return function (setShippingInformationAction) {

    return wrapper.wrap(setShippingInformationAction, function (originalAction) {

    let shippingAddress = quote.shippingAddress();

    console.log(shippingAddress);
    console.log(shippingAddress.customAttributes);

    if (shippingAddress['extension_attributes'] === undefined) {
    shippingAddress['extension_attributes'] = {};
    }

    // shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];

    // shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];
    // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
    return originalAction();
    });
    };
    });


    checkout_index_index.xml



    <?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-shipping-method-form" xsi:type="array">
    <item name="component" xsi:type="string">uiComponent</item>
    <item name="displayArea" xsi:type="string">before-shipping-method-form</item>
    <item name="children" xsi:type="array">


    <item name="custom-checkout-form-container" xsi:type="array">
    <item name="component" xsi:type="string">KingfisherDirect_Checkout/js/view/delivery-instructions</item>
    <item name="provider" xsi:type="string">checkoutProvider</item>
    <item name="config" xsi:type="array">
    <item name="template" xsi:type="string">KingfisherDirect_Checkout/delivery-instructions</item>
    </item>
    <item name="sortOrder" xsi:type="string">3</item>
    <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="textarea_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/textarea</item>
    </item>
    <item name="provider" xsi:type="string">checkoutProvider</item>
    <item name="dataScope" xsi:type="string">customCheckoutForm.textarea_field</item>
    <!--<item name="label" xsi:type="string">Textarea Field</item>-->
    <item name="sortOrder" xsi:type="string">1</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">Checkbox Field</item>
    <item name="sortOrder" xsi:type="string">2</item>
    </item>
    </item>
    </item>
    </item>
    </item>



    </item>
    </item>
    </item>
    </item>

    </item>
    </item>

    </item>
    </item>
    </item>
    </item>
    </item>
    </argument>
    </arguments>
    </referenceBlock>
    </body>
    </page>


    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="MagentoQuoteApiDataOrderInterface">-->
    <!--<attribute code="textarea_field" type="string" />-->
    <!--</extension_attributes>-->
    <extension_attributes for="MagentoQuoteApiDataAddressInterface">
    <attribute code="checkbox_field" type="string" />
    </extension_attributes>
    </config>


    TestProcessor.php



    <?php
    namespace KingfisherDirectCheckoutBlock;

    use MagentoCheckoutBlockCheckoutLayoutProcessorInterface;

    class TestProcessor implements LayoutProcessorInterface
    {
    /**
    *
    *
    * @param array $jsLayout
    *
    * @return array
    */
    public function process($jsLayout)
    {
    $customAttributeCode = 'checkbox_field';
    $customField = [
    'component' => 'Magento_Ui/js/form/element/abstract',
    'config' => [
    // customScope is used to group elements within a single form (e.g. they can be validated separately)
    'customScope' => 'shippingAddress.custom_attributes',
    'customEntry' => null,
    'template' => 'ui/form/field',
    'elementTmpl' => 'ui/form/element/input',
    'tooltip' => [
    'description' => 'this is what the field is for',
    ],
    ],
    'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
    'label' => 'Custom Attribute',
    'provider' => 'checkoutProvider',
    'sortOrder' => 0,
    'validation' => [
    'required-entry' => true
    ],
    'options' => ,
    'filterBy' => null,
    'customEntry' => null,
    'visible' => true,
    ];

    $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $customField;

    return $jsLayout;
    }
    }


    di.xml



    <?xml version="1.0"?>
    <!--
    /**
    * Copyright © Magento, Inc. All rights reserved.
    * See COPYING.txt for license details.
    */
    -->
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="MagentoCheckoutBlockOnepage">
    <arguments>
    <argument name="layoutProcessors" xsi:type="array">
    <item name="test" xsi:type="object">KingfisherDirectCheckoutBlockTestProcessor</item>
    </argument>
    </arguments>
    </type>
    </config>









    share|improve this question







    New contributor




    Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.























      0












      0








      0








      I've tried multiple ways and sources of trying to save data in Magento 2.3 and I cannot think of what more I can try to get this working. I'm trying to add a simple textarea and save the data somehow but struggling to find documentation or tutorials that fully explain how to save submitted data at the checkout and why it is saved that way.



      It's probably a much simpler fix than I think as I'm somewhat new to Magento, you can find all the files below.



      set-shipping-information.js



      /*jshint browser:true jquery:true*/
      /*global alert*/
      define([
      'jquery',
      'mage/utils/wrapper',
      'Magento_Checkout/js/model/quote'
      ], function ($, wrapper, quote) {
      'use strict';

      return function (setShippingInformationAction) {

      return wrapper.wrap(setShippingInformationAction, function (originalAction) {

      let shippingAddress = quote.shippingAddress();

      console.log(shippingAddress);
      console.log(shippingAddress.customAttributes);

      if (shippingAddress['extension_attributes'] === undefined) {
      shippingAddress['extension_attributes'] = {};
      }

      // shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];

      // shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];
      // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
      return originalAction();
      });
      };
      });


      checkout_index_index.xml



      <?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-shipping-method-form" xsi:type="array">
      <item name="component" xsi:type="string">uiComponent</item>
      <item name="displayArea" xsi:type="string">before-shipping-method-form</item>
      <item name="children" xsi:type="array">


      <item name="custom-checkout-form-container" xsi:type="array">
      <item name="component" xsi:type="string">KingfisherDirect_Checkout/js/view/delivery-instructions</item>
      <item name="provider" xsi:type="string">checkoutProvider</item>
      <item name="config" xsi:type="array">
      <item name="template" xsi:type="string">KingfisherDirect_Checkout/delivery-instructions</item>
      </item>
      <item name="sortOrder" xsi:type="string">3</item>
      <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="textarea_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/textarea</item>
      </item>
      <item name="provider" xsi:type="string">checkoutProvider</item>
      <item name="dataScope" xsi:type="string">customCheckoutForm.textarea_field</item>
      <!--<item name="label" xsi:type="string">Textarea Field</item>-->
      <item name="sortOrder" xsi:type="string">1</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">Checkbox Field</item>
      <item name="sortOrder" xsi:type="string">2</item>
      </item>
      </item>
      </item>
      </item>
      </item>



      </item>
      </item>
      </item>
      </item>

      </item>
      </item>

      </item>
      </item>
      </item>
      </item>
      </item>
      </argument>
      </arguments>
      </referenceBlock>
      </body>
      </page>


      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="MagentoQuoteApiDataOrderInterface">-->
      <!--<attribute code="textarea_field" type="string" />-->
      <!--</extension_attributes>-->
      <extension_attributes for="MagentoQuoteApiDataAddressInterface">
      <attribute code="checkbox_field" type="string" />
      </extension_attributes>
      </config>


      TestProcessor.php



      <?php
      namespace KingfisherDirectCheckoutBlock;

      use MagentoCheckoutBlockCheckoutLayoutProcessorInterface;

      class TestProcessor implements LayoutProcessorInterface
      {
      /**
      *
      *
      * @param array $jsLayout
      *
      * @return array
      */
      public function process($jsLayout)
      {
      $customAttributeCode = 'checkbox_field';
      $customField = [
      'component' => 'Magento_Ui/js/form/element/abstract',
      'config' => [
      // customScope is used to group elements within a single form (e.g. they can be validated separately)
      'customScope' => 'shippingAddress.custom_attributes',
      'customEntry' => null,
      'template' => 'ui/form/field',
      'elementTmpl' => 'ui/form/element/input',
      'tooltip' => [
      'description' => 'this is what the field is for',
      ],
      ],
      'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
      'label' => 'Custom Attribute',
      'provider' => 'checkoutProvider',
      'sortOrder' => 0,
      'validation' => [
      'required-entry' => true
      ],
      'options' => ,
      'filterBy' => null,
      'customEntry' => null,
      'visible' => true,
      ];

      $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $customField;

      return $jsLayout;
      }
      }


      di.xml



      <?xml version="1.0"?>
      <!--
      /**
      * Copyright © Magento, Inc. All rights reserved.
      * See COPYING.txt for license details.
      */
      -->
      <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
      <type name="MagentoCheckoutBlockOnepage">
      <arguments>
      <argument name="layoutProcessors" xsi:type="array">
      <item name="test" xsi:type="object">KingfisherDirectCheckoutBlockTestProcessor</item>
      </argument>
      </arguments>
      </type>
      </config>









      share|improve this question







      New contributor




      Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.












      I've tried multiple ways and sources of trying to save data in Magento 2.3 and I cannot think of what more I can try to get this working. I'm trying to add a simple textarea and save the data somehow but struggling to find documentation or tutorials that fully explain how to save submitted data at the checkout and why it is saved that way.



      It's probably a much simpler fix than I think as I'm somewhat new to Magento, you can find all the files below.



      set-shipping-information.js



      /*jshint browser:true jquery:true*/
      /*global alert*/
      define([
      'jquery',
      'mage/utils/wrapper',
      'Magento_Checkout/js/model/quote'
      ], function ($, wrapper, quote) {
      'use strict';

      return function (setShippingInformationAction) {

      return wrapper.wrap(setShippingInformationAction, function (originalAction) {

      let shippingAddress = quote.shippingAddress();

      console.log(shippingAddress);
      console.log(shippingAddress.customAttributes);

      if (shippingAddress['extension_attributes'] === undefined) {
      shippingAddress['extension_attributes'] = {};
      }

      // shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];

      // shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];
      // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
      return originalAction();
      });
      };
      });


      checkout_index_index.xml



      <?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-shipping-method-form" xsi:type="array">
      <item name="component" xsi:type="string">uiComponent</item>
      <item name="displayArea" xsi:type="string">before-shipping-method-form</item>
      <item name="children" xsi:type="array">


      <item name="custom-checkout-form-container" xsi:type="array">
      <item name="component" xsi:type="string">KingfisherDirect_Checkout/js/view/delivery-instructions</item>
      <item name="provider" xsi:type="string">checkoutProvider</item>
      <item name="config" xsi:type="array">
      <item name="template" xsi:type="string">KingfisherDirect_Checkout/delivery-instructions</item>
      </item>
      <item name="sortOrder" xsi:type="string">3</item>
      <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="textarea_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/textarea</item>
      </item>
      <item name="provider" xsi:type="string">checkoutProvider</item>
      <item name="dataScope" xsi:type="string">customCheckoutForm.textarea_field</item>
      <!--<item name="label" xsi:type="string">Textarea Field</item>-->
      <item name="sortOrder" xsi:type="string">1</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">Checkbox Field</item>
      <item name="sortOrder" xsi:type="string">2</item>
      </item>
      </item>
      </item>
      </item>
      </item>



      </item>
      </item>
      </item>
      </item>

      </item>
      </item>

      </item>
      </item>
      </item>
      </item>
      </item>
      </argument>
      </arguments>
      </referenceBlock>
      </body>
      </page>


      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="MagentoQuoteApiDataOrderInterface">-->
      <!--<attribute code="textarea_field" type="string" />-->
      <!--</extension_attributes>-->
      <extension_attributes for="MagentoQuoteApiDataAddressInterface">
      <attribute code="checkbox_field" type="string" />
      </extension_attributes>
      </config>


      TestProcessor.php



      <?php
      namespace KingfisherDirectCheckoutBlock;

      use MagentoCheckoutBlockCheckoutLayoutProcessorInterface;

      class TestProcessor implements LayoutProcessorInterface
      {
      /**
      *
      *
      * @param array $jsLayout
      *
      * @return array
      */
      public function process($jsLayout)
      {
      $customAttributeCode = 'checkbox_field';
      $customField = [
      'component' => 'Magento_Ui/js/form/element/abstract',
      'config' => [
      // customScope is used to group elements within a single form (e.g. they can be validated separately)
      'customScope' => 'shippingAddress.custom_attributes',
      'customEntry' => null,
      'template' => 'ui/form/field',
      'elementTmpl' => 'ui/form/element/input',
      'tooltip' => [
      'description' => 'this is what the field is for',
      ],
      ],
      'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
      'label' => 'Custom Attribute',
      'provider' => 'checkoutProvider',
      'sortOrder' => 0,
      'validation' => [
      'required-entry' => true
      ],
      'options' => ,
      'filterBy' => null,
      'customEntry' => null,
      'visible' => true,
      ];

      $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $customField;

      return $jsLayout;
      }
      }


      di.xml



      <?xml version="1.0"?>
      <!--
      /**
      * Copyright © Magento, Inc. All rights reserved.
      * See COPYING.txt for license details.
      */
      -->
      <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
      <type name="MagentoCheckoutBlockOnepage">
      <arguments>
      <argument name="layoutProcessors" xsi:type="array">
      <item name="test" xsi:type="object">KingfisherDirectCheckoutBlockTestProcessor</item>
      </argument>
      </arguments>
      </type>
      </config>






      checkout magento2.3






      share|improve this question







      New contributor




      Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked Jan 11 at 14:29









      AdamAdam

      1




      1




      New contributor




      Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          2 Answers
          2






          active

          oldest

          votes


















          0














          Try following way:



          Step 1: SR/MagentoStackExchange/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="MagentoCheckoutBlockCheckoutLayoutProcessor">
          <plugin name="SR_MagentoStackExchange::add_address_field"
          type="SRMagentoStackExchangePluginCheckoutBlockCheckoutLayoutProcessor" sortOrder="1"/>
          </type>
          </config>


          Step 2: SR/MagentoStackExchange/Plugin/Checkout/Block/Checkout/LayoutProcessor.php




          <?php
          namespace SRMagentoStackExchangePluginCheckoutBlockCheckout;

          class LayoutProcessor
          {
          public function afterProcess(
          MagentoCheckoutBlockCheckoutLayoutProcessor $subject,
          $jsLayout
          ) {

          $customAttributeCode = 'custom_field';
          $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
          ['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $this->addNewField($customAttributeCode);
          return $jsLayout;
          }

          private function addNewField($customAttributeCode)
          {

          $customField = [
          'component' => 'Magento_Ui/js/form/element/abstract',
          'config' => [
          // customScope is used to group elements within a single form (e.g. they can be validated separately)
          'customScope' => 'shippingAddress.custom_attributes',
          'customEntry' => null,
          'template' => 'ui/form/field',
          'elementTmpl' => 'ui/form/element/input',
          'tooltip' => [
          'description' => 'this is what the field is for',
          ],
          ],
          'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
          'label' => 'Custom Attribute',
          'provider' => 'checkoutProvider',
          'sortOrder' => 1000,
          'validation' => [
          'required-entry' => false
          ],
          'options' => ,
          'filterBy' => null,
          'customEntry' => null,
          'visible' => true,
          ];

          return $customField;
          }
          }


          Step 3: SR/MagentoStackExchange/view/frontend/requirejs-config.js




          var config = {
          config: {
          mixins: {
          'Magento_Checkout/js/action/set-shipping-information': {
          'SR_MagentoStackExchange/js/action/set-shipping-information-mixin': true
          }
          }
          }
          };


          Step 4: SR/MagentoStackExchange/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) {
          var shippingAddress = quote.shippingAddress();
          if (shippingAddress['extension_attributes'] === undefined) {
          shippingAddress['extension_attributes'] = {};
          }

          $.each(shippingAddress.customAttributes, function(index, item) {
          shippingAddress['extension_attributes'][item.attribute_code] = item.value;
          });

          // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
          return originalAction();
          });
          };
          });


          Step 5: SR/MagentoStackExchange/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="MagentoQuoteApiDataAddressInterface">
          <attribute code="custom_field" type="string" />
          </extension_attributes>
          </config>


          Step 6: SR/MagentoStackExchange/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="MagentoCheckoutModelShippingInformationManagement">
          <plugin name="SR_MagentoStackExchange::ShippingInformationManagement" type="SRMagentoStackExchangePluginCheckoutModelShippingInformationManagement" sortOrder="1"/>
          </type>
          </config>


          Step 7: SR/MagentoStackExchange/Plugin/Checkout/Model/ShippingInformationManagement.php
          You now able to get data for saving. Use before/after/around plugin which suite your requirement.




          <?php
          namespace SRMagentoStackExchangePluginCheckoutModel;

          class ShippingInformationManagement
          {
          /**
          * @param MagentoCheckoutModelShippingInformationManagement $subject
          * @param $cartId
          * @param MagentoCheckoutApiDataShippingInformationInterface $addressInformation
          */
          public function beforeSaveAddressInformation(
          MagentoCheckoutModelShippingInformationManagement $subject,
          $cartId,
          MagentoCheckoutApiDataShippingInformationInterface $addressInformation
          ) {
          $address = $addressInformation->getShippingAddress();
          $extAttributes = $address->getExtensionAttributes();
          error_log(print_r($extAttributes,1));
          }
          }





          share|improve this answer

































            0














            I ended up following the example set in the following Git Repo



            It's a lot of files to add and a lot to take in but I believe it all makes the most sense of anything I've found.



            https://github.com/sbodak/magento2-checkout-custom-form





            share








            New contributor




            Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.




















              Your Answer








              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "479"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });






              Adam is a new contributor. Be nice, and check out our Code of Conduct.










              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f257537%2fhow-to-save-data-from-a-checkout-text-form%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              0














              Try following way:



              Step 1: SR/MagentoStackExchange/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="MagentoCheckoutBlockCheckoutLayoutProcessor">
              <plugin name="SR_MagentoStackExchange::add_address_field"
              type="SRMagentoStackExchangePluginCheckoutBlockCheckoutLayoutProcessor" sortOrder="1"/>
              </type>
              </config>


              Step 2: SR/MagentoStackExchange/Plugin/Checkout/Block/Checkout/LayoutProcessor.php




              <?php
              namespace SRMagentoStackExchangePluginCheckoutBlockCheckout;

              class LayoutProcessor
              {
              public function afterProcess(
              MagentoCheckoutBlockCheckoutLayoutProcessor $subject,
              $jsLayout
              ) {

              $customAttributeCode = 'custom_field';
              $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
              ['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $this->addNewField($customAttributeCode);
              return $jsLayout;
              }

              private function addNewField($customAttributeCode)
              {

              $customField = [
              'component' => 'Magento_Ui/js/form/element/abstract',
              'config' => [
              // customScope is used to group elements within a single form (e.g. they can be validated separately)
              'customScope' => 'shippingAddress.custom_attributes',
              'customEntry' => null,
              'template' => 'ui/form/field',
              'elementTmpl' => 'ui/form/element/input',
              'tooltip' => [
              'description' => 'this is what the field is for',
              ],
              ],
              'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
              'label' => 'Custom Attribute',
              'provider' => 'checkoutProvider',
              'sortOrder' => 1000,
              'validation' => [
              'required-entry' => false
              ],
              'options' => ,
              'filterBy' => null,
              'customEntry' => null,
              'visible' => true,
              ];

              return $customField;
              }
              }


              Step 3: SR/MagentoStackExchange/view/frontend/requirejs-config.js




              var config = {
              config: {
              mixins: {
              'Magento_Checkout/js/action/set-shipping-information': {
              'SR_MagentoStackExchange/js/action/set-shipping-information-mixin': true
              }
              }
              }
              };


              Step 4: SR/MagentoStackExchange/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) {
              var shippingAddress = quote.shippingAddress();
              if (shippingAddress['extension_attributes'] === undefined) {
              shippingAddress['extension_attributes'] = {};
              }

              $.each(shippingAddress.customAttributes, function(index, item) {
              shippingAddress['extension_attributes'][item.attribute_code] = item.value;
              });

              // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
              return originalAction();
              });
              };
              });


              Step 5: SR/MagentoStackExchange/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="MagentoQuoteApiDataAddressInterface">
              <attribute code="custom_field" type="string" />
              </extension_attributes>
              </config>


              Step 6: SR/MagentoStackExchange/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="MagentoCheckoutModelShippingInformationManagement">
              <plugin name="SR_MagentoStackExchange::ShippingInformationManagement" type="SRMagentoStackExchangePluginCheckoutModelShippingInformationManagement" sortOrder="1"/>
              </type>
              </config>


              Step 7: SR/MagentoStackExchange/Plugin/Checkout/Model/ShippingInformationManagement.php
              You now able to get data for saving. Use before/after/around plugin which suite your requirement.




              <?php
              namespace SRMagentoStackExchangePluginCheckoutModel;

              class ShippingInformationManagement
              {
              /**
              * @param MagentoCheckoutModelShippingInformationManagement $subject
              * @param $cartId
              * @param MagentoCheckoutApiDataShippingInformationInterface $addressInformation
              */
              public function beforeSaveAddressInformation(
              MagentoCheckoutModelShippingInformationManagement $subject,
              $cartId,
              MagentoCheckoutApiDataShippingInformationInterface $addressInformation
              ) {
              $address = $addressInformation->getShippingAddress();
              $extAttributes = $address->getExtensionAttributes();
              error_log(print_r($extAttributes,1));
              }
              }





              share|improve this answer






























                0














                Try following way:



                Step 1: SR/MagentoStackExchange/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="MagentoCheckoutBlockCheckoutLayoutProcessor">
                <plugin name="SR_MagentoStackExchange::add_address_field"
                type="SRMagentoStackExchangePluginCheckoutBlockCheckoutLayoutProcessor" sortOrder="1"/>
                </type>
                </config>


                Step 2: SR/MagentoStackExchange/Plugin/Checkout/Block/Checkout/LayoutProcessor.php




                <?php
                namespace SRMagentoStackExchangePluginCheckoutBlockCheckout;

                class LayoutProcessor
                {
                public function afterProcess(
                MagentoCheckoutBlockCheckoutLayoutProcessor $subject,
                $jsLayout
                ) {

                $customAttributeCode = 'custom_field';
                $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                ['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $this->addNewField($customAttributeCode);
                return $jsLayout;
                }

                private function addNewField($customAttributeCode)
                {

                $customField = [
                'component' => 'Magento_Ui/js/form/element/abstract',
                'config' => [
                // customScope is used to group elements within a single form (e.g. they can be validated separately)
                'customScope' => 'shippingAddress.custom_attributes',
                'customEntry' => null,
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/input',
                'tooltip' => [
                'description' => 'this is what the field is for',
                ],
                ],
                'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
                'label' => 'Custom Attribute',
                'provider' => 'checkoutProvider',
                'sortOrder' => 1000,
                'validation' => [
                'required-entry' => false
                ],
                'options' => ,
                'filterBy' => null,
                'customEntry' => null,
                'visible' => true,
                ];

                return $customField;
                }
                }


                Step 3: SR/MagentoStackExchange/view/frontend/requirejs-config.js




                var config = {
                config: {
                mixins: {
                'Magento_Checkout/js/action/set-shipping-information': {
                'SR_MagentoStackExchange/js/action/set-shipping-information-mixin': true
                }
                }
                }
                };


                Step 4: SR/MagentoStackExchange/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) {
                var shippingAddress = quote.shippingAddress();
                if (shippingAddress['extension_attributes'] === undefined) {
                shippingAddress['extension_attributes'] = {};
                }

                $.each(shippingAddress.customAttributes, function(index, item) {
                shippingAddress['extension_attributes'][item.attribute_code] = item.value;
                });

                // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
                return originalAction();
                });
                };
                });


                Step 5: SR/MagentoStackExchange/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="MagentoQuoteApiDataAddressInterface">
                <attribute code="custom_field" type="string" />
                </extension_attributes>
                </config>


                Step 6: SR/MagentoStackExchange/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="MagentoCheckoutModelShippingInformationManagement">
                <plugin name="SR_MagentoStackExchange::ShippingInformationManagement" type="SRMagentoStackExchangePluginCheckoutModelShippingInformationManagement" sortOrder="1"/>
                </type>
                </config>


                Step 7: SR/MagentoStackExchange/Plugin/Checkout/Model/ShippingInformationManagement.php
                You now able to get data for saving. Use before/after/around plugin which suite your requirement.




                <?php
                namespace SRMagentoStackExchangePluginCheckoutModel;

                class ShippingInformationManagement
                {
                /**
                * @param MagentoCheckoutModelShippingInformationManagement $subject
                * @param $cartId
                * @param MagentoCheckoutApiDataShippingInformationInterface $addressInformation
                */
                public function beforeSaveAddressInformation(
                MagentoCheckoutModelShippingInformationManagement $subject,
                $cartId,
                MagentoCheckoutApiDataShippingInformationInterface $addressInformation
                ) {
                $address = $addressInformation->getShippingAddress();
                $extAttributes = $address->getExtensionAttributes();
                error_log(print_r($extAttributes,1));
                }
                }





                share|improve this answer




























                  0












                  0








                  0







                  Try following way:



                  Step 1: SR/MagentoStackExchange/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="MagentoCheckoutBlockCheckoutLayoutProcessor">
                  <plugin name="SR_MagentoStackExchange::add_address_field"
                  type="SRMagentoStackExchangePluginCheckoutBlockCheckoutLayoutProcessor" sortOrder="1"/>
                  </type>
                  </config>


                  Step 2: SR/MagentoStackExchange/Plugin/Checkout/Block/Checkout/LayoutProcessor.php




                  <?php
                  namespace SRMagentoStackExchangePluginCheckoutBlockCheckout;

                  class LayoutProcessor
                  {
                  public function afterProcess(
                  MagentoCheckoutBlockCheckoutLayoutProcessor $subject,
                  $jsLayout
                  ) {

                  $customAttributeCode = 'custom_field';
                  $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                  ['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $this->addNewField($customAttributeCode);
                  return $jsLayout;
                  }

                  private function addNewField($customAttributeCode)
                  {

                  $customField = [
                  'component' => 'Magento_Ui/js/form/element/abstract',
                  'config' => [
                  // customScope is used to group elements within a single form (e.g. they can be validated separately)
                  'customScope' => 'shippingAddress.custom_attributes',
                  'customEntry' => null,
                  'template' => 'ui/form/field',
                  'elementTmpl' => 'ui/form/element/input',
                  'tooltip' => [
                  'description' => 'this is what the field is for',
                  ],
                  ],
                  'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
                  'label' => 'Custom Attribute',
                  'provider' => 'checkoutProvider',
                  'sortOrder' => 1000,
                  'validation' => [
                  'required-entry' => false
                  ],
                  'options' => ,
                  'filterBy' => null,
                  'customEntry' => null,
                  'visible' => true,
                  ];

                  return $customField;
                  }
                  }


                  Step 3: SR/MagentoStackExchange/view/frontend/requirejs-config.js




                  var config = {
                  config: {
                  mixins: {
                  'Magento_Checkout/js/action/set-shipping-information': {
                  'SR_MagentoStackExchange/js/action/set-shipping-information-mixin': true
                  }
                  }
                  }
                  };


                  Step 4: SR/MagentoStackExchange/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) {
                  var shippingAddress = quote.shippingAddress();
                  if (shippingAddress['extension_attributes'] === undefined) {
                  shippingAddress['extension_attributes'] = {};
                  }

                  $.each(shippingAddress.customAttributes, function(index, item) {
                  shippingAddress['extension_attributes'][item.attribute_code] = item.value;
                  });

                  // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
                  return originalAction();
                  });
                  };
                  });


                  Step 5: SR/MagentoStackExchange/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="MagentoQuoteApiDataAddressInterface">
                  <attribute code="custom_field" type="string" />
                  </extension_attributes>
                  </config>


                  Step 6: SR/MagentoStackExchange/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="MagentoCheckoutModelShippingInformationManagement">
                  <plugin name="SR_MagentoStackExchange::ShippingInformationManagement" type="SRMagentoStackExchangePluginCheckoutModelShippingInformationManagement" sortOrder="1"/>
                  </type>
                  </config>


                  Step 7: SR/MagentoStackExchange/Plugin/Checkout/Model/ShippingInformationManagement.php
                  You now able to get data for saving. Use before/after/around plugin which suite your requirement.




                  <?php
                  namespace SRMagentoStackExchangePluginCheckoutModel;

                  class ShippingInformationManagement
                  {
                  /**
                  * @param MagentoCheckoutModelShippingInformationManagement $subject
                  * @param $cartId
                  * @param MagentoCheckoutApiDataShippingInformationInterface $addressInformation
                  */
                  public function beforeSaveAddressInformation(
                  MagentoCheckoutModelShippingInformationManagement $subject,
                  $cartId,
                  MagentoCheckoutApiDataShippingInformationInterface $addressInformation
                  ) {
                  $address = $addressInformation->getShippingAddress();
                  $extAttributes = $address->getExtensionAttributes();
                  error_log(print_r($extAttributes,1));
                  }
                  }





                  share|improve this answer















                  Try following way:



                  Step 1: SR/MagentoStackExchange/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="MagentoCheckoutBlockCheckoutLayoutProcessor">
                  <plugin name="SR_MagentoStackExchange::add_address_field"
                  type="SRMagentoStackExchangePluginCheckoutBlockCheckoutLayoutProcessor" sortOrder="1"/>
                  </type>
                  </config>


                  Step 2: SR/MagentoStackExchange/Plugin/Checkout/Block/Checkout/LayoutProcessor.php




                  <?php
                  namespace SRMagentoStackExchangePluginCheckoutBlockCheckout;

                  class LayoutProcessor
                  {
                  public function afterProcess(
                  MagentoCheckoutBlockCheckoutLayoutProcessor $subject,
                  $jsLayout
                  ) {

                  $customAttributeCode = 'custom_field';
                  $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
                  ['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $this->addNewField($customAttributeCode);
                  return $jsLayout;
                  }

                  private function addNewField($customAttributeCode)
                  {

                  $customField = [
                  'component' => 'Magento_Ui/js/form/element/abstract',
                  'config' => [
                  // customScope is used to group elements within a single form (e.g. they can be validated separately)
                  'customScope' => 'shippingAddress.custom_attributes',
                  'customEntry' => null,
                  'template' => 'ui/form/field',
                  'elementTmpl' => 'ui/form/element/input',
                  'tooltip' => [
                  'description' => 'this is what the field is for',
                  ],
                  ],
                  'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
                  'label' => 'Custom Attribute',
                  'provider' => 'checkoutProvider',
                  'sortOrder' => 1000,
                  'validation' => [
                  'required-entry' => false
                  ],
                  'options' => ,
                  'filterBy' => null,
                  'customEntry' => null,
                  'visible' => true,
                  ];

                  return $customField;
                  }
                  }


                  Step 3: SR/MagentoStackExchange/view/frontend/requirejs-config.js




                  var config = {
                  config: {
                  mixins: {
                  'Magento_Checkout/js/action/set-shipping-information': {
                  'SR_MagentoStackExchange/js/action/set-shipping-information-mixin': true
                  }
                  }
                  }
                  };


                  Step 4: SR/MagentoStackExchange/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) {
                  var shippingAddress = quote.shippingAddress();
                  if (shippingAddress['extension_attributes'] === undefined) {
                  shippingAddress['extension_attributes'] = {};
                  }

                  $.each(shippingAddress.customAttributes, function(index, item) {
                  shippingAddress['extension_attributes'][item.attribute_code] = item.value;
                  });

                  // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
                  return originalAction();
                  });
                  };
                  });


                  Step 5: SR/MagentoStackExchange/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="MagentoQuoteApiDataAddressInterface">
                  <attribute code="custom_field" type="string" />
                  </extension_attributes>
                  </config>


                  Step 6: SR/MagentoStackExchange/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="MagentoCheckoutModelShippingInformationManagement">
                  <plugin name="SR_MagentoStackExchange::ShippingInformationManagement" type="SRMagentoStackExchangePluginCheckoutModelShippingInformationManagement" sortOrder="1"/>
                  </type>
                  </config>


                  Step 7: SR/MagentoStackExchange/Plugin/Checkout/Model/ShippingInformationManagement.php
                  You now able to get data for saving. Use before/after/around plugin which suite your requirement.




                  <?php
                  namespace SRMagentoStackExchangePluginCheckoutModel;

                  class ShippingInformationManagement
                  {
                  /**
                  * @param MagentoCheckoutModelShippingInformationManagement $subject
                  * @param $cartId
                  * @param MagentoCheckoutApiDataShippingInformationInterface $addressInformation
                  */
                  public function beforeSaveAddressInformation(
                  MagentoCheckoutModelShippingInformationManagement $subject,
                  $cartId,
                  MagentoCheckoutApiDataShippingInformationInterface $addressInformation
                  ) {
                  $address = $addressInformation->getShippingAddress();
                  $extAttributes = $address->getExtensionAttributes();
                  error_log(print_r($extAttributes,1));
                  }
                  }






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jan 11 at 16:34

























                  answered Jan 11 at 16:29









                  Sohel RanaSohel Rana

                  20.2k33853




                  20.2k33853

























                      0














                      I ended up following the example set in the following Git Repo



                      It's a lot of files to add and a lot to take in but I believe it all makes the most sense of anything I've found.



                      https://github.com/sbodak/magento2-checkout-custom-form





                      share








                      New contributor




                      Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                      Check out our Code of Conduct.

























                        0














                        I ended up following the example set in the following Git Repo



                        It's a lot of files to add and a lot to take in but I believe it all makes the most sense of anything I've found.



                        https://github.com/sbodak/magento2-checkout-custom-form





                        share








                        New contributor




                        Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                        Check out our Code of Conduct.























                          0












                          0








                          0







                          I ended up following the example set in the following Git Repo



                          It's a lot of files to add and a lot to take in but I believe it all makes the most sense of anything I've found.



                          https://github.com/sbodak/magento2-checkout-custom-form





                          share








                          New contributor




                          Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.










                          I ended up following the example set in the following Git Repo



                          It's a lot of files to add and a lot to take in but I believe it all makes the most sense of anything I've found.



                          https://github.com/sbodak/magento2-checkout-custom-form






                          share








                          New contributor




                          Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.








                          share


                          share






                          New contributor




                          Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.









                          answered 9 mins ago









                          AdamAdam

                          1




                          1




                          New contributor




                          Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.





                          New contributor





                          Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.






                          Adam is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.






















                              Adam is a new contributor. Be nice, and check out our Code of Conduct.










                              draft saved

                              draft discarded


















                              Adam is a new contributor. Be nice, and check out our Code of Conduct.













                              Adam is a new contributor. Be nice, and check out our Code of Conduct.












                              Adam is a new contributor. Be nice, and check out our Code of Conduct.
















                              Thanks for contributing an answer to Magento Stack Exchange!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f257537%2fhow-to-save-data-from-a-checkout-text-form%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Polycentropodidae

                              Magento 2 Error message: Invalid state change requested

                              Paulmy