FullCalendar在GWT中:如何刷新日历并保留事件

huangapple go评论65阅读模式
英文:

FullCalendar in GWT : How to refresh calendar while keeping events

问题

我正在使用GWT应用程序开发,使用Domino/UINalukit和JavaScript插件FullCalendar v6。我创建了一个自定义弹出窗口,用于修改和删除事件,但当我验证表单时,我的日历会刷新,我的周视图中的所有事件都消失了。

应用程序运行的演示

我使用了本机函数 gotoDate 来更改日历的视图以匹配事件的修改日期。

以下是我的控制器中 renderrefreshCalendar 方法的示例代码:

@Override
public void render() {

    // 省略了与样式相关的代码

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

    // 用于显示周末的单选按钮
    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();
}

这是我用于FullCalendar的JS函数的包装类:

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

我尝试使用 gotoDate 强制本机JavaScript函数 refetchEvents,但结果相同。然后我尝试使用 addEventSource 来恢复我的事件,但仍然没有成功。

我期望重新渲染我的日历,以显示已修改事件所在周的事件。

英文:

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

得分: 0

通过在回调中加载事件并在refreshCalendar方法中重新获取它们,解决了我的问题:

@Override
public void refreshCalendar() {

    if (lastModifiedEvent != null)
        
        moveToLastEventModifiedDate();

    else
    
        mainCalendar.refetchEvents();         
}

/**
 * 使用最后修改的事件来将日历移动到其开始日期
 * 然后再次获取事件以将它们加载到日历组件中
 */
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;
}

希望这可以帮助您解决问题。

英文:

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

huangapple
  • 本文由 发表于 2023年6月1日 18:19:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76380894.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定