Problem/Motivation
DOM may be updated by various front end, back end or other ajax actions. Currently when an element with the class ".use-ajax" is added after the initial page load it usually isn't initialised. Although it might work for the admin user as the element binding could occur after the inistial DOM update (such as with VueJS or ReactJS).
To reproduce, create a dialog link with the class attribute use-ajax and data-dialog-type="modal", linking to another page. This should work.
Next, dynamically add another link, using either a JS front end or developer tools. Clicking on the link will take you to the page instead of opening a modal.
Proposed resolution
Find a way to delegate the event to a parent element or listen for dynamic updates.
The attached patch is non-compliant, and it doesn't include ES6 changes, but it does show one way to listen for dynamic updates.
| Comment | File | Size | Author |
|---|---|---|---|
| #25 | 2997668-19-d10.1.x.updated.patch | 2.51 KB | a.kovrigin |
| #19 | 2997668-19-d10.1.x.patch | 2.5 KB | agarzola |
| #18 | 2997668-18-d10.0.x.patch | 2.12 KB | yauheni |
| #16 | ajax_binding_should_apply_to_dynamic_elements-2997668-16.patch | 4.14 KB | sidgrafix |
| #13 | interdiff_12-13.txt | 1.09 KB | ranjith_kumar_k_u |
Comments
Comment #4
yivanov commentedI tested your patch and it works well for Drupal Core 8.8.2 , but still as you mentioned - it needs more work.
I found another workaround here, until we have a Drupal core solution - https://stackoverflow.com/questions/59085793/drupal-8-ajax-modal-not-wor...
Comment #6
kiseleva.t commentedUpdated patch for 9.3.x
Comment #8
qzmenkoPatch #6 works for me, thanks.
But changes also should be applied to file
/core/misc/ajax.es6.jsComment #10
qzmenkoReroll for core 9.3.x
Comment #11
qzmenkoComment #12
gauravvvv commentedFixed custom command failed, Attached interdiff for #10. Please review.
Comment #13
ranjith_kumar_k_u commentedComment #16
sidgrafix commentedPatch for Drupal 9.5 for anyone using this (patch-13 wouldn't apply after core update) do to number of lines in files have changed
Comment #18
yauheni commentedReroll for core 10.0.x
Comment #19
agarzola commentedProviding a new patch for 10.1.x that uses
MutationObserver, sinceMutationEventis deprecated.Comment #21
markdorisonComment #22
yfiervil commentedOne solution is to manage this directly where the DOM is updated.
For exemple on Vue, you can just force the bind with :
Did the core really need to manage this case ?
Comment #23
agarzola commentedSince loading content dynamically via Ajax is functionality offered by core and it is a reasonable expectation for dynamically-loaded content to itself contain dynamic links within, then it stands to reason that core should handle that use case.
Comment #25
a.kovrigin commentedI'm facing an issue when observer does nothing when no DOM changes happens on page load.
Usage of
MutationObserveris a great option here, but shouldn'tbindAjaxLinks()be called anyway, so we'll have processed.use-ajaxlinks at the page loaded stage and on DOM mutation level?