cancel
Showing results for 
Search instead for 
Did you mean: 

Add a back button to the payment step in checkout

SOLVED

Re: Add a back button to payment.html in module

Re: Add a back button to payment.html in module

Hello @SannNL

 

you need to put code into 

module-checkout\view\frontend\web\js\view\payment\default.js

 

If work then marks as solution.


Problem solved? Click Kudos & Accept as Solution!
Sunil Patel
Magento 2 Certified Professional Developer & Frontend Developer

Re: Add a back button to payment.html in module

Ahh that explains a lot haha.

 

But i'm a bit confused now. I still get the same error and now i have the following files:

 

Vendor/Module/view/frontend/web/js/view/payment/default.js

 

define([
    'ko',
    'jquery',
    'uiComponent',
    'Magento_Checkout/js/action/place-order',
    'Magento_Checkout/js/action/select-payment-method',
    'Magento_Checkout/js/model/quote',
    'Magento_Customer/js/model/customer',
    'Magento_Checkout/js/model/payment-service',
    'Magento_Checkout/js/checkout-data',
    'Magento_Checkout/js/model/checkout-data-resolver',
    'uiRegistry',
    'Magento_Checkout/js/model/payment/additional-validators',
    'Magento_Ui/js/model/messages',
    'uiLayout',
    'Magento_Checkout/js/action/redirect-on-success',
    'Magento_Checkout/js/model/step-navigator'
], function (
    ko,
    $,
    Component,
    placeOrderAction,
    selectPaymentMethodAction,
    quote,
    customer,
    paymentService,
    checkoutData,
    checkoutDataResolver,
    registry,
    additionalValidators,
    Messages,
    layout,
    redirectOnSuccessAction,
    stepNavigator
) {
    'use strict';

    return Component.extend({
        redirectAfterPlaceOrder: true,
        isPlaceOrderActionAllowed: ko.observable(quote.billingAddress() != null),

        /**
         * After place order callback
         */
        afterPlaceOrder: function () {
            // Override this function and put after place order logic here
        },

        /**
         * Initialize view.
         *
         * @return {exports}
         */
        initialize: function () {
            var billingAddressCode,
                billingAddressData,
                defaultAddressData;

            this._super().initChildren();
            quote.billingAddress.subscribe(function (address) {
                this.isPlaceOrderActionAllowed(address !== null);
            }, this);
            checkoutDataResolver.resolveBillingAddress();

            billingAddressCode = 'billingAddress' + this.getCode();
            registry.async('checkoutProvider')(function (checkoutProvider) {
                defaultAddressData = checkoutProvider.get(billingAddressCode);

                if (defaultAddressData === undefined) {
                    // Skip if payment does not have a billing address form
                    return;
                }
                billingAddressData = checkoutData.getBillingAddressFromData();

                if (billingAddressData) {
                    checkoutProvider.set(
                        billingAddressCode,
                        $.extend(true, {}, defaultAddressData, billingAddressData)
                    );
                }
                checkoutProvider.on(billingAddressCode, function (providerBillingAddressData) {
                    checkoutData.setBillingAddressFromData(providerBillingAddressData);
                }, billingAddressCode);
            });

            return this;
        },

        /**
         * Initialize child elements
         *
         * @returns {Component} Chainable.
         */
        initChildren: function () {
            this.messageContainer = new Messages();
            this.createMessagesComponent();

            return this;
        },

        /**
         * Create child message renderer component
         *
         * @returns {Component} Chainable.
         */
        createMessagesComponent: function () {

            var messagesComponent = {
                parent: this.name,
                name: this.name + '.messages',
                displayArea: 'messages',
                component: 'Magento_Ui/js/view/messages',
                config: {
                    messageContainer: this.messageContainer
                }
            };

            layout([messagesComponent]);

            return this;
        },

        /**
         * Place order.
         */
        placeOrder: function (data, event) {
            var self = this;

            if (event) {
                event.preventDefault();
            }

            if (this.validate() && additionalValidators.validate()) {
                this.isPlaceOrderActionAllowed(false);

                this.getPlaceOrderDeferredObject()
                    .fail(
                        function () {
                            self.isPlaceOrderActionAllowed(true);
                        }
                    ).done(
                        function () {
                            self.afterPlaceOrder();

                            if (self.redirectAfterPlaceOrder) {
                                redirectOnSuccessAction.execute();
                            }
                        }
                    );

                return true;
            }

            return false;
        },

        /**
         * @return {*}
         */
        getPlaceOrderDeferredObject: function () {
            return $.when(
                placeOrderAction(this.getData(), this.messageContainer)
            );
        },

        /**
         * @return {Boolean}
         */
        selectPaymentMethod: function () {
            selectPaymentMethodAction(this.getData());
            checkoutData.setSelectedPaymentMethod(this.item.method);

            return true;
        },

        isChecked: ko.computed(function () {
            return quote.paymentMethod() ? quote.paymentMethod().method : null;
        }),

        isRadioButtonVisible: ko.computed(function () {
            return paymentService.getAvailablePaymentMethods().length !== 1;
        }),

        /**
         * Get payment method data
         */
        getData: function () {
            return {
                'method': this.item.method,
                'po_number': null,
                'additional_data': null
            };
        },

        /**
         * Get payment method type.
         */
        getTitle: function () {
            return this.item.title;
        },

        /**
         * Get payment method code.
         */
        getCode: function () {
            return this.item.method;
        },

        /**
         * @return {Boolean}
         */
        validate: function () {
            return true;
        },

        /**
         * @return {String}
         */
        getBillingAddressFormName: function () {
            return 'billing-address-form-' + this.item.method;
        },

        /**
         * Dispose billing address subscriptions
         */
        disposeSubscriptions: function () {
            // dispose all active subscriptions
            var billingAddressCode = 'billingAddress' + this.getCode();

            registry.async('checkoutProvider')(function (checkoutProvider) {
                checkoutProvider.off(billingAddressCode);
            });
        },

        goToPrevStep:function(){
            stepNavigator.next();
        }
    });
});

