0

I have a calendar that logs the event date, title and description of an event created through an event form. This data is stored within the cell of the day it was logged (the date as an ID and event title as a text node). When the button is pressed, a modal is presented with all of this information.

To fetch the information of each event previously logged, I'm using a querySelectAll method to fetch all the ID's and adding an event listener to them. This event listener converts the ID of each cell to Unix time, and if a button is present on the cell (created with the form), to display the modal described above.

While this works to each cell on the starting month, any navigation to a month forward or previous to it does not display any of this information inside the modal.

I suspect it is because my queryselector is only gathering the cells present when the page loads, but is not 'reloading' once new cells are presented on the page.

How could this be made to work? is there a way to rerun this same querySelector once my DOM elements have changed? and if not, is there a way to rerun a .js script once a navigation button is pressed?

Below is my block of code I would like to run each time a month navigation button is pressed:

  document.querySelectorAll("[id*='date']")
.forEach(e => e.addEventListener("click", function () {
    //fixing the time
    var time = e.id
    var timeFixed = time.replace(/\D/g, "")
    console.log(timeFixed)

    //getting and logging the event title 
    var eventText = e.querySelector('#titleText')
    if (eventText != null) {
        console.log('first Child', eventText.textContent)
    }
    if (eventText == null) {
        return
    }

    //get the event title
    body = $('#modalHead').text('Title: ' + eventText.textContent)

    //header append to modal
    header = $('#modalDate').text('Date: ' + new Date(parseInt(timeFixed)).toLocaleDateString('en-US'));

    //description append to modal
    var descEvent = e.querySelector('#descText')
    if (descEvent.textContent != null) {
        desc = $('#modalDesc').text('Description: ' + descEvent.textContent)
        console.log('description', descEvent.textContent)
    }
    if (descEvent.textContent == null) {
        body = $('#modalHead').text('Title: ' + eventText.textContent)
    }        
}))

I have tried to implement this code block as a function that can be called once my button is pressed, however I ran into problems trying to make the event targets work. I also tried to fit this code block into a setinterval() every second, but scrapped the idea as I imagine this would be incredibly inefficient.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 6
    You will want to use event delegation. -> https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_delegation – Keith Dec 24 '22 at 21:10
  • Please post a [mcve] of your attempt, noting input and expected output, preferably in a [Stacksnippet](https://blog.stackoverflow.com/2014/09/introducing-runnable-javascript-css-and-html-code-snippets/) – mplungjan Dec 25 '22 at 06:44
  • one problem I see it's that you refer to `e` inside your event handler. That function will run when the event will occur and not while the foreach loop will just be adding the handler to each object returned by the selector. You should fetch the element triggering the event inside the event handler doing `event.target` (while having the event argument in your function) – Diego D Dec 26 '22 at 09:09

0 Answers0