1

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.

  • When you modify events, are you storing them anywhere else except just in fullCalendar? You would need to save them somewhere, such as in a database. – ADyson Jun 01 '23 at 11:47
  • They are saved in a database, I have server actions dealing with this matter but the issue there isn't about saving events or retrieving them from the DB but rather rerendering the calendar with the events. This behavior works when switching from a week to another or by clicking on a date in the small calendar then the main calendar refreshes with the expected events. – Loïc LEPRIEUR Jun 01 '23 at 12:10
  • I guess the issue comes from my implementation of the popup : there has to be something messing with the refresh when it closes – Loïc LEPRIEUR Jun 01 '23 at 12:27
  • @ADyson I've added a GIF in my post to show you what's happening – Loïc LEPRIEUR Jun 01 '23 at 12:47

1 Answers1

0

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;
}