Vendor/Module/view/frontend/web/template/payment.html

 

 

<li id="payment" role="presentation" class="checkout-payment-method" data-bind="fadeVisible: isVisible">
    <div id="checkout-step-payment"
         class="step-content"
         data-role="content"
         role="tabpanel"
         aria-hidden="false">
        <!-- ko if: (quoteIsVirtual) -->
            <!-- ko foreach: getRegion('customer-email') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->
        <!--/ko-->
        <form id="co-payment-form" class="form payments" novalidate="novalidate">
            <input data-bind='attr: {value: getFormKey()}' type="hidden" name="form_key"/>
            <fieldset class="fieldset">
                <legend class="legend">
                    <span data-bind="i18n: 'Payment Information'"></span>
                </legend><br />
                <!-- ko foreach: getRegion('beforeMethods') -->
                    <!-- ko template: getTemplate() --><!-- /ko -->
                <!-- /ko -->
                <div id="checkout-payment-method-load" class="opc-payment" data-bind="visible: isPaymentMethodsAvailable">
                    <!-- ko foreach: getRegion('payment-methods-list') -->
                        <!-- ko template: getTemplate() --><!-- /ko -->
                    <!-- /ko -->
                </div>

                <div class="no-quotes-block" data-bind="visible: isPaymentMethodsAvailable() == false">
                    <!-- ko i18n: 'No Payment method available.'--><!-- /ko -->
                </div>
                <!-- ko foreach: getRegion('afterMethods') -->
                    <!-- ko template: getTemplate() --><!-- /ko -->
                <!-- /ko -->

                <div class="back">
                    <a data-bind="click: goToPrevStep($parents[1])"
                       aria-describedby="checkout-back"
                       class="action back">
                        <span data-bind="i18n: '&lt; Back'">< Back</span>
                    </a>
                </div>
            </fieldset>
        </form>
    </div>
</li>

Vendor/Module/view/frontend/web/template/payment/default.html (this doesn't really link to anything?)

 

 

<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<div class="actions-toolbar" id="review-buttons-container">
    <div class="primary">
        <button data-role="review-save" type="submit"
            data-bind="click: placeOrder($parents[1]), attr: {title: $t('Place Order')}"
            class="button action primary checkout"><span data-bind="i18n: 'Place Order'"></span></button>
    </div>
    <div class="secondary">
        <span id="checkout-review-edit-label" data-bind="i18n: 'Forgot an Item?'"></span>
        <a data-bind="attr: {href: $parents[1].cartUrl}"
           aria-describedby="checkout-review-edit-label"
           class="action edit">
            <span data-bind="i18n: 'Edit Your Cart'"></span>
        </a>
    </div>

    <div class="back">
        <a data-bind="click: goToPrevStep(click: goToPrevStep($parents[1]))"
           aria-describedby="checkout-back"
           class="action back">
            <span data-bind="i18n: 'Back'">Back</span>
        </a>
    </div>
</div>

Vendor/Module/view/frontend/requirejs-config.js

 

 

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/view/shipping': {
                'BB_Checkout/js/mixin/shipping-mixin': true
            }
        }
    },
    'map': {
        '*': {
            'Wezz_Postcode/js/view/postcode': 'BB_Checkout/js/view/postcode-overwrite',
            'Magento_Checkout/template/shipping-information/address-renderer/default': 'BB_Checkout/template/shipping-information/address-renderer/default-overwrite',
            'ui/template/form/element/input': 'BB_Checkout/templates/form/element/input-overwrite',
            'ui/template/form/element/email': 'BB_Checkout/templates/form/element/email-overwrite',
            'ui/template/form/element/password': 'BB_Checkout/templates/form/element/password-overwrite',
            'ui/template/form/field': 'BB_Checkout/templates/form/field-overwrite',
            'Magento_Checkout/template/payment': 'BB_Checkout/template/payment',
            'Magento_Checkout/js/view/payment/default.js': 'BB_Checkout/js/view/payment/default.js'
        }
    }
};

