1

I'm trying to show a custom checkout step when a product has a boolean attribute that I created. My attribute is showing 'undefined' when I check it with console.log on the step view js. The name of the attribute is 'agendavel'. I'm trying to set isVisible: ko.observable(quote.isVirtual() && quote.agendavel) before registering my step but it is not working. The step is always showing.

Please, HELP !!! Best Regards

Here is my code
File "SW/CheckouDelta/view/frontend/web/js/view/agendamento-step-view.js'

define(
[
    'ko',
    'uiComponent',
    'underscore',
    'Magento_Checkout/js/model/step-navigator', 
    'Magento_Checkout/js/model/quote'
],
function (
    ko,
    Component,
    _,
    stepNavigator, 
    quote
) {
    'use strict'; 

    return Component.extend({
        defaults: {
            template: 'SW_CheckoutDelta/agendamentostep'
        },

        //add here your logic to display step,
        isVisible: ko.observable(quote.isVirtual() && quote.agendavel), 

        /**
        *
        * @returns {*}
        */
        initialize: function () {
            this._super();
            console.log(quote.agendavel); 

            // register your step
            stepNavigator.registerStep(
                //step code will be used as step content id in the component template
                'agendamento_step_code',
                //step alias
                null,
                //step title value
                'Schedule Information',
                //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
                */
                15
            );


            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();
        }
    });
});

file 'SW/CheckoutDelta/view/frontend/web/template/agendamentostep.html'

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

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

    <form data-bind="submit: navigateToNextStep" novalidate="novalidate">
        <div class="actions-toolbar">
            <div class="primary">
                <button data-role="opc-continue" type="submit" class="button action continue primary">
                    <span><!-- ko i18n: 'Next'--><!-- /ko --></span>
                </button>
            </div>
        </div>
    </form>
</div>

file 'SW/CheckoutDelta/view/frontend/layout/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">                                     
                                        <!-- The new step you add -->
                                        <item name="agendamento-step" xsi:type="array">
                                            <item name="component" xsi:type="string">SW_CheckoutDelta/js/view/agendamento-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">2</item>
                                            <item name="children" xsi:type="array">
                                                <!--add here child component declaration for your step-->
                                                <item name="custom-checkout-form-container" xsi:type="array">
                                                    <item name="component" xsi:type="string">SW_CheckoutDelta/js/view/checkout/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">SW_CheckoutDelta/checkout/custom-checkout-form</item>
                                                    </item>
                                                    <item name="children" xsi:type="array">
                                                        <item name="custom-checkout-form-fieldset" xsi:type="array">
                                                            <item name="component" xsi:type="string">uiComponent</item>
                                                            <item name="displayArea" xsi:type="string">custom-checkout-form-fields</item>
                                                            <item name="children" xsi:type="array">

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

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

File 'SW/CheckoutDelta/etc/catalog_attributes.xml'

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/catalog_attributes.xsd">
    <group name="quote_item">
        <attribute name="agendavel"/>
    </group>
</config>

file 'SW/CheckoutDelta/view/frontend/web/js/view/shipping-payment-mixin.js

 define(
     [
         'ko'
     ], function (ko) {
         'use strict';

         var mixin = {

             initialize: function () {
                 this.isVisible = ko.observable(false); // set visible to be initially false to have your step show first
                 this._super();

                 return this;
             }
         };

         return function (target) {
             return target.extend(mixin);
         };
     }
 );

file 'SW/CheckoutDelta/view/base/requirejs-config.js'

 var config = {
    'config': {
        'mixins': {
           'Magento_Checkout/js/view/shipping': {
               'SW_CheckoutDelta/js/view/shipping-payment-mixin': true
           },
           'Magento_Checkout/js/view/payment': {
               'SW_CheckoutDelta/js/view/shipping-payment-mixin': true
           }
       }
    }
 }

1 Answer 1

2

I found how to hide and show the step deppending on te product attribute.

I had to create a function to set isVisible and ALSO I had to put an IF to avoid the stepNavigator to register the step. That way, the step shows only when the attribute 'agendavel' exists and it is set to True. (Also I had to discover how to access my product attribute having the quote, quite difficulty for me, noob in JS).

Here my code 'SW/CheckouDelta/view/frontend/web/js/view/agendamento-step-view.js'

define(
    [
        'ko',
        'uiComponent',
        'underscore',
        'Magento_Checkout/js/model/step-navigator', 
        'Magento_Checkout/js/model/quote'
    ],
    function (
        ko,
        Component,
        _,
        stepNavigator, 
        quote
    ) {
        'use strict'; 

        function showStep() {
            if (((quote.getItems()[0]['product']['agendavel'])!=null) && ((quote.getItems()[0]['product']['agendavel']) == 1)) 
                return true;
            else 
                return false;       
        }

        return Component.extend({
            defaults: {
                template: 'SW_CheckoutDelta/agendamentostep'
            },

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

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

                console.log(((quote.getItems()[0]['product']['agendavel'])!=null)&&(quote.getItems()[0]['product']['agendavel']));

                if (((quote.getItems()[0]['product']['agendavel'])!=null) && (quote.getItems()[0]['product']['agendavel'])==1) {
                    stepNavigator.registerStep(
                        //step code will be used as step content id in the component template
                        'agendamento_step_code',
                        //step alias
                        null,
                        //step title value
                        'Schedule Information',
                        //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
                        */
                        15
                    );
                }

                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();
            }
        });
    }
);

Now, when the attribute is set, my step shows ok.

enter image description here

And it disapears, when the attribute is not set.

enter image description here

Your Answer

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

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