7

I'm doing Custom Checkout, and here is what i've done til now. enter image description here

The adea is to use validate so when i click on "Next" button, it gonna check if the checkbox in "Terms of Use", if its checked, then it free to go, but if its not, a validate message will appear.

Here is my code, i've push to github so you guys can easily to watch and re-procedure:
https://github.com/saxsax1995/MagentoCheckoutCustom

So i've follow devdoc and mageplaza
https://devdocs.magento.com/guides/v2.2/howdoi/checkout/checkout_carrier.html https://www.mageplaza.com/custom-shipping-carrier-validator-magento-2.html
But it still doesn't work.

I've try to console.log() in C:\xampp\htdocs\magento\app\code\Aht\MagentoCheckoutCustom\view\frontend\web\js\view\custom-validation.js but it doesn't run to it.
Do i missing something here? I think i've do everything the devdoc and mageplaza said.

So here is my code:

C:\xampp\htdocs\magento\app\code\Aht\MagentoCheckoutCustom\view\frontend\layout\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">
    <head>
        <css src="Aht_MagentoCheckoutCustom/css/style.css"/>
        <!--<script src="Aht_MagentoCheckoutCustom::js/custom-validator.js"></script>-->
    </head>
    <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="step-config" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="shipping-rates-validation" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="custom-validator" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Aht_MagentoCheckoutCustom/js/view/custom-validation</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                                <item name="shippingAddress" xsi:type="array">
                                                    <!--<item name="config" xsi:type="array">-->
                                                        <!--<item name="template" xsi:type="string">Aht_MagentoCheckoutCustom/custom-shipping</item>-->
                                                    <!--</item>-->
                                                    <item name="children" xsi:type="array">
                                                        <item name="shipping-address-fieldset" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="delivery-group" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Aht_MagentoCheckoutCustom/js/view/custom-shipping</item>
                                                                    <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                    <item name="sortOrder" xsi:type="string">150</item>
                                                                    <item name="children" xsi:type="array">
                                                                        <item name="delivery-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>
                                                                            <item name="displayArea" xsi:type="string">delivery-fieldsets</item>
                                                                            <item name="children" xsi:type="array">
                                                                                <item name="delivery_instruction" 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">deliveryForm</item>
                                                                                        <item name="template" xsi:type="string">ui/form/field</item>
                                                                                        <item name="elementTmpl" xsi:type="string">ui/form/element/input</item>
                                                                                    </item>
                                                                                    <!-- value element allows to specify default value of the form field -->
                                                                                    <!--<item name="value" xsi:type="string">Yout value here</item>-->
                                                                                    <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                                    <item name="dataScope" xsi:type="string">deliveryForm.delivery_instruction</item>
                                                                                    <item name="label" xsi:type="string">Delivery Instruction:</item>
                                                                                    <item name="sortOrder" xsi:type="string">1</item>
                                                                                </item>
                                                                                <item name="delivery_type" 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">deliveryForm</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">Delivery Type 1</item>
                                                                                            <item name="value" xsi:type="string">delivery_type_1</item>
                                                                                        </item>
                                                                                        <item name="1" xsi:type="array">
                                                                                            <item name="label" xsi:type="string">Delivery Type 2</item>
                                                                                            <item name="value" xsi:type="string">delivery_type_2</item>
                                                                                        </item>
                                                                                        <item name="2" xsi:type="array">
                                                                                            <item name="label" xsi:type="string">Delivery Type 3</item>
                                                                                            <item name="value" xsi:type="string">delivery_type_3</item>
                                                                                        </item>
                                                                                    </item>
                                                                                    <!-- value element allows to specify default value of the form field -->
                                                                                    <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                                    <item name="dataScope" xsi:type="string">deliveryForm.delivery_type</item>
                                                                                    <item name="label" xsi:type="string">Delivery Type:</item>
                                                                                    <item name="sortOrder" xsi:type="string">2</item>
                                                                                </item>
                                                                                <item name="term_of_use" 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">deliveryForm</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">deliveryForm.term_of_use</item>
                                                                                    <item name="description" xsi:type="string">I accept the Terms of Use and Privacy Policy
                                                                                        Sorry, you must accept our Terms of Use and our Privacy Policy before placing your order</item>
                                                                                    <item name="sortOrder" xsi:type="string">3</item>
                                                                                </item>
                                                                            </item>
                                                                        </item>
                                                                    </item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

