add custom js to the certain input element on the checkout page
-
14-04-2021 - |
Вопрос
My final goal adds custom js to the certain input element on the checkout page
what i tried
- 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()
})
})
- 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