Error: Uncaught ReferenceError: Unable to process binding "click: function (){return goToPrevStep($parents[1]) }" Message: goToPrevStep is not defined.

 

Re: Add a back button to payment.html in module

Hello @SannNL

 

Sorry for the late reply

 

Here is final code

<div class="back">
					<a data-bind="click: goToPrevStep"
					   aria-describedby="checkout-back"
					   class="action back">
						<span data-bind="i18n: 'Back'"></span>
					</a>
				</div>

you need to add above code into that payment method phtml where you added form and place order button.

 

Also payment for method you created method-renderer/payment.js 

where payment.js may be your payment js file name

 

in that js file

define(
	[
		'Magento_Checkout/js/view/payment/default',
        'jquery',
        'Magento_Checkout/js/model/quote',
        'Magento_Customer/js/customer-data',
        'Magento_Catalog/js/price-utils',
        'mage/validation',
        'mage/translate',
		'Magento_Checkout/js/model/step-navigator'
	],function (Component, $, quote, customerData, priceUtils,validation,translate,stepnavigator) {

  return Component.extend({
..................
goToPrevStep :function()
			{
				stepnavigator.navigateTo('shipping');
			}
})
};

If it will work then mark as solution.


Problem solved? Click Kudos & Accept as Solution!
Sunil Patel
Magento 2 Certified Professional Developer & Frontend Developer

Re: Add a back button to payment.html in module

Hey,

Have you checked, are you still facing any issue?

Problem solved? Click Kudos & Accept as Solution!
Sunil Patel
Magento 2 Certified Professional Developer & Frontend Developer

Re: Add a back button to payment.html in module

Hello, sorry I had the day of because of kingsdag. I tried your example but i'm unsure on what js file exactly i need to change or extend or anything. Because I keep getting the error that the function is undefined so I definitely have the wrong Js file.

 

Also in Checkout > view > frontend > web > template > payment.html the data-bind i18n:  'Back' doesn't get shown.

Re: Add a back button to payment.html in module

Hello @SannNL

 

can I know for which payment are you doing?


Problem solved? Click Kudos & Accept as Solution!
Sunil Patel
Magento 2 Certified Professional Developer & Frontend Developer

Re: Add a back button to payment.html in module

I'm trying to add it in the button of the payment page, not in one method. Like this:

 

Screen Shot 2018-04-30 at 10.05.54.png

Re: Add a back button to payment.html in module

Hello @SannNL

 

If you want to do for all payment method then you need to edit that related phtml file and js file 

e.g

 

https://github.com/magento/magento2/blob/2.2-develop/app/code/Magento/OfflinePayments/view/frontend/... - here you need to add your button code for back.

 

https://github.com/magento/magento2/blob/2.2-develop/app/code/Magento/OfflinePayments/view/frontend/...

here you need to your back js code, same for all other payment method.

 

Hope it will help you.

 

If it will help you then mark as a solution or give us kudos.


Problem solved? Click Kudos & Accept as Solution!
Sunil Patel
Magento 2 Certified Professional Developer & Frontend Developer

Re: Add a back button to payment.html in module

I ended up extending the xml with a custom component and adding JS to that.

 

checkout_index_index.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <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="billing-step" xsi:type="array">
                                                <item name="children" xsi:type="array">
                                                    <item name="payment" xsi:type="array">
                                                        <item name="children" xsi:type="array">
                                                            <item name="afterMethods" xsi:type="array">

                                                                <item name="children" xsi:type="array">
                                                                    <item name="back-button" xsi:type="array">
                                                                        <item name="sortOrder" xsi:type="string">35</item>
                                                                        <item name="component"  xsi:type="string">uiComponent</item>
                                                                        <item name="config" xsi:type="array">
                                                                            <item name="template" xsi:type="string">BB_Checkout/back-button</item>
                                                                            <item name="component" xsi:type="string">BB_Checkout/js/view/back-button</item>
                                                                        </item>
                                                                    </item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </argument>
                </arguments>
            </referenceBlock>
        </referenceContainer>
    </body>
</page>

back-button.js

define([
    'uiComponent',
    'Magento_Checkout/js/model/step-navigator'
], function (Component, stepNavigator) {
    return Component.extend({
        goToPrevStep: function () {
            stepNavigator.navigateTo('shipping');
        }
    })
});

back-button.html

<div class="back">
    <a data-bind="click: goToPrevStep()"
       aria-describedby="checkout-back"
       class="action back">
        <span data-bind="i18n: '&lt; Back'"></span>
    </a>
</div>

Thanks for the help Smiley Happy