cancel
Showing results for 
Search instead for 
Did you mean: 
paul14
Community Participant

JavaScript and dynamically loaded elements

Jump to solution

Hi community.

I am creating a little addon to our Calendar events that allows people to click a button to register for a session. My script works just the way I want it in the full calendar event view because I can simply use:

$(document).ready(function() and document.getElementById("my-button-id") and onclick etc.

But I'm running into problems with this popup view that Canvas provides when you click the event in the calendar:

cnvs-ex.png

The event HTML including my button element is added dynamically to the DOM when the user clicks onto the calendar event. The element didn't exist when the $(document).ready(function() event happened, so the code breaks.

The code provided here got me a step further:

https://github.com/unsupported/canvas/blob/master/branding/javascript/on_element_rendered/on_element... (@whoever provided this - thank you!)

But it only works once. If the user opens the little popup version of the event and closes it again, it no longer seems to work.

Then I found a possibly more modern approach - MutationObserver https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver but I think I'm a bit out of my depth there.

I feel like I am just over-complicating the whole thing and I'm probably just missing a simpler way to accomplish this.

TL;DR - how can I watch for a button click on a button that sits in dynamically loaded content?

Now this would be easy if I could put the onClick event directly into the button! 🤣

Labels (1)
Tags (1)
0 Kudos
1 Solution

Accepted Solutions
James
Community Champion

As I'm reading through your post, I'm thinking Mutation Observers the whole way. There are several places I've had to put a Mutation Observer at a high level to watch for the item I want to appear so that I can put a Mutation Observer on that. The higher level stays while the nested one gets destroyed when Canvas does its magic and creates things on the fly. This is going to happen with most modal dialogs.

View solution in original post

2 Replies
paul14
Community Participant

@James I just read on a number of your posts you're quite the advocate for MutationObserver! I think this is my answer. I really like how detailed and thoughtful your responses are around here by the way!

Also, I think I just read that ENV.current_user doesn't exist in the mobile app version which I was relying on heavily for my script to work. Bummer! I will probably make a seperate post on that issue.

Edit: No need to use ENV.current_user I can use fetch() to get better user data from the API. I'm so out of my element with JavaScript but amazing how powerful it's become! I think you said elsewhere James that it's easy to get stuck in the old approaches we learnt 10-20 years ago. Async/Await. Promises. Fat Arrow Functions. My head is spinning. Good fun.

James
Community Champion

As I'm reading through your post, I'm thinking Mutation Observers the whole way. There are several places I've had to put a Mutation Observer at a high level to watch for the item I want to appear so that I can put a Mutation Observer on that. The higher level stays while the nested one gets destroyed when Canvas does its magic and creates things on the fly. This is going to happen with most modal dialogs.

View solution in original post