Pip install full-calendar-component 📅

20242-ezgif.com-optimize (1)
Downloads
This is an actual published version of what was started based on my prior post: Dash-full-calendar component

The goal was to build out a full feature component to provide https://fullcalendar.io/ for dash.

You can use this component with pip install full-calendar-component==0.0.3 its was built on top of the the hard work and backs of dash-mantine-components==0.13.0a2, dash-quill and obviously dash.

So you’ll also need to pip install dash dash-mantine-components==0.13.0a2 dash-quill to get the most out of this package.

You can also change the styling of the calendar with adding this code into your style.css file:

/* the main calendar container theme */

.fc { /* the main calendar container */
    background-color: #ffffff;
    color: #ecf0f1;
}

.fc-daygrid-day { /* the individual day cells */
    background-color: #1d2731;
}

.fc-event { /* the events */
    background-color: #3498db;
    border-color: #3498db;
}

These are some of the features and capabilities this full-calendar-component has access to:
props: id, initialView, headerToolbar, initialDate, selectable, editable, events, views, multiMonthMaxColumns, resources, navLinks, businessHours, nowIndicator

This is a basic example of how to get this project up and running:

import full_calendar_component as fcc
from dash import *
import dash_mantine_components as dmc
from dash.exceptions import PreventUpdate
from datetime import datetime, date, timedelta
import dash_quill

app = Dash(__name__, prevent_initial_callbacks=True)

quill_mods = [
    [{"header": "1"}, {"header": "2"}, {"font": []}],
    [{"size": []}],
    ["bold", "italic", "underline", "strike", "blockquote"],
    [{"list": "ordered"}, {"list": "bullet"}, {"indent": "-1"}, {"indent": "+1"}],
    ["link", "image"],
]

# Get today's date
today = datetime.now()

# Format the date
formatted_date = today.strftime("%Y-%m-%d")

