Schedule – Lazy

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

Ну вот и все, имеем доступ к смене видов всегда и делаем что хотим. Добились того чего хотели. Кажды может код подогнать под свои потребности, но для меня этот код помого выполнть поставленую задачу. Удачи всем в кодинге!!!

Please follow and like us:

Leave a Comment