Вопрос

My final goal adds custom js to the certain input element on the checkout page

what i tried

  1. To get element with uiRegistry and on redner add needed code, but failed, i can work with tjis element like with usual elements in DOM with jQuery
require(['uiRegistry'], function (r) {
    r.get("checkout.steps.shipping-step.shippingAddress.shipping-address-fieldset.telephone", function (el) {
        debugger;
        el.disable()
    })
})
  1. second idea was to add custom JS to the item in Vendor/ModuleName/view/frontend/layout/checkout_index_index.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout" 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="shipping-address-fieldset" xsi:type="array">
                                                        <item name="children" xsi:type="array">
                                                            <item name="telephone" xsi:type="array">
                                                                <item name="component" xsi:type="string">Vendor_ModuleName/js/view/telephone</item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

As the inputs on the Checkout rendered from the

vendor/magento/module-ui/view/frontend/web/templates/form/element/input.html

template, I created own template file based on the input.html, with one modification

Vendor/ModuleName/view/frontend/web/template/telephone.html with afteRender

<input class="input-text" afterRender="onElementRender" type="text" data-bind="
    value: value,
    valueUpdate: 'keyup',
    hasFocus: focused,
    attr: {
        name: inputName,
        placeholder: placeholder,
        'aria-describedby': getDescriptionId(),
        'aria-required': required,
        'aria-invalid': error() ? true : 'false',
        id: uid,
        disabled: disabled
    }" />

also tried

<input class="input-text" type="text" data-bind="
    value: value,
    valueUpdate: 'keyup',
    hasFocus: focused,
    attr: {
        name: inputName,
        placeholder: placeholder,
        'aria-describedby': getDescriptionId(),
        'aria-required': required,
        'aria-invalid': error() ? true : 'false',
        id: uid,
        disabled: disabled,
        afterRender: onElementRender
    }" />

added js file Vendor/ModuleName/view/frontend/web/js/view/telephone.js

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

    debugger;

    return Component.extend({
        defaults: {
            template: 'Vendor_ModuleName/telephone'
        },
        onElementRender: function () {
            debugger;
        }
    });
});

the first debugger works well and after that, i got an error

Uncaught ReferenceError: Unable to process binding "css: function (){return additionalClasses }"
Message: additionalClasses is not defined
    at css (eval at createBindingsStringEvaluator (knockout.js:2624), <anonymous>:3:148)
    at update (knockout.js:3803)
    at ko.dependentObservable.disposeWhenNodeIsRemoved (knockout.js:3004)
    at evaluateImmediate (knockout.js:1737)
    at Object.ko.computed.ko.dependentObservable (knockout.js:1946)
    at knockout.js:3002
    at Object.arrayForEach (knockout.js:151)
    at applyBindingsToNodeInternal (knockout.js:2974)
    at applyBindingsToNodeAndDescendantsInternal (knockout.js:2854)
    at Object.ko.applyBindings (knockout.js:3065)

i google this, seems like the issue with the template, but what exactly wrong? But i think something wrong with telephone.js

Or how it's to do in a right way?

Это было полезно?

Решение

I found a solution, I did this with using layout processor

created 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 disabled="false" name="MaxMage_InternationalTelephoneInput_Plugin_Block_Checkout_LayoutProcessor"
                type="MaxMage\InternationalTelephoneInput\Plugin\Block\Checkout\LayoutProcessor"/>
    </type>
</config>

created a file Plugin/Block/Checkout/LayoutProcessor.php in a module, where i override the xml ui component with need template

[
            'component' => 'Magento_Ui/js/form/element/abstract',
            'config' => [
                'customScope' => $addressType . $method,
                'customEntry' => null,
                'template' => 'ui/form/field',
                'elementTmpl' => 'MaxMage_InternationalTelephoneInput/form/element/telephone',
                'tooltip' => [
                    'description' => 'For delivery questions.',
                    'tooltipTpl' => 'ui/form/element/helper/tooltip'
                ],
            ],
            'dataScope' => $addressType . $method . '.telephone',
            'dataScopePrefix' => $addressType . $method,
            'label' => __('Phone Number'),
            'provider' => 'checkoutProvider',
            'sortOrder' => 120,
            'validation' => [
                "required-entry"    => true,
                "max_text_length"   => 255,
                "min_text_length"   => 1
            ],
            'options' => [],
            'filterBy' => null,
            'customEntry' => null,
            'visible' => true,
            'focused' => false,
        ];

the ready code on the github

Другие советы

Magento usesMagento_Ui/js/form/element/abstract.js as default component for the input fileds. To create a custom component with some default functionality you need to use Abstract component as dependancy

define([
   'jquery',
   'Magento_Ui/js/form/element/abstract'
 ], function ($, Abstract) {
 'use strict';
 
  return Abstract.extend({ 
      initialize: function (){
        console.log(this);
        return this._super();
      },      

     /**
     * On value change handler.
     *
     * @param {String} value
     */
     onUpdate: function (value) {
        console.log("update");       
        return this._super();
     },
   });
});

Hope This will help and save time

Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top