app.layout = html.Div(
    [
        fcc.FullCalendarComponent(
            id="calendar",  # Unique ID for the component
            initialView="listWeek",  # dayGridMonth, timeGridWeek, timeGridDay, listWeek,
            # dayGridWeek, dayGridYear, multiMonthYear, resourceTimeline, resourceTimeGridDay, resourceTimeLineWeek
            headerToolbar={
                "left": "prev,next today",
                "center": "",
                "right": "listWeek,timeGridDay,timeGridWeek,dayGridMonth",
            },  # Calendar header
            initialDate=f"{formatted_date}",  # Start date for calendar
            editable=True,  # Allow events to be edited
            selectable=True,  # Allow dates to be selected
            events=[],
            nowIndicator=True,  # Show current time indicator
            navLinks=True,  # Allow navigation to other dates
        ),
        dmc.MantineProvider(
            theme={"colorScheme": "dark"},
            children=[
                dmc.Modal(
                    id="modal",
                    size="xl",
                    title="Event Details",
                    zIndex=10000,
                    children=[
                        html.Div(id="modal_event_display_context"),
                        dmc.Space(h=20),
                        dmc.Group(
                            [
                                dmc.Button(
                                    "Close",
                                    color="red",
                                    variant="outline",
                                    id="modal-close-button",
                                ),
                            ],
                            position="right",
                        ),
                    ],
                )
            ],
        ),
        dmc.MantineProvider(
            theme={"colorScheme": "dark"},
            children=[
                dmc.Modal(
                    id="add_modal",
                    title="New Event",
                    size="xl",
                    children=[
                        dmc.Grid(
                            children=[
                                dmc.Col(
                                    html.Div(
                                        dmc.DatePicker(
                                            id="start_date",
                                            label="Start Date",
                                            value=datetime.now().date(),
                                            styles={"width": "100%"},
                                            disabled=True,
                                        ),
                                        style={"width": "100%"},
                                    ),
                                    span=6,
                                ),
                                dmc.Col(
                                    html.Div(
                                        dmc.TimeInput(
                                            label="Start Time",
                                            withSeconds=True,
                                            value=datetime.now(),
                                            format="12",
                                            id="start_time",
                                        ),
                                        style={"width": "100%"},
                                    ),
                                    span=6,
                                ),
                            ],
                            gutter="xl",
                        ),
                        dmc.Grid(
                            children=[
                                dmc.Col(
                                    html.Div(
                                        dmc.DatePicker(
                                            id="end_date",
                                            label="End Date",
                                            value=datetime.now().date(),
                                            styles={"width": "100%"},
                                        ),
                                        style={"width": "100%"},
                                    ),
                                    span=6,
                                ),
                                dmc.Col(
                                    html.Div(
                                        dmc.TimeInput(
                                            label="End Time",
                                            withSeconds=True,
                                            value=datetime.now(),
                                            format="12",
                                            id="end_time",
                                        ),
                                        style={"width": "100%"},
                                    ),
                                    span=6,
                                ),
                            ],
                            gutter="xl",
                        ),
                        dmc.Grid(
                            children=[
                                dmc.Col(
                                    span=6,
                                    children=[
                                        dmc.TextInput(
                                            label="Event Title:",
                                            style={"width": "100%"},
                                            id="event_name_input",
                                            required=True,
                                        )
                                    ],
                                ),
                                dmc.Col(
                                    span=6,
                                    children=[
                                        dmc.Select(
                                            label="Select event color",
                                            placeholder="Select one",
                                            id="event_color_select",
                                            value="ng",
                                            data=[
                                                {
                                                    "value": "bg-gradient-primary",
                                                    "label": "bg-gradient-primary",
                                                },
                                                {
                                                    "value": "bg-gradient-secondary",
                                                    "label": "bg-gradient-secondary",
                                                },
                                                {
                                                    "value": "bg-gradient-success",
                                                    "label": "bg-gradient-success",
                                                },
                                                {
                                                    "value": "bg-gradient-info",
                                                    "label": "bg-gradient-info",
                                                },
                                                {
                                                    "value": "bg-gradient-warning",
                                                    "label": "bg-gradient-warning",
                                                },
                                                {
                                                    "value": "bg-gradient-danger",
                                                    "label": "bg-gradient-danger",
                                                },
                                                {
                                                    "value": "bg-gradient-light",
                                                    "label": "bg-gradient-light",
                                                },
                                                {
                                                    "value": "bg-gradient-dark",
                                                    "label": "bg-gradient-dark",
                                                },
                                                {
                                                    "value": "bg-gradient-white",
                                                    "label": "bg-gradient-white",
                                                },
                                            ],
                                            style={"width": "100%", "marginBottom": 10},
                                            required=True,
                                        )
                                    ],
                                ),
                            ]
                        ),
                        dash_quill.Quill(
                            id="rich_text_input",
                            modules={
                                "toolbar": quill_mods,
                                "clipboard": {
                                    "matchVisual": False,
                                },
                            },
                        ),
                        dmc.Accordion(
                            children=[
                                dmc.AccordionItem(
                                    [
                                        dmc.AccordionControl("Raw HTML"),
                                        dmc.AccordionPanel(
                                            html.Div(
                                                id="rich_text_output",
                                                style={
                                                    "height": "300px",
                                                    "overflowY": "scroll",
                                                },
                                            )
                                        ),
                                    ],
                                    value="raw_html",
                                ),
                            ],
                        ),
                        dmc.Space(h=20),
                        dmc.Group(
                            [
                                dmc.Button(
                                    "Submit",
                                    id="modal_submit_new_event_button",
                                    color="green",
                                ),
                                dmc.Button(
                                    "Close",
                                    color="red",
                                    variant="outline",
                                    id="modal_close_new_event_button",
                                ),
                            ],
                            position="right",
                        ),
                    ],
                ),
            ],
        ),
    ]
)


