@im-perativa I came across this when I was looking for some calendar components for Streamlit. This has been amazing! Thank you so much for creating it. We’re using it at our firm to quickly see teaching allocations of all our instructors, where resource=Instructor name and building=Region. Super easy to modify by converting our pandas dataframes into JSON objects for the calendar.
Hi! This is a really cool module, but I’m having some trouble with it. I’ve tried everything I can think of, but the calendar won’t update new events I add to the session_state. For the life of me, I can’t figure out why. If somebody knows how to do this, or is facing a similar issue, could they please tell me?
Hi bogdant,
It seems like you know how to, or know somebody who knows how to update this calendar module in real-time, like adding and removing events from the calendar. If you are aware of how to execute this with the streamlit_calendar component, could you let me know? I’ve been really stuck on this problem, since i need to add and delete events from the calendar after it has been rendered.
Hello im-perativa, is there a way to update the calendar? the calendar only updates on refresh, even if the data it’s being given changes on rerun. Im not sure how to work around this, so I wanted to ask if there was a feature built-in or something?
Hi Rishu,
Try recreating key for calendar everytime you want to refresh.
if not st.session_state.get("CalKey", False):
st.session_state["CalKey"] = str(uuid.uuid4())
Once new event is added in event json do
st.session_state["CalKey"] = str(uuid.uuid4())
This will make sure calendar is re-rendered.
Hi Mohit,
Does this work? I also want to refresh the calender every time that I add a new event but i have no idea how to do it. @im-perativa is there a way to do this? How do we add more events to the calendar after the calendar has already been created? For example, creating a few widgets for the user to input data to be added to the calendar.
HI Adam,
Every time you add new event to event json, add these 2 lines after that.
st.session_state["CalKey"] = str(uuid.uuid4())
st.rerun()
This will make sure calendar widget is re created.
Super helpful! Thanks for the share!
Hi Mohit,
I tried that, but the code still doesnt work. I get this error:
StreamlitAPIException: st.session_state.Calendar
cannot be modified after the widget with key Calendar
is instantiated.
The code is below. Can you help? Thanks!
colors = ["blue", "red", "green"]
events = [
{
"title": "Event 1",
"color": colors[2],
"location": "LA",
"start": "2024-08-30",
"end": "2024-09-02",
"resourceId": "b",
}
]
people = [
{"id": "a", "title": "Jeff"},
{"id": "b", "title": "John"},
{"id": "c", "title": "Both"}
]
calendar_options = {
"editable": "true",
"navLinks": "true",
"resources": people,
"selectable": "true",
}
calendar_options = {
**calendar_options,
"headerToolbar": {
"left": "today prev,next",
"center": "title",
"right": "dayGridDay,dayGridWeek,dayGridMonth",
},
"initialDate": "2024-08-01",
"initialView": "dayGridMonth",
}
state = calendar(
events=st.session_state.get("events", events),
options=calendar_options,
custom_css="""
.fc-event-past {
opacity: 0.8;
}
.fc-event-time {
font-style: italic;
}
.fc-event-title {
font-weight: 700;
}
.fc-toolbar-title {
font-size: 2rem;
}
""",
key="Calendar",
)
event_to_add = {
"title": "Event 7",
"color": "#FF4B4B",
"location": "SF",
"start": "2024-09-01",
"end": "2024-09-07",
"resourceId": "a"
}
if st.button("add event"):
events.append(event_to_add)
st.write(events)
st.session_state["Calendar"] = str(uuid.uuid4())
st.rerun()
if state.get("eventsSet") is not None:
st.session_state["events"] = state["eventsSet"]
Try this
import streamlit as st
from streamlit_calendar import calendar
import uuid
colors = ["blue", "red", "green"]
events = [
{
"title": "Event 1",
"color": colors[2],
"location": "LA",
"start": "2024-08-30",
"end": "2024-09-02",
"resourceId": "b",
}
]
people = [
{"id": "a", "title": "Jeff"},
{"id": "b", "title": "John"},
{"id": "c", "title": "Both"}
]
calendar_options = {
"editable": "true",
"navLinks": "true",
"resources": people,
"selectable": "true",
}
calendar_options = {
**calendar_options,
"headerToolbar": {
"left": "today prev,next",
"center": "title",
"right": "dayGridDay,dayGridWeek,dayGridMonth",
},
"initialDate": "2024-08-01",
"initialView": "dayGridMonth",
}
if not st.session_state.get("Calendar", False):
st.session_state["Calendar"] = str(uuid.uuid4())
state = calendar(
events=events,
options=calendar_options,
custom_css="""
.fc-event-past {
opacity: 0.8;
}
.fc-event-time {
font-style: italic;
}
.fc-event-title {
font-weight: 700;
}
.fc-toolbar-title {
font-size: 2rem;
}
""",
key=st.session_state["Calendar"],
)
event_to_add = {
"title": "Event 7",
"color": "#FF4B4B",
"location": "SF",
"start": "2024-09-01",
"end": "2024-09-07",
"resourceId": "a"
}
if st.button("add event"):
events.append(event_to_add)
st.write(events)
st.session_state["Calendar"] = str(uuid.uuid4())
st.rerun()
if state.get("eventsSet") is not None:
st.session_state["events"] = state["eventsSet"]
Hi Mohit,
Thank you for the response, but that unfortunately doesn’t work either. The code no longer encounters an error, but doesn’t update the calendar either. Do you (or anyone else) have any ideas?
Thanks
Hi Adam,
The events list is getting re-created every time app runs from top to bottom. The second event that you are trying to add is not getting added to events list and hence you see only one event in calendar.
You need to use st.session_state to store your events to make sure its not getting re created on every run.
hope this helps.
Hi Mohit, I love this package, thank you.
I am wondering the best way to add additional text beyond just the title. I have tried just adding everything to the title, but oddly adding “\n” does not seem to force a line break. Is there another way to do this to that I can add a description to the event?
thx,
Kevin