C:\xampp\htdocs\magento\app\code\Aht\MagentoCheckoutCustom\view\frontend\web\js\model\custom-shipping-rates-validation-rules.js

define(
    [],
    function () {
        'use strict';
        return {
            getRules: function() {
                return {
                    'term_of_use': {
                        'required': true
                    }
                };
            }
        };
    }
)

C:\xampp\htdocs\magento\app\code\Aht\MagentoCheckoutCustom\view\frontend\web\js\model\custom-validator.js

define(
    [
        'jquery',
        'mageUtils',

        './custom-shipping-rates-validation-rules',
        'mage/translate'
    ],
    function ($, utils, validationRules, $t) {
        'use strict';
        return {
            validationErrors: [],
            validate: function (address) {
                var self = this;
                this.validationErrors = [];
                $.each(validationRules.getRules(), function (field, rule) {
                    if (rule.required && utils.isEmpty(address[field])) {
                        var message = $t('Field ') + field + $t(' is required.');
                        self.validationErrors.push(message);
                    }
                });
                return !Boolean(this.validationErrors.length);
            }
        };
    });

C:\xampp\htdocs\magento\app\code\Aht\MagentoCheckoutCustom\view\frontend\web\js\view\custom-validation.js

define(
    [
        'uiComponent',
        'Magento_Checkout/js/model/shipping-rates-validator',
        'Magento_Checkout/js/model/shipping-rates-validation-rules',
        'Aht_MagentoCheckoutCustom/js/model/custom-validator',
        'Aht_MagentoCheckoutCustom/js/model/custom-shipping-rates-validation-rules'
    ],
    function (Component,
              defaultShippingRatesValidator,
              defaultShippingRatesValidationRules,
              shippingRatesValidator,
              shippingRatesValidationRules)
    {
        'use strict';
        console.log('123');
        defaultShippingRatesValidator.registerValidator('custom-validator', shippingRatesValidator);
        defaultShippingRatesValidationRules.registerRules('custom-shipping-rates-validation-rules', shippingRatesValidationRules);
        return Component;
    }
);



In the source, it doesn't even called in my module.
Here is description image: enter image description here


Please give advice, thanks for reading :)

EDIT 1:
After few days looking for solution, look like custom validate for shipping address doesn't work this way.
I've found another solution, follow the submit form event when we click "Next" in setShippingInformation -> validateShippingInformation function in shipping.js enter image description here

C:\xampp\htdocs\magento\pub\static\frontend\Magento\luma\en_US\Magento_Checkout\js\view\shipping.js


What i'm trying to do is validate the "term of use", and then show validate message after it. Right now, it console.log correctly when i click on "Next" button, but doesn't show correct message. Its always show "false" just like my description image.
So here is what i've done. (i've updated on github if you guys want to see the module)

C:\xampp\htdocs\magento\app\code\Aht\MagentoCheckoutCustom\view\frontend\web\js\view\shipping.js

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

    return function (Target) {
        return Target.extend({
            errorDeliveryValidationMessage: ko.observable(false),
            validateShippingInformation: function () {
                this._super();
                if($('[name="term_of_use"]:checked').length > 0) {
                    console.log('1');
                    return true;
                }
                console.log('2');
                this.errorDeliveryValidationMessage('Please agree our term of use.');
                return false;
            }
        });
    }
});

C:\xampp\htdocs\magento\app\code\Aht\MagentoCheckoutCustom\view\frontend\requirejs-config.js

var config = {
    map: {
        '*': {
            'Magento_Checkout/js/model/shipping-save-processor/default': 'Aht_MagentoCheckoutCustom/js/model/shipping-save-processor/default'
        }
    }
    ,
    'config': {
        'mixins': {
            'Magento_Checkout/js/view/shipping': {
                'Aht_MagentoCheckoutCustom/js/view/shipping': true
            }
        }
    }
};