@app.callback(
    Output("modal", "opened"),
    Output("modal", "title"),
    Output("modal_event_display_context", "children"),
    Input("modal-close-button", "n_clicks"),
    Input("calendar", "clickedEvent"),
    State("modal", "opened"),
)
def open_event_modal(n, clickedEvent, opened):
    ctx = callback_context

    if not ctx.triggered:
        raise PreventUpdate
    else:
        button_id = ctx.triggered[0]["prop_id"].split(".")[0]

    if button_id == "calendar" and clickedEvent is not None:
        event_title = clickedEvent["title"]
        event_context = clickedEvent["extendedProps"]["context"]
        return (
            True,
            event_title,
            html.Div(
                dash_quill.Quill(
                    id="input3",
                    value=f"{event_context}",
                    modules={
                        "toolbar": False,
                        "clipboard": {
                            "matchVisual": False,
                        },
                    },
                ),
                style={"width": "100%", "overflowY": "auto"},
            ),
        )
    elif button_id == "modal-close-button" and n is not None:
        return False, dash.no_update, dash.no_update

    return opened, dash.no_update


@app.callback(
    Output("add_modal", "opened"),
    Output("start_date", "value"),
    Output("end_date", "value"),
    Output("start_time", "value"),
    Output("end_time", "value"),
    Input("calendar", "dateClicked"),
    Input("modal_close_new_event_button", "n_clicks"),
    State("add_modal", "opened"),
)
def open_add_modal(dateClicked, close_clicks, opened):

    ctx = callback_context

    if not ctx.triggered:
        raise PreventUpdate
    else:
        button_id = ctx.triggered[0]["prop_id"].split(".")[0]

    if button_id == "calendar" and dateClicked is not None:
        try:
            start_time = datetime.strptime(dateClicked, "%Y-%m-%dT%H:%M:%S%z").time()
            start_date_obj = datetime.strptime(dateClicked, "%Y-%m-%dT%H:%M:%S%z")
            start_date = start_date_obj.strftime("%Y-%m-%d")
            end_date = start_date_obj.strftime("%Y-%m-%d")
        except ValueError:
            start_time = datetime.now().time()
            start_date_obj = datetime.strptime(dateClicked, "%Y-%m-%d")
            start_date = start_date_obj.strftime("%Y-%m-%d")
            end_date = start_date_obj.strftime("%Y-%m-%d")
        end_time = datetime.combine(date.today(), start_time) + timedelta(hours=1)
        start_time_str = start_time.strftime("%Y-%m-%d %H:%M:%S")
        end_time_str = end_time.strftime("%Y-%m-%d %H:%M:%S")
        return True, start_date, end_date, start_time_str, end_time_str

    elif button_id == "modal_close_new_event_button" and close_clicks is not None:
        return False, dash.no_update, dash.no_update, dash.no_update, dash.no_update

    return opened, dash.no_update, dash.no_update, dash.no_update, dash.no_update


@app.callback(
    Output("calendar", "events"),
    Output("add_modal", "opened", allow_duplicate=True),
    Output("event_name_input", "value"),
    Output("event_color_select", "value"),
    Output("rich_text_input", "value"),
    Input("modal_submit_new_event_button", "n_clicks"),
    State("start_date", "value"),
    State("start_time", "value"),
    State("end_date", "value"),
    State("end_time", "value"),
    State("event_name_input", "value"),
    State("event_color_select", "value"),
    State("rich_text_output", "children"),
    State("calendar", "events"),
)
def add_new_event(
    n,
    start_date,
    start_time,
    end_date,
    end_time,
    event_name,
    event_color,
    event_context,
    current_events,
):
    if n is None:
        raise PreventUpdate

    start_time_obj = datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")
    end_time_obj = datetime.strptime(end_time, "%Y-%m-%d %H:%M:%S")

    start_time_str = start_time_obj.strftime("%H:%M:%S")
    end_time_str = end_time_obj.strftime("%H:%M:%S")

    start_date = f"{start_date}T{start_time_str}"
    end_date = f"{end_date}T{end_time_str}"

    new_event = {
        "title": event_name,
        "start": start_date,
        "end": end_date,
        "className": event_color,
        "context": event_context,
    }

    return current_events + [new_event], False, "", "bg-gradient-primary", ""


