0

I'm still a novice when it comes to Magento 2 frontend with jsLayout, requireJS, etc. I have a custom module where, in javascript, I am trying to attach an onchange listener to the email textbox. I tried going the simple route by including a .phtml file via layout.xml:

checkout_index_index.xml

<referenceContainer name="after.body.start">
 <block class="Magento\Framework\View\Element\Template" name="sf.checkout.trackuser" as="sf.checkout.trackuser"
 after="sf.ads.default" template="MyVendor_SF::checkout-track-user.phtml" />
</referenceContainer> 

checkout-track-user.phtml

<script>
require(['jquery'], function($) {
 $(document).ready(function() {
 $("input#customer-email").on("change", function(e) {
 //console.log('yay');
 });
 });
});

However, when my js runs, the input#customer-email element is not yet loaded on the page, even when put inside $(document).ready(function() {});. How can run my js code after this textbox has loaded on the page?

My guess is that I need to add a component to the checkout jsLayout, but I am not sure how to go about doing this. I've looked at docs and examples, and currently, I have:

<body>
 <referenceContainer name="after.body.start">
 <block class="Magento\Framework\View\Element\Template" name="sf.checkout.trackuser" as="sf.checkout.trackuser"
 after="sf.ads.default" template="MyVendor_SF::checkout-track-user.phtml" />
 </referenceContainer>
 <referenceContainer name="content">
 <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="component" xsi:type="string">MyVendor_SF/js/track-checkout-guest</item>
 </item>
 </item>
 </item>
 </item>
 </item>
 </item>
 </item>
 </argument>
 </arguments>
 </referenceBlock>
 </referenceContainer>
</body> 

I have no clue how I would code track-checkout-guest.js though.. in my case I don't think it's an actual component (no .html template or knockoutJS involved), so I'm not sure what to do.

asked May 25, 2021 at 19:10
2
  • It's kinda hack but you can try checking if your element exists then run function. In jquery you can do this by if($("#customer-email").length) and then put your code inside if. Maybe that could solve it Commented May 26, 2021 at 4:38
  • magento.stackexchange.com/questions/166126/… Commented May 27, 2021 at 7:03

1 Answer 1

0

The reason why your solution doesn't work is that e-mail component appears in DOM after DOM is "ready". You could either create a Magento JS mixin for the component and run your code after the component is initialized (see: https://devdocs.magento.com/guides/v2.4/javascript-dev-guide/javascript/js_mixins.html), or use your approach but with MutationObserver instead of document ready event (see: https://gabrieleromanato.name/jquery-detecting-new-elements-with-the-mutationobserver-object).

answered May 26, 2021 at 6:50

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.