C:\xampp\htdocs\magento\pub\static\frontend\Magento\luma\en_US\Aht_MagentoCheckoutCustom\template\shipping-delivery\delivery-form.html

<form class="form form-shipping-delivery" id="co-shipping-delivery-form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
    <div id="shipping-delivery" class="fieldset delivery">
        <!-- ko foreach: getRegion('delivery-fieldsets') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
        <!--/ko-->
    </div>
</form>
<div role="alert" class="message notice">
    <span text="errorDeliveryValidationMessage()" />
</div>
0

You can try something like this , add this in your layout 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" 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="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="payments-list" xsi:type="array">
                                                        <item name="children" xsi:type="array">
                                                            <item name="before-place-order" xsi:type="array">
                                                                <item name="children" xsi:type="array">
                                                                    <item name="agreements" xsi:type="array">
                                                                        <item name="component" xsi:type="string">Aht_MagentoCheckoutCustom/js/view/custom-js</item>
                                                                        <item name="sortOrder" xsi:type="string">100</item>
                                                                        <item name="displayArea" xsi:type="string">before-place-order</item>
                                                                        <item name="dataScope" xsi:type="string">checkoutAgreements</item>
                                                                        <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                    </item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </item>
            </argument>
        </arguments>
    </referenceBlock>
</body>

in Aht\MagentoCheckoutCustom\view\frontend\web\js\view\custom-js.js

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

 define([
'ko',
'jquery',
'uiComponent',
'Magento_CheckoutAgreements/js/model/agreements-modal'
], function (ko, $, Component, agreementsModal) {
//put the logic here
});
  • Unfortunately, Its doesn't work :( Do you have any other solutions? – fudu Sep 20 '18 at 1:40
  • I think my problems here is the "click event" doesn't work, i've use deps:[ 'Aht_MagentoCheckoutCustom/js/custom-js' ] in requirejs-config.js so it can import to every page in magento 2, and console.log works. But the click event doesn't work. – fudu Sep 20 '18 at 2:08
  • I've follow this post magento.stackexchange.com/questions/131056/… – fudu Sep 20 '18 at 2:10
  • Seem like it call only at loading page maybe ? – fudu Sep 20 '18 at 2:13
  • I've edit the post, please check :) – fudu Sep 22 '18 at 8:42
0

You can use magento-init for init and load your custom Js component. As following:

Step 1: remove js extension in requirejs-config.js

var config = {
    map: {
        '*': {
            //customJS doesn't work because no where need to use that customJS.
            customJs : 'Aht_MagentoCheckoutCustom/js/custom-js',
            'Magento_Checkout/js/model/shipping-save-processor/default': 'Aht_MagentoCheckoutCustom/js/model/shipping-save-processor/default'
        }
    }
};

Step 2: Add template file (use for init js file) to checkout_index_index.xml layout.

<referenceContainer name="content">
    <block class="Magento\Framework\View\Element\Template" name="custom-js" template="Aht_MagentoCheckoutCustom::js.phtml" after="-"/>
</referenceContainer>

And remove import js on head

<script src="Aht_MagentoCheckoutCustom::js/custom-js.js"></script>

Step 3: create js.phtml in view/frontend/templates and put content

<script type="text/x-magento-init">
    {
        "*":{
            "customJs":{}
        }
    }
</script>

Step 4: change content of your js file (custom-js.js).

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

    $.fn.customJs = function(options) {
        console.log('1234');
    };

    return true;
});
  • wait, can we use <referenceContainer name="content"> to create our new block and template ? I mean its already used? – fudu Sep 21 '18 at 2:55
  • Add to checkout_index_index.xml . Example gist.github.com/bangnguyen47/… – bang.nguyen47 Sep 21 '18 at 3:00
  • I've try your solution, it does work, but still, my checkout page still not working. Just like my old way... :( Both solution still doesn't work on checkout page (first step). – fudu Sep 22 '18 at 3:18
  • I've edit the post, please check :) – fudu Sep 22 '18 at 8:42
  • I've edit the post, please check :) EDIT 1 – fudu Sep 27 '18 at 14:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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