@app.callback(
    Output("rich_text_output", "children"),
    [Input("rich_text_input", "value")],
    [State("rich_text_input", "charCount")],
)
def display_output(value, charCount):
    return value


if __name__ == "__main__":
    app.run_server(debug=True, port=8556)

Basically the layout is the calendar component I’ve built out as a package:

fcc.FullCalendarComponent(
            id="calendar",
            initialDate=f"2024-04-01",
            editable=True,
            selectable=True,
            events=[
                {
                    "title": "Pip Install Python",
                    "start": f"{formatted_date}",
                    "end": f"{formatted_date}",
                    "className": "bg-gradient-success",
                    "context": "Pip Install FullCalendar",
                }
            ],
        )

I’ve also created some more complex examples to showcase the full capabilities of this project.

timeGridWeek:


Custom time grid date range (example) timeGridFourDay:


listWeek:


listWeek (multiple initial events):


dayGridWeek:


multiMonthYear (multiMonthMaxColumns=int):


multiMonthYear:


Custom multiMonthYear date range (example):


resourceTimeLineWeek:


resourceTimeGridDay:


dayGridMonth with (navLinks=True, headerToolBar=dic):
pasted-movie

prop - buisnessHours=[dic]:


prop - nowIndicator=True


Setting up time range for events:


Some base improvements I’d like to make in the coming days are the style.css should be automatically included in the pip install, and not needed to be be manually added in the future. Add start time, end day and time for create event modal.

Would appreciate plotly’s team support in taking over this component as fullcalendar.io has Premium api points that I’ve connected that would be useful if a direct collaboration is setup between the two projects https://fullcalendar.io/pricing

For more refrence check out fullcalendar.io directly at: Documentation | FullCalendar

Github project (support with a :star:): GitHub - pip-install-python/full_calendar_component: https://fullcalendar.io/ for Plotly Dash.

Pypi: full-calendar-component · PyPI

Anything else that would be a cool addition just post in the comments and if I find the time I might add it to the project.

Also special thanks to @AnnMarieW, @jinnyzor, @adamschroeder.

Follow me on github:
Pip Install Python GitHub stats
Also if you like this project check out my other dash packages I’ve built:

  1. dash-summernote: Pip install dash-summernote 📝 - #2 by AnnMarieW

  2. dash-swiper: Pip install dash-swiper 🌠

  3. dash-insta-stories: Pip install dash-insta-stories 🐇

  4. dash-emoji-mart: Pip install dash-emoji-mart 😀

Cheers,
Pip

5 Likes

Hello @PipInstallPython,

Is this an AIO component? Or did you wrap the full calendar as a dash component? Was looking for repo.

If it is a wrapped component, you can include it in the component.

If it is an AIO, you can include it in the bundle and app. Check out here for an example:

Originally I attempted:

_css_dist = [{"relative_package_path": "../style.css", "namespace": package_name}]

but it crashed the app, eventually just set _css_dist to a blank list to proceed.

I started the project like 3 weeks ago don’t remember specifically how i set it up, believe it was just following through a base dash-boiler-plate.

Just pushed the repo to github: GitHub - pip-install-python/full_calendar_component: https://fullcalendar.io/ for Plotly Dash.

updated the package to full-calendar-component 0.0.2

  • initialView (supports): dayGridMonth, timeGridWeek, timeGridDay, listWeek, # dayGridWeek, dayGridYear, multiMonthYear, resourceTimeline, resourceTimeGridDay, resourceTimeLineWeek

  • headerToolbar editable directly from fcc.FullCalendarComponent

  • added multiMonthMaxColumns

  • resources editable from fcc.FullCalendarComponent

  • navLink added to fcc.FullCalendarComponent

  • businessHours added to fcc.FullCalendarComponent

  • nowIndicator added to fcc.FullCalendarComponent

