skip to Main Content

I am looking to append divs onto Vanilla Calendar to show indicators that the day has an event on. I have my event information in a JSON file:

{
  "events": [{
      "2023-08": [{
          "2023-08-29": [{
              "eventID1": [{
                "title": "Event Title",
                "category": "Category"
              }]
            },
            {
              "eventID2": [{
                "title": "Event Title",
                "category": "Category"
              }]
            }
          ]
        },
        {
          "2023-08-30": [{
              "eventID1": [{
                "title": "Event Title",
                "category": "Category"
              }]
            },
            {
              "eventID2": [{
                "title": "Event Title",
                "category": "Category"
              }]
            }
          ]
        }
      ]
    },
    {
      "2023-09": [{
          "2023-09-29": [{
              "eventID1": [{
                "title": "Event Title",
                "category": "Category"
              }]
            },
            {
              "eventID2": [{
                "title": "Event Title",
                "category": "Category"
              }]
            }
          ]
        },
        {
          "2023-09-30": [{
              "eventID1": [{
                "title": "Event Title",
                "category": "Category"
              }]
            },
            {
              "eventID2": [{
                "title": "Event Title",
                "category": "Category"
              }]
            }
          ]
        }
      ]
    }
  ]
}

Each month of the calendar shows a data attribute on the div like this:

data-calendar-selected-month="7" //month 7 = August 

Each day of the calendar shows a data attribute on the button like this:

data-calendar-day="2023-08-29"
<button class="vanilla-calendar-day__btn vanilla-calendar-day__btn_today" type="button" data-calendar-day="2023-08-29">29</button>

What I’m looking to do is for every day on the calendar, append a div onto that element on the page that matches the date within the JSON data… I am just unsure how to approach this with a lot of JSON data

Can someone detail how that loop might work?

I’m trying something like this:

eventData = data.events;
drawEvent(data)

function drawEvent(data) {
  for (events in data) {
    var eventEntries = data[*date?*]
    for (var i = 0; i < eventEntries.length; i++) {
      //append the div here?
    }
  }
}

Sorry for rough code, but I appreciate any help

2

Answers


  1. That data is structured very strangely, including arrays and objects which always only have one item.

    let data = {
      "events": [{
          "2023-08": [{
              "2023-08-29": [{
                  "eventID1": [{
                    "title": "Event Title",
                    "category": "Category"
                  }]
                },
                {
                  "eventID2": [{
                    "title": "Event Title",
                    "category": "Category"
                  }]
                }
              ]
            },
            {
              "2023-08-30": [{
                  "eventID1": [{
                    "title": "Event Title",
                    "category": "Category"
                  }]
                },
                {
                  "eventID2": [{
                    "title": "Event Title",
                    "category": "Category"
                  }]
                }
              ]
            }
          ]
        },
        {
          "2023-09": [{
              "2023-09-29": [{
                  "eventID1": [{
                    "title": "Event Title",
                    "category": "Category"
                  }]
                },
                {
                  "eventID2": [{
                    "title": "Event Title",
                    "category": "Category"
                  }]
                }
              ]
            },
            {
              "2023-09-30": [{
                  "eventID1": [{
                    "title": "Event Title",
                    "category": "Category"
                  }]
                },
                {
                  "eventID2": [{
                    "title": "Event Title",
                    "category": "Category"
                  }]
                }
              ]
            }
          ]
        }
      ]
    };
    let eventData = data.events;
    for (const entry of eventData) {
      for (const [month, days] of Object.entries(entry)) {
        for (const dayObject of days) {
          for (const [day, events] of Object.entries(dayObject)) {
            let dayElement = document.querySelector(`[data-calendar-day="${day}"]`);
            for (const eventObject of events) {
              for (const [eventId, details] of Object.entries(eventObject)) {
                for (const event of details) {
                  let div = document.createElement("div");
                  div.append(event.title + ", " + event.category);
                  dayElement.append(div);
                }
              }
            }
          }
        }
      }
    }
    <button class="vanilla-calendar-day__btn vanilla-calendar-day__btn_today" type="button" data-calendar-day="2023-08-29">29</button>
    <button class="vanilla-calendar-day__btn vanilla-calendar-day__btn_today" type="button" data-calendar-day="2023-08-30">30</button>
    <button class="vanilla-calendar-day__btn vanilla-calendar-day__btn_today" type="button" data-calendar-day="2023-09-29">29</button>
    <button class="vanilla-calendar-day__btn vanilla-calendar-day__btn_today" type="button" data-calendar-day="2023-09-30">30</button>

    I would prefer it if the data looked like this instead:

    {
      "events": {
          "2023-08": {
              "2023-08-29": [
                 {
                    "id": "eventID1",
                    "title": "Event Title",
                    "category": "Category"
                 },
                 {
                    "id": "eventID2",
                    "title": "Event Title",
                    "category": "Category"
                 }
              ],
              "2023-08-30": [
                 {
                    "id": "eventID1",
                    "title": "Event Title",
                    "category": "Category"
                 },
                 {
                    "id": "eventID2",
                    "title": "Event Title",
                    "category": "Category"
                 }
              ]
          },
          "2023-09": {
              "2023-09-29": [
                 {
                    "id": "eventID1",
                    "title": "Event Title",
                    "category": "Category"
                 },
                 {
                    "id": "eventID2",
                    "title": "Event Title",
                    "category": "Category"
                 }
              ],
              "2023-09-30": [
                 {
                    "id": "eventID1",
                    "title": "Event Title",
                    "category": "Category"
                 },
                 {
                    "id": "eventID2",
                    "title": "Event Title",
                    "category": "Category"
                 }
              ]
          }
      }
    }
    
    Login or Signup to reply.
  2. You can find the matching element with the following loop. targetElement will be the div matching data-calendar-day.

    for (let month of data.events) {
        for (let days of Object.values(month)) {
            for (let day of days) {
                for (let [date, events] of Object.entries(day)) {
                    for (let event of events.map(it => Object.values(it)).flat(2)) {
                        const targetElement = document.querySelector(`[data-calendar-day="${date}"]`);
                        targetElement.textContent = `Title: ${event.title}. Category: ${event.category}`;
                    }
                }
            }
        }
    }
    

    More information regarding Object.values(), Object.entries() and flat().

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search