0

I have a custom shipping method. By default, the Shipping Methods show 3 columns -

  • Price,
  • Method and
  • Carrier.

I want to add another column that shows the estimated time of delivery.
How can I add the extra column?

I tried adding this to Vendor/Module/Model/Carrier/Rates.php

$method->setCarrier('customCarrier');
$method->setCarrierTitle('customCarrierTitle');
$method->setMethod('customMethod');
$method->setMethodTitle('customMethodTitle');
$method->setData('foo','customValue');

In the template file,

<tr class="row"
   click="element.selectShippingMethod">
   <td class="col col-method">
       <input type="radio"
              class="radio"
              ifnot="method.error_message"
              ko-checked="element.isSelected"
              ko-value="method.carrier_code + '_' + method.method_code"
              attr="'aria-labelledby': 'label_method_' + method.method_code + '_' + method.carrier_code + ' ' + 'label_carrier_' + method.method_code + '_' + method.carrier_code,
                   'checked': element.rates().length == 1 || element.isSelected" />
   </td>
   <td class="col col-price">
       <each args="element.getRegion('price')" render="" />
   </td>
   <td class="col col-method"
       attr="'id': 'label_method_' + method.method_code + '_' + method.carrier_code"
       text="method.method_title" />
   <td class="col col-carrier"
       attr="'id': 'label_carrier_' + method.method_code + '_' + method.carrier_code"
       text="method.carrier_title" />
    <td class="col col-foo"
       attr="'id': 'label_foo_' + method.method_code + '_' + method.carrier_code"
       text="method.foo" />     
</tr>

The extra field 'foo' is not shown.

Thanks!

  • I think this one can help you get started magento.stackexchange.com/questions/92734/… – magefms Apr 18 at 3:02
  • I don't need an additional block, I need an additional column in the same block. How does Magento render the shipping methods? – coderGeek Apr 18 at 15:35
  • you mean you want to display some extra column when your custom shipping is selected? – magefms Apr 21 at 23:09
  • Yes, something like that can also work. – coderGeek Apr 22 at 6:21
  • you can't do that as template file is using ko js to bind data – magefms Apr 23 at 4:19
0

I have done this before by adding an extra field just below my custom shipping method and only display it when my custom shipping method is selected.

Follow this steps:
Create a plugin for the process method, Magento\Checkout\Block\Checkout\LayoutProcessor in the path

app/code/Vendor/Module/Plugin/Checkout/LayoutProcessorPlugin.php

<?php

namespace Vendor\Module\Plugin\Checkout;

use Magento\Checkout\Block\Checkout\LayoutProcessor;