1 Like

what a great component @PipInstallPython.

I’m having so much fun playing around with it.

Would it make sense to add all these example codes and images to the Project’s Readme so people can have quick access to them?

Do you know why at the bottom left corner there is a notification: “Your license key is invalid. More Info”. What is this referring to?

I was even able to build an app with this component on WasmDash. Find code below the image (I hope I used the external_stylesheets correcty).

import micropip
await micropip.install('dash-mantine-components')
await micropip.install('dash-quill')
await micropip.install('full-calendar-component==0.0.2')

import full_calendar_component as fcc
from dash import *
import dash_mantine_components as dmc
from dash.exceptions import PreventUpdate
from datetime import datetime
import dash_quill

app = Dash(__name__, prevent_initial_callbacks=True, external_stylesheets=["https://raw.githubusercontent.com/pip-install-python/dash-full-calendar/master/assets/fullcalendar.css"])

quill_mods = [
    [{"header": "1"}, {"header": "2"}, {"font": []}],
    [{"size": []}],
    ["bold", "italic", "underline", "strike", "blockquote"],
    [{"list": "ordered"}, {"list": "bullet"}, {"indent": "-1"}, {"indent": "+1"}],
    ["link", "image"],
    # ['clean'],
]

# Get today's date
today = datetime.now()

# Format the date
formatted_date = today.strftime("%Y-%m-%d")


app.layout = html.Div(
    [
        fcc.FullCalendarComponent(
            id="calendar",
            initialDate=f"2024-04-01",
            editable=True,
            selectable=True,
            events=[
                {
                    "title": "Pip Install Python",
                    "start": f"{formatted_date}",
                    "end": f"{formatted_date}",
                    "className": "bg-gradient-success",
                    "context": "Pip Install FullCalendar",
                }
            ],
        ),
        dmc.Modal(
            id="modal",
            size="xl",
            title="Event Details",
            zIndex=10000,
            children=[
                html.Div(id="modal_event_display_context"),
                dmc.Space(h=20),
                dmc.Group(
                    [
                        dmc.Button(
                            "Close",
                            color="red",
                            variant="outline",
                            id="modal-close-button",
                        ),
                    ],
                    position="right",
                ),
            ],
        ),
        dmc.Modal(
            id="add_modal",
            title="New Event",
            size="xl",
            children=[
                dmc.Grid(
                    children=[
                        dmc.Col(
                            html.Div(
                                dmc.DatePicker(
                                    id="add_modal_date",
                                    label="Start Date",
                                    value=datetime.now().date(),
                                    styles={"width": "100%"},
                                    disabled=True,
                                ),
                                style={"width": "100%"},
                            ),
                            span=6,
                        ),
                        dmc.Col(
                            html.Div(
                                dmc.TextInput(
                                    label="Event Name:",
                                    style={"width": "100%"},
                                    id="event_name_input",
                                    required=True,
                                ),
                                style={"width": "100%"},
                            ),
                            span=6,
                        ),
                    ],
                    gutter="xl",
                ),
                dmc.Select(
                    label="Select event color",
                    placeholder="Select one",
                    id="event_color_select",
                    value="ng",
                    data=[
                        {
                            "value": "bg-gradient-primary",
                            "label": "bg-gradient-primary",
                        },
                        {
                            "value": "bg-gradient-secondary",
                            "label": "bg-gradient-secondary",
                        },
                        {
                            "value": "bg-gradient-success",
                            "label": "bg-gradient-success",
                        },
                        {"value": "bg-gradient-info", "label": "bg-gradient-info"},
                        {
                            "value": "bg-gradient-warning",
                            "label": "bg-gradient-warning",
                        },
                        {"value": "bg-gradient-danger", "label": "bg-gradient-danger"},
                        {"value": "bg-gradient-light", "label": "bg-gradient-light"},
                        {"value": "bg-gradient-dark", "label": "bg-gradient-dark"},
                        {"value": "bg-gradient-white", "label": "bg-gradient-white"},
                    ],
                    style={"width": "100%", "marginBottom": 10},
                    required=True,
                ),
                dash_quill.Quill(
                    id="rich_text_input",
                    modules={
                        "toolbar": quill_mods,
                        "clipboard": {
                            "matchVisual": False,
                        },
                    },
                ),
                dmc.Accordion(
                    children=[
                        dmc.AccordionItem(
                            [
                                dmc.AccordionControl("Raw HTML"),
                                dmc.AccordionPanel(
                                    html.Div(
                                        id="rich_text_output",
                                        style={
                                            "height": "300px",
                                            "overflowY": "scroll",
                                        },
                                    )
                                ),
                            ],
                            value="raw_html",
                        ),
                    ],
                ),
                dmc.Space(h=20),
                dmc.Group(
                    [
                        dmc.Button("Submit", id="modal_submit_new_event_button"),
                        dmc.Button(
                            "Close",
                            color="red",
                            variant="outline",
                            id="modal_close_new_event_button",
                        ),
                    ],
                    position="right",
                ),
            ],
        ),
    ]
)


