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!

9
  • I think this one can help you get started magento.stackexchange.com/questions/92734/…
    – fmsthird
    Apr 18 '19 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 '19 at 15:35
  • you mean you want to display some extra column when your custom shipping is selected?
    – fmsthird
    Apr 21 '19 at 23:09
  • Yes, something like that can also work.
    – coderGeek
    Apr 22 '19 at 6:21
  • you can't do that as template file is using ko js to bind data
    – fmsthird
    Apr 23 '19 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.

7
  • Thanks. I'll try it and let you know
    – coderGeek
    Apr 22 '19 at 6:21
  • How can I set some data in Model/Carrier/Rates.php and display it in template?
    – coderGeek
    Apr 22 '19 at 21:35
  • did above code work for you?
    – fmsthird
    Apr 22 '19 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();
    – fmsthird
    Apr 22 '19 at 21:40
  • please post it as new question so others can help as well and maybe provide a better solution.
    – fmsthird
    Apr 22 '19 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.