Schedule – Lazy – очень удобный компонент на основе FullCalendar. Расмотрим что может и чего не хватает. |
Prime Faces предлагает нашему вниманию этот компонент. Он классно подойдетв палне органайзера, календаря. Вы можете добавлять события и визуально ихнаблюдать. Компонент поддерживает lazy loading – и это безусловно плюс.Если вы показываете только один месяц, нет смысла грузить все события, например с БДКак все настроить вы на йдете на сайте Prime Faces, там множество настроек, также поддержа локализаций. Вы можете выбирать вид для просмотра событий, или в режиме месяц,неделя, день. На первый взгляд – что еще можно хотеть от этого компонента, но давайтекопнем поглубже. |

Представим что у нас есть в БД таблица откуда мы грузим наши события. С нужным нам периодом, или это месяц, день, неделя. С lazy loading ситуация следующая, если мы загрузи сначала вид день, мы мы взяли события за выбраной нами день. Потом берем неделю, грузим с БД за неделю. Потом взяли месяц – загрузили с БД за месяц. А потом если мы гуляем в предялах этого месяца, мы ничего не грузим с БД, компонент после месяца все себе сохранил и больше не нужно ему лезть в БД и грузить наше приложение запросами. Все прекрасно и рационально. Но есть один минус, если вы выбрали месяц(как на примере) ноябрь и у нас не только отображаются дни этого месяца но и пару с предедущего 27-31 октября. Вопросс, если я вижу месяц ноябрь, зачем мне события за октябрь. Ведь компонент загрузит события за все дни что отображаются. Кому то это не покажется серьезной проблемой, но мне пришлось с ней бороться. Есть ситуации когда лишние ди были как с переди так и в конце месяца. Но это не главное, если кто хочет может с этим бороться…. (я таки победил эту ситуацию)
Но давайте смоделируем ситуацию, что вы хоти на странице иметь два компонента calendar где отображать интервалы которые выбраны в Schedule. Тоесть поменяли вид и ваши отрезки с интервалами тоже меняются. Например: вы выбрали 2 октября и видите интервал с 2 – октября по 2 октября; вы выбрали 7-13 октября и видите этот интервал; выбрали месяц и видите начало и конец месяца. Проблема следующая, когда вы начнете с дня и до месяца компонент будет вызывать метод для загрузки событий и вы имеете доступ к датами компонента
@Override
public void loadEvents(Date start, Date end) {
start - начало
end - конец
}
Все прекрасно используйте их и обновляйте свои calendar но если только вы загрузите месяц целиком. Вы не зайдете в этот метод и не сможете контролировать даты. Они у вас всегда будут начало и конец месяца. Тоесть после месяца Вы не сделаете интервал для Ваших calendar – неделю. Там уже работает JS и серверного доступа у Вас нет. Что же тогда делать?
Выход есть – переписать обработчики для кнопок переключения видов, кнопка вперед, назад, сегодня.
Сначала прячем стандартные кнопки указав свойства Schedule
rightHeaderTemplate="none"
leftHeaderTemplate="none"
Тогда добавлем наши кнопки
<p:commandButton update=":mainForm:scheduler" actionListener="#{planner.nextPrevious}" proces="@this">
<f:attribute name="increment" value="previous" />
</p:commandButton>
<p:commandButton update=":mainForm:scheduler" actionListener="#{planner.nextPrevious}" proces="@this">
<f:attribute name="increment" value="next" />
</p:commandButton>
<p:commandButton value="Месяц" update=":mainForm:scheduler" actionListener="#{planner.selectView}" process="@this">
<f:attribute name="view" value="month" />
</p:commandButton>
<p:commandButton value="Неделя" update=":mainForm:scheduler" actionListener="#{planner.selectView}" process="@this">
<f:attribute name="view" value="agendaWeek" />
</p:commandButton>
<p:commandButton value="День" update=":mainForm:scheduler" actionListener="#{planner.selectView}" process="@this">
<f:attribute name="view" value="agendaDay" />
</p:commandButton>
Нам нужно только написать метод для actionListenera в нашем случае это метод selectView(). Для себя я в коде сделал еще один Schedule для того чтоб сохранять копию того что у нас на фронте. Если мы меняем виды на фронте то они меняются но после update они не сохраняются, а так мы можем себе их сохранять и всегда знать что мы имеем. Переходим к коду:
public void selectView(ActionEvent event) {
initScgedulemodelView(false);
String view = (String) event.getComponent().getAttributes().get("view");
this.getModel().setView(view);
this.getModel().setInitialDate(getScheduleModel().getInitialDate());
this.scheduleModel.setView(view);
}
private void initScgedulemodelView(boolean start) {
if (getScheduleModel() == null) {
setScheduleModel(new Schedule());
getScheduleModel().setView(getModel().getView());
getScheduleModel().setInitialDate(start == true ? new Date() : getModel().getInitialDate());
getModel().setInitialDate(getScheduleModel().getInitialDate());
}
}
public Schedule getModel() {
Schedule d = (Schedule) FacesContext.getCurrentInstance().getViewRoot().findComponent("mainForm:scheduler");
return d;
}
public void nextPrevious(ActionEvent event) {
initScgedulemodelView(false);
String increment = (String) event.getComponent().getAttributes().get("increment");
int moveValue = increment.equals("next") ? 1 : -1;
Calendar cal = Calendar.getInstance();
cal.setTime((Date) this.getScheduleModel().getInitialDate());
if (this.getScheduleModel().getView().equals(agendaDay))
cal.add(Calendar.DAY_OF_MONTH, moveValue);
else if (this.getScheduleModel().getView().equals(agendaWeek))
cal.add(Calendar.WEEK_OF_MONTH, moveValue);
else if (this.getScheduleModel().getView().equals(month))
cal.add(Calendar.MONTH, moveValue);
this.getModel().setView(getScheduleModel().getView());
this.getModel().setInitialDate(cal.getTime());
this.getScheduleModel().setInitialDate(cal.getTime());
}
public void today(ActionEvent event) {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
this.getModel().setView("agendaDay");
this.getModel().setInitialDate(cal.getTime());
this.getScheduleModel().setInitialDate(cal.getTime());
this.getScheduleModel().setView("agendaDay");
}
Ну вот и все, имеем доступ к смене видов всегда и делаем что хотим. Добились того чего хотели. Кажды может код подогнать под свои потребности, но для меня этот код помого выполнть поставленую задачу. Удачи всем в кодинге!!!