@app.callback(
    Output("modal", "opened"),
    Output("modal", "title"),
    Output("modal_event_display_context", "children"),
    Input("modal-close-button", "n_clicks"),
    Input("calendar", "clickedEvent"),
    State("modal", "opened"),
)
def open_event_modal(n, clickedEvent, opened):
    ctx = callback_context

    if not ctx.triggered:
        raise PreventUpdate
    else:
        button_id = ctx.triggered[0]["prop_id"].split(".")[0]

    if button_id == "calendar" and clickedEvent is not None:
        event_title = clickedEvent["title"]
        event_context = clickedEvent["extendedProps"]["context"]
        return (
            True,
            event_title,
            html.Div(
                dash_quill.Quill(
                    id="input3",
                    value=f"{event_context}",
                    modules={
                        "toolbar": False,
                        "clipboard": {
                            "matchVisual": False,
                        },
                    },
                ),
                style={"width": "100%", "overflowY": "auto"},
            ),
        )
    elif button_id == "modal-close-button" and n is not None:
        return False, dash.no_update, dash.no_update

    return opened, dash.no_update


@app.callback(
    Output("add_modal", "opened"),
    Output("add_modal_date", "value"),
    Input("calendar", "dateClicked"),
    Input("modal_close_new_event_button", "n_clicks"),
    State("add_modal", "opened"),
)
def open_add_modal(dateClicked, close_clicks, opened):
    ctx = callback_context

    if not ctx.triggered:
        raise PreventUpdate
    else:
        button_id = ctx.triggered[0]["prop_id"].split(".")[0]

    if button_id == "calendar" and dateClicked is not None:
        return True, dateClicked
    elif button_id == "modal_close_new_event_button" and close_clicks is not None:
        return False, dash.no_update

    return opened, dash.no_update


@app.callback(
    Output("calendar", "events"),
    Output("add_modal", "opened", allow_duplicate=True),
    Output("event_name_input", "value"),
    Output("event_color_select", "value"),
    Output("rich_text_input", "value"),
    Input("modal_submit_new_event_button", "n_clicks"),
    State("add_modal_date", "value"),
    State("event_name_input", "value"),
    State("event_color_select", "value"),
    State("rich_text_output", "children"),
    State("calendar", "events"),
)
def add_new_event(n, date, event_name, event_color, event_context, current_events):
    if n is None:
        raise PreventUpdate

    new_event = {
        "title": event_name,
        "start": date,
        "end": date,
        "className": event_color,
        "context": event_context,
    }

    return current_events + [new_event], False, "", "bg-gradient-primary", ""


@app.callback(
    Output("rich_text_output", "children"),
    [Input("rich_text_input", "value")],
    [State("rich_text_input", "charCount")],
)
def display_output(value, charCount):
    return value


