14

There are 2 Shipping methods and by default no one is selected, user have to manually select one, as a result it say shipping (undefined-undefined). I want that First item should be automatically comes selected if none is selected how this can be done in magento 2

| improve this question | | | | |
22

As i understood from your question is that you want to always have a shipping method selected when someone comes on checkout page.

To achieve this, we need to override a javascript from Magento_Checkout module.

First things first, we need to create a module :

Namespace/Module/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Namespace_Module',
    __DIR__
);

Namespace/Module/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Namespace_Module" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Checkout"/>
        </sequence>
    </module>
</config>

After this, we need to create the requirejs for overriding that js.

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

var config = {
    map: {
        '*': {
            'Magento_Checkout/js/model/checkout-data-resolver': 'Namespace_Module/js/model/checkout-data-resolver'
        }
    }
};

Now we have to copy checkout-data-resolver.js from Magento_Checkout/view/frontend/web/js/model in our module with the same path Namespace_Module/view/frontend/web/js/model

After that, we need to change a condition inside the function resolveShippingRates: function (ratesData)

From:

            ...

            if (ratesData.length == 1) {
                //set shipping rate if we have only one available shipping rate
                selectShippingMethodAction(ratesData[0]);

                return;
            }

            ...

To:

           ...

            if (ratesData.length >= 1) {
                //set shipping rate if we have only one available shipping rate
                selectShippingMethodAction(ratesData[0]);

                return;
            }

            ...

And thats it, all you have to do now is:

  • Activate the module : php bin/magento module:enable Namespace_Module
  • Run a setup upgrade : php bin/magento setup:upgrade
  • Do a static deploy : php bin/magento setup:static-content:deploy
| improve this answer | | | | |
  • If I want to provide option in configuration for which shipping method should be selected then what types of changes in need to do for that? – Indian Jun 1 '17 at 11:07
  • 2
    This is not working properly. It will not working when we fill the form and then when we try to select other shipping method then we are not able to select it. it will select default shipping method again automatically. – Indian Jul 31 '17 at 5:42
  • 1
    I modified this and added the call to selectShippingMethodAction(ratesData[0]); downn a bit lower in the method, after it looks for the already selected methods, so it doesn't override them. – thaddeusmt Jan 9 '18 at 22:04
  • it's working good. But when using onestepcheckout, how can we get the shipping amount to order summary updated as well? it seems the shipping cost in the order summary first get updated when manually clicking on the shipping method – Magento Learner Jun 19 '19 at 12:56
  • This works great, but i would recommend using mixins, scroll a few answers down how to use those and then use the lines from this answer ;) – Sanne Feb 11 at 11:42
8
if (ratesData.length >= 1) {
  //set shipping rate if we have only one available shipping rate
  selectShippingMethodAction(ratesData[0]);

  return;
}

This will make it impossible to select any other shipping option. This solves the issue for me:

if (ratesData.length == 1) {
    //set shipping rate if we have only one available shipping rate;
    selectShippingMethodAction(ratesData[0]);

    return;
}

if (ratesData.length >= 1) {
    //set shipping rate if we have only one available shipping rate
    if(!selectedShippingRate) {
        selectShippingMethodAction(ratesData[0]);
    }
}
| improve this answer | | | | |
  • In which file is this? – Erfan Jan 23 '18 at 4:15
  • @Benjamin, it's working good. But when using onestepcheckout, how can we get the order total updated as well? it seems the shipping cost in the order total is only updated when manually clicking on the shipping method. – Magento Learner Jun 19 '19 at 11:39
  • 1
    This should be the accepted answer – Tailtiu Nov 22 '19 at 7:06
5

