FullCalendar in GWT : How to refresh calendar while keeping events

130 Views Asked by At

I'm working on a GWT application using Domino/UI, Nalukit and the Javascript plugin FullCalendar v6. I made a custom popup to modify and delete an event but when I validate the form, my calendar refreshes and all the event in my week view disappear.

Demo of the app running

I used the native function gotoDate to change to view of the calendar to the event's modified date.

Here's a sample from my controller's render and refreshCalendar methods :

    @Override
    public void render() {

        // Styling related lines omitted

        FcOptionOverrides mainOptions = new FcOptionOverrides();
        mainOptions.locale = "fr";
        mainOptions.initialView = "timeGridWeek";
        mainOptions.views = new FcViewOptions();
        mainOptions.views.timeGridWeek = new FcView();
        mainOptions.views.timeGridWeek.weekends = true;
        mainOptions.views.timeGridWeek.slotMinTime = "07:00:00";
        mainOptions.views.timeGridWeek.slotMaxTime = "22:00:00";
        mainOptions.eventSources = new FcEventSources();
        mainOptions.eventSources.events = this.getController()::onEventNeedMain;
        mainOptions.datesSet = this::onDatesSet;
        
        mainOptions.eventDidMount = this::onEventDidMount;
        mainOptions.dateClick = this::onBigCalendarDateClick;

        mainCalendar = new FcCalendar(mainAgendaContainer, mainOptions);

        FcOptionOverrides smallOptions = new FcOptionOverrides();
        smallOptions.locale = "fr";
        smallOptions.initialView = "dayGridMonth";
        smallOptions.height = "330px";
        smallOptions.aspectRatio = 1.0f;
        smallOptions.eventSources = new FcEventSources();
        smallOptions.eventSources.events = this.getController()::onEventNeedSmall;

        smallOptions.dateClick = this::onSmallCalendarDateClick;

        smallCalendar = new FcCalendar(smallAgendaContainer, smallOptions);

        // radio button for displaying week-ends
        RayflexRadio displayWeekendRadio = new RayflexRadio("weekends", "Week-ends", "Afficher", "Masquer");
        displayWeekendRadio.style("position:absolute; top:18px; right:230px;");
        displayWeekendRadio.addChangeHandler(event -> {

            if (displayWeekendRadio.getValue()) {

                DominoElement.of(mainAgendaContainer).removeCss(RxResource.INSTANCE.gss().calendar_main_no_weekends());
                DominoElement.of(mainAgendaContainer).css(RxResource.INSTANCE.gss().calendar_main());

            } else {

                DominoElement.of(mainAgendaContainer).removeCss(RxResource.INSTANCE.gss().calendar_main());
                DominoElement.of(mainAgendaContainer).css(RxResource.INSTANCE.gss().calendar_main_no_weekends());

            }
            displayWeekEnds = displayWeekendRadio.getValue();
            refreshCalendar();

        });

        displayWeekendRadio.setValue(displayWeekEnds);

        card.getBody().appendChild(displayWeekendRadio.element());

        initElement(card.element());
    }

 @Override
    public void refreshCalendar() {

        if (lastModifiedEvent != null) {
            
            Date beginDate = lastModifiedEvent.getBeginDate();
            JsDate jsDate = new JsDate(1900 + beginDate.getYear(), beginDate.getMonth(), beginDate.getDate());

            mainCalendar.gotoDate(jsDate);
            smallCalendar.gotoDate(jsDate);
        }
        
        mainCalendar.refetchEvents();
    }

Here's my wrapper class for FullCalendar's JS functions :

package com.alara.rayflex.ui.client.calendar;

import elemental2.core.JsDate;
import elemental2.dom.Element;
import jsinterop.annotations.JsType;

@JsType(isNative = true, namespace = "FullCalendar", name="Calendar")
public class FcCalendar {

    public FcCalendar(Element root) {}
    
    public FcCalendar(Element root, FcOptionOverrides optionOverrides) {}
    
    public native void render();
    public native void updateSize();
    
    public native void gotoDate(JsDate start);
    public native JsDate getDate();
    
    public native void setOption(String name, String value);
    public native void setOption(String name, int value);
    
    public native void select(JsDate date);
    
    public native void refetchEvents();
    
    public native void addEventSource(FcOnEventNeed needEvent);
    
    public native void changeView(String viewName, JsDate dateOrRange);
}

I tried to force the native javascript functions refetchEvents with gotoDate but I got the same result. Then I tried using addEventSource to restore my events but still no success there.

I'm expecting to rerender my calendar with the events of the week which the event has been modified.

1

There are 1 best solutions below

0
On BEST ANSWER

Solved my issue by loading the events in a callback and refetching them in my refreshCalendar method :

@Override
public void refreshCalendar() {

    if (lastModifiedEvent != null)
        
        moveToLastEventModifiedDate();

    else
    
        mainCalendar.refetchEvents();         
}

/**
 * Use the last modified event to move the calendar to its begin date
 * then fetch the events to load them again in the calendar component 
 */
public void moveToLastEventModifiedDate() {
    
    Date eventDate = lastModifiedEvent.getBeginDate();
    JsDate jsEventDate = new JsDate(1900 + eventDate.getYear(), eventDate.getMonth(), eventDate.getDate());
    
    Date previousMonday = DateUtils.getPreviousMonday(eventDate);
    Date nextMonday = DateUtils.getNextMonday(eventDate);

    JsDate jsDateBegin = new JsDate(1900 + previousMonday.getYear(), previousMonday.getMonth(), previousMonday.getDate());
    JsDate jsDateEnd = new JsDate(1900 + nextMonday.getYear(), nextMonday.getMonth(), nextMonday.getDate());

    mainCalendar.gotoDate(jsEventDate);
    smallCalendar.select(jsEventDate);

    FcEventFetchInfo info = new FcEventFetchInfo();
    info.start = jsDateBegin;
    info.end = jsDateEnd;
    
    this.getController().onEventNeedMain(info, success -> {
        mainCalendar.setOption("events", fcOnEventNeed);
        mainCalendar.refetchEvents();
        
    }, failure -> {
        
        ErrorManager.displayServerError("event.list", failure.message, getController().getEventBus());
    });

    lastModifiedEvent = null;
}