Create a new custom Module
You can find a lot of tutorials how to create a Magento 2 Module in my previous tutorials or online. I will skip this step for shortness of length of this tutorial. My new module called, ‘Jeff_CustomCheckout’. In this tutorial, I will add a new step for the checkout called, ‘Pharmacy Questions’. In this step, I will create some form fields, input, checkbox, select, and date. The final result should look like:
Page handle file: checkout_index_index.xml
In any custom module, we first create a checkout_index_index.xml handle file in the magento_root/app/code/Jeff/CustomCheckout/view/frontend/layout.
- Jeff_CustomCheckout/js/view/my-step-view
- 3
- uiComponent
- field-group-custom
- Jeff_CustomCheckout/js/view/custom-checkout-form
- checkoutProvider
- Jeff_CustomCheckout/custom-checkout-form
- uiComponent
- custom-checkout-form-fields
- Magento_Ui/js/form/element/abstract
- customCheckoutForm
- ui/form/field
- ui/form/element/input
- checkoutProvider
- customCheckoutForm.text_field
- Text Field
- 1
- true
- Magento_Ui/js/form/element/boolean
- customCheckoutForm
- ui/form/field
- ui/form/element/checkbox
- checkoutProvider
- customCheckoutForm.checkbox_field
- Checkbox Field
- 3
- Magento_Ui/js/form/element/select
- customCheckoutForm
- ui/form/field
- ui/form/element/select
- Please select value
- Value 1
- value_1
- Value 2
- value_2
- value_2
- checkoutProvider
- customCheckoutForm.select_field
- Select Field
- 2
- Jeff_CustomCheckout/form/element/my_form_field
Create a UI Component: Jeff_CustomCheckout/js/view/my-step-view
#app/code/Jeff/CustomCheckout/view/frontend/web/js/view/my-step-view.js define(['ko', 'uiComponent', 'underscore', 'Magento_Checkout/js/model/step-navigator'], function(ko, Component, _, stepNavigator) { return Component.extend({ defaults: { template: 'Jeff_CustomCheckout/mystep' }, isVisible: ko.observable(true), initialize: function() { this._super(); stepNavigator.registerStep( 'step_code', null, 'Pharmacy Questions', this.isVisible, _.bind(this.navigate, this), 5 /* sort order value < 10: before shipping step; sort order value < 20: between shipping and payment steps; sort order value > 20: after payment step */ ); return this; }, navigate: function() { }, navigateToNextStep: function() { stepNavigator.next(); } }); });
Create the template for new UI Component: Jeff_CustomCheckout/mystep
#app/code/Jeff/CustomCheckout/view/frontend/web/template/mystep.html
Create a Plugin for dynamically generating UI components for form fields
#app/code/Jeff/CustomCheckout/Plugin/Checkout/LayoutProcessorPlugin.php 'Magento_Ui/js/form/element/abstract', 'config' => [ 'customScope' => 'customStepFields.input_field', 'template' => 'ui/form/field', 'elementTmpl' => 'ui/form/element/input', 'id' => 'input_custom_field' ], 'dataScope' => 'customStepFields.imnput_field', 'label' => 'Input Field:', 'provider' => 'checkoutProvider', 'visible' => true, 'sortOrder' => 1, 'id' => 'input_field' ]; $jsLayout['components']['checkout']['children']['steps']['children']['my-new-step']['children']['field-group-custom']['children']['custom_checkbox_field'] = [ 'component' => 'Magento_Ui/js/form/element/boolean', 'config' => [ 'customScope' => 'customStepFields.checkbox_field', 'template' => 'ui/form/field', 'elementTmpl' => 'ui/form/element/checkbox', 'id' => 'custom_checkbox_field' ], 'dataScope' => 'customStepFields.checkbox_field', 'label' => 'Checkbox Field:', 'provider' => 'checkoutProvider', 'visible' => true, 'sortOrder' => 2, 'id' => 'checkbox_field' ]; $jsLayout['components']['checkout']['children']['steps']['children']['my-new-step']['children']['field-group-custom']['children']['custom_select_field'] = [ 'component' => 'Magento_Ui/js/form/element/select', 'config' => [ 'customScope' => 'customStepFields.select_field', 'template' => 'ui/form/field', 'elementTmpl' => 'ui/form/element/select', 'id' => 'custom_select_field' ], 'dataScope' => 'customStepFields.select_field', 'label' => 'Select Field:', 'options' => $this->getSelectOptions(), 'caption' => 'please select one', 'provider' => 'checkoutProvider', 'visible' => true, 'sortOrder' => 3, 'id' => 'select_field' ]; $jsLayout['components']['checkout']['children']['steps']['children']['my-new-step']['children']['field-group-custom']['children']['custom_date_field'] = [ 'component' => 'Magento_Ui/js/form/element/date', 'config' => [ 'customScope' => 'customStepFields.date_field', 'template' => 'ui/form/field', 'elementTmpl' => 'ui/form/element/date', 'id' => 'custom_date_field' ], 'dataScope' => 'customStepFields.date_field', 'label' => 'Date Input Field:', 'options' => $this->getOptions(), 'provider' => 'checkoutProvider', 'visible' => true, 'sortOrder' => 4, 'id' => 'date_field' ]; return $jsLayout; } protected function getOptions() { return ['dateFormat' => 'm/d/Y', 'timeFormat' => 'HH:mm', 'showsTime' => true]; } protected function getSelectOptions() { $items = array(); $items[] = ['value' => '1', 'label' => 'First Class']; $items[] = ['value' => '2', 'label' => 'Second Class']; return $items; } }
Hook up the plugin with di.xml
Some images for final results:
The source code can be downloaded at My Github .
If you have any question, please let me know. Enjoy!