class LayoutProcessorPlugin
{
   /**
    * @param LayoutProcessor $subject
    * @param array $jsLayout
    * @return array
    */
   public function afterProcess(
       LayoutProcessor $subject,
       array $jsLayout
   ) {
       $validation['required-entry'] = false;
       $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
       ['shippingAddress']['children']['custom-shipping-method-fields']['children']['input_custom_shipping_field'] = [
           'component' => "Magento_Ui/js/form/element/abstract",
           'config' => [
               'customScope' => 'customShippingMethodFields',
               'template' => 'ui/form/field',
               'elementTmpl' => "ui/form/element/hidden",
               'id' => "input_custom_shipping_field"
           ],
           'dataScope' => 'customShippingMethodFields.custom_shipping_field[input_custom_shipping_field]',
           'label' => "Your Custom Label", //you can add your custom text here
           'provider' => 'checkoutProvider',
           'visible' => true,
           'validation' => $validation,
           'sortOrder' => 2,
           'id' => 'custom_shipping_field[input_custom_shipping_field]'
       ];

       return $jsLayout;

}

Declare the plugin Vendor\Module\Plugin\Checkout\LayoutProcessorPlugin for the class Magento\Checkout\Block\Checkout\LayoutProcessor in your custom module’s di.xml.

app/code/Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
   <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
       <plugin name="checkout_custom_shipping_fields" type="Vendor\Module\Plugin\Checkout\LayoutProcessorPlugin" sortOrder="10"/>
   </type>
</config>

To include the custom input field in shippingMethodItemTemplate, declare a region custom-shipping-method-fields under the section shippingAddress in the file path

app/code/Vendor/Module/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">
                                       <item name="shipping-step" xsi:type="array">
                                           <item name="children" xsi:type="array">
                                               <item name="shippingAddress" xsi:type="array">
                                                   <item name="config" xsi:type="array">
                                                       <item name="shippingMethodItemTemplate" xsi:type="string">Vendor_Module/shipping-address/shipping-method-item</item>
                                                   </item>                                                   
                                                   <item name="children" xsi:type="array">
                                                       <item name="custom-shipping-method-fields" xsi:type="array">
                                                           <item name="component" xsi:type="string">uiComponent</item>
                                                           <item name="displayArea" xsi:type="string">custom-shipping-method-fields</item>
                                                           <item name="children" xsi:type="array">
                                                           </item>
                                                       </item>
                                                   </item>
                                               </item>
                                           </item>
                                       </item>
                                   </item>
                               </item>
                           </item>
                       </item>
                   </item>
               </argument>
           </arguments>
       </referenceBlock>
   </body>
</page>

Override the shipping-method-item.html in the path

app/code/Vendor/Module/view/frontend/web/template/shipping-address/

<tr class="row"
   click="element.selectShippingMethod">
   <td class="col col-method">
       <input type="radio"
              class="radio"
              ifnot="method.error_message"
              ko-checked="element.isSelected"
              ko-value="method.carrier_code + '_' + method.method_code"
              attr="'aria-labelledby': 'label_method_' + method.method_code + '_' + method.carrier_code + ' ' + 'label_carrier_' + method.method_code + '_' + method.carrier_code,
                   'checked': element.rates().length == 1 || element.isSelected" />
   </td>
   <td class="col col-price">
       <each args="element.getRegion('price')" render="" />
   </td>
   <td class="col col-method"
       attr="'id': 'label_method_' + method.method_code + '_' + method.carrier_code"
       text="method.method_title" />
   <td class="col col-carrier"
       attr="'id': 'label_carrier_' + method.method_code + '_' + method.carrier_code"
       text="method.carrier_title" />
</tr>
<!-- ko if: ((method.method_code + '_' + method.carrier_code == "customshipping_customshipping") && element.selectedMethod() == "customshipping_customshipping") -->
<tr class="custom-shipping-method-fields-shipping-information" >
   <td colspan="4">
       <div id="custom-shipping-method-fields-details-list-wrapper" data-bind="visible: method.method_code + '_' + method.carrier_code == 'customshipping_customshipping'">
           <!-- ko foreach: element.getRegion('custom-shipping-method-fields') -->
               <!-- ko template: getTemplate() --><!-- /ko -->
           <!--/ko-->
       </div>
   </td>
</tr>
<!-- /ko -->
<tr class="row row-error"
   if="method.error_message">
   <td class="col col-error" colspan="4">
       <div role="alert" class="message error">
           <div text="method.error_message"></div>
       </div>
       <span class="no-display">
           <input type="radio"
                  attr="'value' : method.method_code, 'id': 's_method_' + method.method_code" />
       </span>
   </td>
</tr>

Note: change customshipping_customshipping according to your custom shipping method code.

Don't forget to run upgrade and redeploy static content.

  • Thanks. I'll try it and let you know – coderGeek Apr 22 at 6:21
  • How can I set some data in Model/Carrier/Rates.php and display it in template? – coderGeek Apr 22 at 21:35
  • did above code work for you? – magefms Apr 22 at 21:38
  • for your new question you can create a block wherein you can put your public method and set a template (phtml) and in your template you can call it as $block->yourPublicMethod(); – magefms Apr 22 at 21:40
  • please post it as new question so others can help as well and maybe provide a better solution. – magefms Apr 22 at 21:42

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.