I am wanting to run some javascript code on content after pat-inject loads it. In particular, the content has bootstrap 5 popovers which need to be initialized Popovers · Bootstrap v5.3. I've tried two methods that do not work:
Watch for the "injecting" class to be removed, but this would try to initialize before the content loads, or at the least it's a race condition
Put a tag directly into the content being loaded. As far as I can tell, this just gets stripped out by the pattern?
Also fyi, assuming the people responsible for it are also on this site, Inject — Patterns has a lot of broken images.
This will "click" the element with that class.
You can bind to the click event your js code.
This is of course an horrifying hack, but an hack that proved to work reliably.
Disclaimer: I am the human being more distant from a JavaScript developer that exists on this planet and I feel fine
document.querySelector(".pat-inject.my-specific-selector").addEventListener("pat-inject-success", (e) => {
// do something
})
That's a good occasion to finally document what I have to look up myself quite often. I'll copy the following table over to the pat-inject documentation which should then be on the website after the next Patternslib release.
pat-inject fires several JavaScript events which bubble up the DOM tree:
Event name
Type
Triggered on
Bubbles
Description
patterns-inject-triggered
jQuery
pat-inject-element
true
Triggered, right after injection has been triggered. This can be on click, on submit, automatically and so on.
pat-ajax-success
jQuery
pat-inject element
true
Triggered after successful ajax call but before the response is injected into the document
patterns-injected
jQuery
parent of injected content
true
Triggered after successful injection
pat-inject-success
JavaScript
pat-inject element
true
Triggered after successful injection, right after patterns-injected but on the pat-inject element and not on the injected content itself.
patterns-injected-scanned
jQuery
injected content
true
Triggered after injected content was scanned by Pattern registry for new patterns.
patterns-injected-delayed
JavaScript
injected content
true
Triggered 10ms after patterns-injected-scanned
pat-inject-content-loaded
jQuery
images within injected content
true
Triggered on images within the injected content when those images are loaded.
pat-inject-missingSource
jQuery
trigger which caused the injection
true
Triggered when no to-be-injected source could be found.
pat-inject-missingTarget
jQuery
trigger which caused the injection
true
Triggered when no target could be found.
Please note: jQuery.trigger events can be catched with jQuery only while JavaScript dispatchEvent events can be catched with bare JavaScript addEventListener and jQuery.on.
I have come across an edge case with a problem. I have a form inside of #my-content and the injection replaces the contents of #my-content. I would like to do something after this injection, but since the form element no longer exists the patterns-inject-triggered event will never fire. This is on Plone 5.2.x.
I'm not sure if there is a hacky solution. I cannot simply add another event when the button is pressed, because I need the form submission to resolve first. Perhaps I have reached the limit of what can be done without having an actual one page solution like React.
Sorry for the late reply. Using patterns-injected doesn't help? It triggers on the parent of the injected content, so should not vanish after injection and bubble up to the document root element.
As a maintainer of patternslib I have already added some events in cases where the original ones didn't help me. So if this use case - which I think is a very valid one - can't be solved with the existing events, I can help and add a new one.
Are you using the latest Patternslib or the one provided in plone.patternslib package? plone.patternslib uses a quite old Patternslib version which does not have all the events listed in my comment above.