if __name__ == "__main__":
    app.run_server(debug=True, port=8257)

Planning on building and hosting an app similar to https://www.dash-mantine-components.com/ and https://www.dash-leaflet.com/ and better defining the readme.md just haven’t had the time. I’ve only put like two days worth of work into the project. Just used this as an initial place to put some context for those interested in playing around and testing it before the official 1.0.0 release.

The license key is in reference to: https://fullcalendar.io/pricing specifically the initialView= ‘timeline’ and ‘vertical resource’ I’ve build out connections to those endpoints, if the plotly team find this useful might be worth reaching out to fullcalendar.io directly from yall’s end and see if we could work out a direct collaboration to support those premium features.

Doesn’t look like the stylesheet was loaded correctly for you, still trying to work out the best way to reference it within _css_dist in the init so its just automatically added for users.

1 Like

A post was split to a new topic: More info on WASM Dash

Updated the package to: full-calendar-component==0.0.3

  • Now supporting Start Time, End Date and End Time based on selection of the day or week grid’s time slots from the fields outlined in the picture

  • Automatically sets up time’s based on a new slotClick={handleTimeClick}

  • Style is automatically provided via the pip install , also trimmed the .css file

  • Changed the modals to reflect improvements in usage.py and styled modals dark for better contrast.

  • Setup style for better mobile viewing

Goals for future 0.0.4 release:

  • Ability to delete events

  • Create a check on add_event fields so they all need to be populated before attempting to create event

  • maybe language support

… any other suggestions just lmk.

2 Likes

Hello @PipInstallPython first of all many thanks for your work!
Though, I encountered the following issue when I try to update the headerToolbar’s title. Updating initialDate’s value does not seem to have any effect on the headerToolbar’s title, and the calendar’s date view.

On the other hand prev and next buttons work well. What I want to do here is to set a new date using a date picker start_date attribute, and update the calendar’s view based on start_date changes.

Here is the relevant layout and callback part of my code:

    @app.callback(
        Output("calendar", "initialDate"),
        Input("datepickerrange-limits", "start_date"),
    )
    def update_initial_date(start_date: str) -> str:
        if start_date is None:
            raise PreventUpdate
        formated_date = datetime.fromisoformat(start_date).strftime("%Y-%m-%d")
        return formated_date
        fcc.FullCalendarComponent(
            id="calendar",  # Unique ID for the component
            initialView="dayGridMonth",  # dayGridMonth, timeGridWeek, timeGridDay, listWeek,
            # dayGridWeek, dayGridYear, multiMonthYear, resourceTimeline, resourceTimeGridDay, resourceTimeLineWeek
            headerToolbar={
                "left": "prev,next today",
                "center": "title",
                "right": "listWeek,timeGridDay,timeGridWeek,dayGridMonth",
            },  # Calendar header
            initialDate=f"{formatted_date}",  # Start date for calendar
            editable=True,  # Allow events to be edited
            selectable=True,  # Allow dates to be selected
            events=[],
            nowIndicator=True,  # Show current time indicator
            navLinks=True,  # Allow navigation to other dates
        ),

Thanks in advance for your help!
Best,

Hey @clemen ,

Welcome to the plotly form. At the moment their is no gotoDate or an equivalent start_date prop setup so you can’t define a date via a date picker and use that to change the display of the calendar. Once a calendar is rendered, whatever you set as the initialDate is what it will always render on.

However the headertoolbar title seems to be working for me, its based on the initialDate, you can try initialDate=f"2024-01-17" and you’ll see July 17 within the title, also looks like you set it up correctly with the:

headerToolbar={
                "left": "prev,next today",
                "center": "title",
                "right": "listWeek,timeGridDay,timeGridWeek,dayGridMonth",
            }

So not an ideal response, can only confirm no way of changing a date of a calendar’s render from an outside component after its been rendered. But the title should work. However I’ll look into building a start_date or gotoDate prop and see if I can get a solution setup for the next release.

