Inside of a modal window I'm loading a form template via jQuery .load. For reasons I don't know, the {% js %} tags that need to come with the form template are not being loaded, even though the {% js %} tag is placed at the bottom of the loaded partial.

Here's the loading code

{% js %}
  MicroModal.init()

  $(document).ready(function() {
    $('.trigger').click(function() {
      event.preventDefault();

      MicroModal.show('addressModal');
      $('.c-modal__content').load('account/profile/billing/add #newAddressForm');
    });
  });
{% endjs %}

On click a modal will open, retrieve the template, look for the #newAddressForm ID element, and an address form template will load within it. The HTML part of the form loads fine, but no JS is brought with it.

The loaded partial template:

<form method="post" id="newAddressForm">
  <input type="hidden" name="action" value="commerce/customer-addresses/save">
  {{ csrfInput() }}

  {% include "shop/_inc/addresses/form" %}

  <button type="submit">Save</button>
</form>

And lastly, the {% include %} has the form fields and {% js %} tag inside.

To reiterate, the HTML of the form loads fine. The JS does not come with it. I'm not sure if this is an issue with Twig, Craft, or jQuery. Help would be appreciated!

In Craft 3, the {% js %} tag places the javascript code just before the closing </body> tag in the rendered HTML document by default.

This means that the rendered <script> tag will not be in the #newAddressForm element, but will be rendered just before the closing </body> tag.

So if you are loading the rendered template using jQuery's .load() function and specifying the #newAddressForm element, the <script> tag will be excluded from the injected code as it isn’t within the #newAddressForm element.

Your best bet is to inline the <script> tag within the Twig template rather than using the {% js %} tag to include it. That way you can ensure that the code will be included in the #newAddressForm element as you need it.

More details of the {% js %} tag can be found in the Craft 3 docs: https://docs.craftcms.com/v3/dev/tags/js.html

  • Maybe I'm being dense here. Isn't the <script> tag technically within the the #newAddressForm element because it's being {% included %} right in the middle there? – John Johnson Aug 9 at 15:37
  • No, because you are use the {% js %} tag to add the javascript. This makes it possible to add the javascript in your template close to where it is relevant, but the actual <script> tag will be rendered at end of the page's <body> tag by default. If you use the {% js %} tag in an {% include %} sub-template, it is still rendered at the end of the <body> tag in the final rendered page. – Steve Rowling Aug 9 at 15:43
  • Steve, thank you for the clarification. Re-thinking how my templates are organized might be my best path forward here so that I can avoid having to target the #newAddressForm element. – John Johnson Aug 9 at 16:13
  • I'm coming up empty. I've dumbed down some test templates and nothing works. The parent template .jstest.twig has jquery .load attached to a button, which loads a message into an empty div fine. It's supposed to also bring a {% js %} tag to say 'ready' in the console. No {% js %} is coming with it. – John Johnson Aug 9 at 17:12
  • Instead of using {% js %} tags to wrap your JavaScript in your template, just use a normal HTML <script> tag pair and it should work as you expect. – Steve Rowling Aug 9 at 18:18

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.