2

I created a module to add a new step to the Magento 2 checkout. This step has a custom form. On submitting the form I can't figure out how to go the the next step.

checkout_index_index.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" 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">
                                    <!-- The new step -->
                                    <item name="my-new-step" xsi:type="array">
                                        <item name="component" xsi:type="string">/BB_CheckoutStep/js/view/my-step-view</item>

                                        <!--To display step content before shipping step "sortOrder" value should be < 1-->
                                        <!--To display step content between shipping step and payment step  1 < "sortOrder" < 2 -->
                                        <!--To display step content after payment step "sortOrder" > 2 -->
                                        <item name="sortOrder" xsi:type="string">0</item>
                                        <item name="children" xsi:type="array">
                                            <!--add here child component-->

                                            <!--start of custom form-->
                                            <item name="custom-checkout-form-container" xsi:type="array">
                                                <item name="component" xsi:type="string">BB_CheckoutStep/js/view/custom-checkout-form</item>
                                                <item name="displayArea" xsi:type="string">custom-checkout-form-container</item>
                                                <item name="provider" xsi:type="string">checkoutProvider</item>
                                                <item name="config" xsi:type="array">
                                                    <item name="template" xsi:type="string">BB_CheckoutStep/custom-checkout-form</item>
                                                </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="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">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">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">Please select value</item>
                                                                        <item name="value" xsi:type="string"></item>
                                                                    </item>
                                                                    <item name="1" xsi:type="array">
                                                                        <item name="label" xsi:type="string">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">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">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">Date Field</item>
                                                                <item name="validation" xsi:type="array">
                                                                    <item name="required-entry" xsi:type="string">true</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>

                                         <!--end of custom form-->

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

my-step-view.js

define(
[
    'ko',
    'uiComponent',
    'underscore',
    'Magento_Checkout/js/model/step-navigator'
],
function (
    ko,
    Component,
    _,
    stepNavigator
) {
    'use strict';
    /**
     *
     * mystep - is the name of the component's .html template,
     * <Vendor>_<Module>  - is the name of the your module directory.
     *
     */
    return Component.extend({
        defaults: {
            template: 'BB_CheckoutStep/mystep'
        },

        //add here your logic to display step,
        isVisible: ko.observable(true),

        /**
         *
         * @returns {*}
         */
        initialize: function () {
            this._super();

            // register your step
            stepNavigator.registerStep(
                //step code will be used as step content id in the component template
                'step_code',
                //step alias
                null,
                //step title value
                'Birthdate',
                //observable property with logic when display step or hide step
                this.isVisible,

                _.bind(this.navigate, this),

                /**
                 * sort order value
                 * 'sort order value' < 10: step displays before shipping step;
                 * 10 < 'sort order value' < 20 : step displays between shipping and payment step
                 * 'sort order value' > 20 : step displays after payment step
                 */
                9
            );

            return this;
        },

        /**
         * The navigate() method is responsible for navigation between checkout step
         * during checkout. You can add custom logic, for example some conditions
         * for switching to your custom step
         */
        navigate: function () {
        },

        /**
         * @returns void
         */
        navigateToNextStep: function () {
            stepNavigator.next();
        }
    });
}
);

mystep.html

<!--The 'step_code' value from the .js file should be used-->

<div id="checkout-step-title"
     class="step-content"
     data-role="content">

    <!-- ko foreach: getRegion('custom-checkout-form-container') -->
    <!-- ko template: getTemplate() --><!-- /ko -->
    <!--/ko-->
</div>

custom-checkout-form.js

/*global define*/
define([
'Magento_Ui/js/form/form',
'Magento_Checkout/js/model/step-navigator'
], 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');
            // stepNavigator.next();
            // do something with form data
            console.dir(formData);
            this.navigateToNextStep();
        }
    }
});
});

custom-checkout-form.html

<div>
<form id="custom-checkout-form" class="form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
    <fieldset class="fieldset">
        <!-- ko foreach: getRegion('custom-checkout-form-fields') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
        <!--/ko-->
    </fieldset>
    <button type="button" data-bind="click: onSubmit" class="action">
        <span data-bind="i18n: 'Submit'"></span>
    </button>
</form>

So i'm trying to use navigateToNextStep() from my-step-view.js in custom-checkout-form but i'm not sure on how to reference that. I also looked into giving parameters to getRegion. I just started working with Magento 2 and KnockoutJS so i'm sorry if it's a bit of a dumb question. I created the new step and custom form by following the Magento 2 Dev Docs. Thanks in advance :)

http://devdocs.magento.com/guides/v2.2/howdoi/checkout/checkout_new_step.html http://devdocs.magento.com/guides/v2.0/howdoi/checkout/checkout_form.html

1 Answer 1

1

I needed to add stepNavigator as a parameter in custom-checkout-form.js.

/*global define*/
define([
  'Magento_Ui/js/form/form',
  'Magento_Checkout/js/model/step-navigator'
], function(Component, stepNavigator) {
'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);
            stepNavigator.next();
        }
    }
  });
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.