There is no need for entire module to achieve this change. You can simple extend the Checkout module and override in in your theme.

  1. Copy the js file checkout-data-resolver.js
    from
    vendor\magento\module-checkout\view\frontend\web\js\model
    to
    app\design\frontend\Namespace\ThemeName\Magento_Checkout\web\js\model.

  2. Locate line with following code:
    if (ratesData.length == 1) {
    and replace it with:
    if (ratesData.length >= 1 && !selectedShippingRate) {

| improve this answer | | | | |
  • 1
    It does not retain the values if the customer has default shipping address pre-populated in the checkout page or the zip code is prepopulated in cart page.is there any way to retain the values in this case? – sahana Mar 18 '19 at 8:59
  • it's working good. But how can we get the shipping amount to order summary updated as well? it seems the shipping cost in the order summary is only updated when manually clicking on the shipping method – Magento Learner Jun 19 '19 at 12:51
  • thanks working fine – Tirth Patel Feb 20 at 12:38
2

What you probably want to do is select the cheapest shipping method by default.

In your module over ride checkout-data-resolver, optionally you might be able to use a mixin instead.

var config = {
    map: {
        '*': {
            'Magento_Checkout/js/model/checkout-data-resolver':'MyModule_Checkout/js/view/checkout-data-resolver'
        }
    }
}

in the resolveShippingRates method modify as below:

        /**
         * @param {Object} ratesData
         */
        resolveShippingRates: function (ratesData) {
            var selectedShippingRate = checkoutData.getSelectedShippingRate(),
                availableRate = false;
            //Added to find the cheapest rate
            var lowestRateId = _.min(_.keys(ratesData), function(k) { return ratesData[k].amount; });

            if (ratesData.length === 1) {
                //set shipping rate if we have only one available shipping rate
                selectShippingMethodAction(ratesData[0]);

                return;
            }

            // added to select the cheapest rate if no method selected

            if(lowestRateId && !selectedShippingRate && ratesData.length > 0) {
                selectShippingMethodAction(ratesData[lowestRateId]);
            }
| improve this answer | | | | |
  • it's working good. But how can we get the shipping amount to order summary updated as well? it seems the shipping cost in the order summary is only updated when manually clicking on the shipping method – Magento Learner Jun 19 '19 at 12:52
  • @MagentoLearner have you got solution to this problem? – user00247 Jul 19 '19 at 7:06
  • @user00247 not yet. if you have a solution please share. – Magento Learner Jul 19 '19 at 11:07
  • @MagentoLearner I am also searching for a solution :( – user00247 Jul 19 '19 at 12:52
2

While the above methods suggest overriding the js functions, I would recommend using mixins to avoid unnecessary code clashes:

In your frontend requirejs-config.js add the following:

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/model/checkout-data-resolver': {
                '{Vendor}/{Module}/model/checkout-data-resolver': true
            }
        }
    }
};

In your checkout-data-resolver.js

define([
    'underscore',
    'mage/utils/wrapper',
    'Magento_Checkout/js/checkout-data',
    'Magento_Checkout/js/action/select-shipping-method',
    'Magento_Checkout/js/action/select-payment-method'
],function (_, wrapper, checkoutData, selectShippingMethodAction) {
    'use strict';

    return function (checkoutDataResolver) {

        var resolveShippingRates = wrapper.wrap(
            checkoutDataResolver.resolveShippingRates,
            function (originalResolveShippingRates, ratesData) {
                // select your shipping method here using the ratesData and selectShippingMethodAction
                return originalResolveShippingRates(ratesData);
            }
        );

        return _.extend(checkoutDataResolver, {
            resolveShippingRates: resolveShippingRates
        });
    };
});

Alternatively, you can download the module here which allows you to select a default shipping and payment method: Default Shipping & Payment Method [M2]

| improve this answer | | | | |
0

Anyone who is using onestepcheckout can try this:

if (ratesData.length >= 1) {
  setTimeout(function(){
     selectShippingMethodAction(ratesData[0]);
  }, 500)
  return;
}

I know it's looking stupid, but for some reason adding that delay really worked for me. Shipping cost is updating itself like this.

| improve this answer | | | | |

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.