1 Like

thank you !!! so much I love you so moch ever!!
i have a question !!

“your license key is invalid. More Info” comment comes out ofter publish
is it not free??

Hey Nick,

Most of the calendar is free, their is a timeline-view, that I have showcased - you can learn more about here: Timeline View - Docs | FullCalendar . This aspect of full calendar is not free and needs a license. In the repo, I included the endpoints to connect to some of the paid features for any enterprise users and as a hopeful way to get plotly to :crossed_fingers: hopefully network with full calendar directly and get a partnership worked out. Maybe with more community interest the component could evolve further.

1 Like

but… Now I’d like to hide that “your license key is invalid. More Info” comment… may I…?

Sure, currently on 0.0.3 but you could try 0.0.2 or 0.0.1 if neither of those work let me know and ill take a look into it

Hello @PipInstallPython, about the license I tested 0.0.2 and the problem is remaining, with 0.0.1 my whole app breaks. Do you have any advise on how I could adapt the latest version so it gets rid of the premium end points and thus the license problems?
Thank you very much!

Fork the repo:

npm uninstall @fullcalendar/resource-timeline
npm uninstall @fullcalendar/resource-timegrid

remove both resource-timegrid and resource-timeline from the FullCalendarComponent.react.js

npm run build

pip install -r requirements.txt

run usage.py to test it out

from https://fullcalendar.io/pricing it looks like Timeline View and
Vertical Resource View are the only two views that could be causing the problem.

Once you have npm and pip setyp, mainly be working within rebuilding FullCalendarComponent.react.js and running python usage.py to test the changes you make.

Would avoid using 0.0.1, many things where broken on the first release :sweat_smile:

Thank you very much, worked perfectly!!

1 Like

sir!! i’m using 0.0.3 but i don’t know how to remove timegrid, timeline for hide a licence message

i can’t see ‘FullCalendarComponent.react.js’ file …

Upgrade to 0.0.4, just pushed an update that removes:

@fullcalendar/resource-timeline
@fullcalendar/resource-timegrid

which also removes the license message.

Also made changes to allow the prop business hours for the calendar and changed the styling to reflect blacking out days and hours which are not in the business hours. Example code:

from dash import *
import full_calendar_component as fcc
from datetime import datetime

# Get today's date
today = datetime.now()

# Format the date
formatted_date = today.strftime("%Y-%m-%d")

events = [
    {
        'title': 'All Day Event',
        'start': f'{formatted_date}T01:00:00',
        'end': f'{formatted_date}T02:00:00',
        'className': 'bg-info',
        'context': 'Welcome to my packages.'
    },
]


fcc.FullCalendarComponent(
            id="calendar",  # Unique ID for the component
            initialView="listWeek",  # dayGridMonth, timeGridWeek, timeGridDay, listWeek,
            # dayGridWeek, dayGridYear, multiMonthYear, resourceTimeline, resourceTimeGridDay, resourceTimeLineWeek
            headerToolbar={
                'start': '',
                "left": "prev,next today",
                "center": 'title',
                "right": "listWeek,timeGridDay,timeGridWeek,dayGridMonth",
            },  # Calendar header
            initialDate=f"{formatted_date}",  # Start date for calendar
            editable=True,  # Allow events to be edited
            selectable=True,  # Allow dates to be selected
            events=events,
            nowIndicator=True,  # Show current time indicator
            navLinks=True,  # Allow navigation to other dates
            businessHours=[{
                    'daysOfWeek': [1, 2, 3, 4, 5],  # Monday, Tuesday, Wednesday, Thursday, Friday
                    'startTime': '10:00',  # Business start time
                    'endTime': '18:00',  # Business end time
                }],
        )

Oh my …
Literally you are my GOD Thanks

2024년 6월 22일 (토) 오전 1:37, Pip Install Python via Plotly Community Forum <notifications@plot.discoursemail.com>님이 작성:

1 Like