I'm having the same issue on my side. As far as I can tell, the issue lies with the Bean constructor being called twice when the page loads and a third time when the user selects an Event. Re-instantiating means the EventModel's event list will have different memory locations before and after the EventSelect is fired.
I've tried using ViewScope, SessionScope and no scope specified and none of these change the triple instantiation.
schedule.xhtml
Code: Select all
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:jsfcal="http://code.google.com/p/jsfcal">
<h:body>
<ui:composition template="templates/main.xhtml">
<ui:define name="headLinks">
<title><h:outputText value="#{msg.schedulepagetitle}"/></title>
<script type="text/javascript">
$(document).ready(function(){
$("#n01").addClass("first select");
$('.standard_table tr:even').addClass('even');
})
</script>
</ui:define>
<ui:define name="content">
<h:form>
<p:ajaxStatus style="height:24px;display:block;">
<f:facet name="start">
<h:graphicImage value="../design/ajaxloading.gif" />
</f:facet>
<f:facet name="complete">
<h:outputText value="" />
</f:facet>
</p:ajaxStatus>
<!--<p:messages id="msgs" showDetail="false"/>-->
<p:growl id="messages" showDetail="true" />
<p:schedule value="#{scheduleBean.eventModel}"
editable="true" widgetVar="myschedule"
eventSelectListener="#{scheduleBean.onEventSelect}"
dateSelectListener="#{scheduleBean.onDateSelect}"
eventMoveListener="#{scheduleBean.onEventMove}"
eventResizeListener="#{scheduleBean.onEventResize}"
onEventMoveUpdate="msgs" onEventResizeUpdate="msgs"
onDateSelectUpdate="eventDetails" onDateSelectComplete="eventDialog.show()"
onEventSelectUpdate="eventDetails" onEventSelectComplete="eventDialog.show()"/>
<p:dialog widgetVar="eventDialog" header="#{msg.addeditschedule}" showEffect="clip" hideEffect="clip" width="400">
<p:panel>
<h:panelGrid columns="2">
<h:outputLabel for="txttitle" value="#{msg.title}" />
<h:inputText id="txttitle" style="#{msg.mediuminputstyle}"
value="#{scheduleBean.appt.title}"
required="true" requiredMessage="#{msg.titlereq}"
size="200"/>
<h:outputLabel for="txtdescription" value="#{msg.description}" />
<h:inputTextarea id="txtdescription" styleClass="dnatextarea"
value="#{scheduleBean.appt.description}"
required="true" requiredMessage="#{msg.descriptionreq}"/>
<h:outputLabel for="cmbscheduletype" value="#{msg.scheduletype}" />
<h:selectOneMenu id="cmbscheduletype" value ="#{scheduleBean.scheduleTypeStr}">
<f:selectItems value="#{scheduleBean.scheduleTypeListWithPleaseSelect}"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputLabel for="txtstartdate" value="#{msg.startdate} (#{msg.datepattern})" />
<h:outputLabel for="txtstarttime" value="#{msg.starttime} (#{msg.timepattern})" />
<p:calendar showOn="#{msg.dateshowon}" effect="#{msg.dateeffect}"
id="txtstartdate" value="#{scheduleBean.startDate}"
required="true" requiredMessage="#{msg.startdatereq}" inputStyleClass="dnadate"
pattern="#{scheduleBean.verticalDNASystem.dateformat}">
</p:calendar>
<h:inputText id="txtstarttime" style="#{msg.timeinputstyle}"
value="#{scheduleBean.startDate}"
required="true" requiredMessage="#{msg.starttimereq}" size="5">
<f:convertDateTime type="time" timeStyle="short" timeZone="#{msg.timezone}"/>
</h:inputText>
<h:outputLabel for="txtenddate" value="#{msg.enddate} (#{msg.datepattern})" />
<h:outputLabel for="txtendtime" value="#{msg.endtime} (#{msg.timepattern})" style="text-align:left" />
<p:calendar showOn="#{msg.dateshowon}" effect="#{msg.dateeffect}"
id="txtenddate" value="#{scheduleBean.endDate}" inputStyleClass="dnadate"
pattern="#{scheduleBean.verticalDNASystem.dateformat}"/>
<h:inputText id="txtendtime" style="#{msg.timeinputstyle}"
value="#{scheduleBean.endDate}"
required="true" requiredMessage="#{msg.endtimereq}"
size="5">
<f:convertDateTime type="time" timeStyle="short" timeZone="#{msg.timezone}" />
</h:inputText>
</h:panelGrid>
<!-- <h:panelGrid columns="3">
<h:outputLabel for="txtevery" value="Every #" />
<h:outputLabel for="cmbrepeatcode" value="Frequency" />
<h:outputLabel for="cmbmonthlyrepeat" value="Day of Month" />
<h:inputText id="txtevery" style="#{msg.smallinputstyle}" value="#{scheduleBean.appt.repeatcount}">
<f:convertNumber type="number" maxIntegerDigits="3"/>
</h:inputText>
<h:selectOneMenu id="cmbrepeatcode" value ="#{scheduleBean.appt.repeatcode}">
<f:selectItems value="#{scheduleBean.repeatCodeListWithPleaseSelect}"/>
</h:selectOneMenu>
<h:selectOneMenu id="cmbmonthlyrepeat" value="#{scheduleBean.appt.monthlyrepeatcode}">
<f:selectItems value="#{scheduleBean.monthlyRepeatCodeListWithPleaseSelect}"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="1">
<h:selectManyCheckbox id="chkdays" value="#{scheduleBean.days}">
<f:selectItems value="#{scheduleBean.daysList}"/>
</h:selectManyCheckbox>
</h:panelGrid>-->
<h:panelGrid columns="2" styleClass="standard_table" columnClasses="output_label,output_value" cellspacing="0">
<f:facet name="footer">
<h:panelGroup style="display:block; text-align:center">
<p:commandButton type="reset" value="Reset" styleClass="stdButton" image="ui-icon ui-icon-cancel"/>
<p:commandButton oncomplete="myschedule.update(); eventDialog.hide();" action="#{scheduleBean.addSchedule}"
value="#{msg.add}" ajax="false" styleClass="stdButton" image="ui-icon ui-icon-save"/>
</h:panelGroup>
</f:facet>
</h:panelGrid>
</p:panel>
<!--
<h:panelGrid id="eventDetails" columns="2">
<h:outputLabel for="title" value="Title:" />
<p:inputText id="title" value="#{scheduleBean.event.title}" />
<h:outputLabel for="from" value="From:" />
<p:inputMask id="from" mask="99/99/9999"
value="#{scheduleBean.event.startDate}" >
<f:convertDateTime pattern="dd/MM/yyyy" />
</p:inputMask>
<h:outputLabel for="to" value="To:" />
<p:inputMask id="to" mask="99/99/9999"
value="#{scheduleBean.event.endDate}" >
<f:convertDateTime pattern="dd/MM/yyyy" />
</p:inputMask>
<p:commandButton type="reset" value="Reset" />
<p:commandButton value="Save"
oncomplete="myschedule.update();eventDialog.hide();"
actionListener="#{scheduleBean.addEvent}" />
</h:panelGrid>
-->
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
</h:body>
</html>
ScheduleBean.java
Code: Select all
package com.verticaldna.beans;
import com.ivedha.crplatform.entityhandler.ScheduleHandler;
import com.ivedha.crplatform.persistence.entity.verticaldna.Accessinfo;
import com.ivedha.crplatform.persistence.entity.verticaldna.Lookupscheduletype;
import com.ivedha.crplatform.persistence.entity.verticaldna.Schedule;
import com.verticaldna.web.common.DNAConstants;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.primefaces.event.DateSelectEvent;
import org.primefaces.event.ScheduleEntryMoveEvent;
import org.primefaces.event.ScheduleEntryResizeEvent;
import org.primefaces.event.ScheduleEntrySelectEvent;
import org.primefaces.model.DefaultScheduleEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleEvent;
import org.primefaces.model.ScheduleModel;
@ViewScoped
public class ScheduleBean extends CommonWebBean {
private List<DefaultScheduleEvent> searchResults;
private ScheduleModel eventModel;
private ScheduleEvent event = new DefaultScheduleEvent();
private Schedule appt = new Schedule();
private Date startSearchRange = null;
private Date endSearchRange = null;
private Date startDate = null;
private Date endDate = null;
private String scheduleTypeStr;
private String days[] = new String[0];
private boolean searched = false;
public ScheduleBean() {
// Retrieve default list of Schedules based on Month and User
System.out.println("!!!!I'm instantiating the Schedule Bean!!!!");
eventModel = new DefaultScheduleModel();
scheduleSearch();
}
public void addEvent(ActionEvent actionEvent) {
if (event.getId() == null) {
eventModel.addEvent(event);
} else {
eventModel.updateEvent(event);
}
event = new DefaultScheduleEvent();
}
public void addSchedule() {
try {
searched = false;
appt.setLookupscheduletype(new Lookupscheduletype(Long.parseLong(scheduleTypeStr)));
Long currentuserid = new UserInfoBean().getSessionUser().getAccessInfoId();
if (appt.getLookupscheduletype().equals(pleaseselect.getValue())) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, this.getMessage("scheduletypereq"), null));
return; //"schedulexhtml";
}
//Lookupscheduletype aScheduletype = new LookupscheduletypeJpaController().findLookupscheduletype(Long.parseLong(scheduleTypeID));
//TODO - Convert dropdown selection to proper Identity
ScheduleHandler wsh = new ScheduleHandler();
appt.setAccessinfo(new Accessinfo(currentuserid));
appt.setStarttime(startDate);
appt.setEndtime(endDate);
wsh.addSchedule(appt);
setObjectToSession(DNAConstants.SCHEDULE_ID, appt.getId());
String outStr = "ID=" + appt.getId() + ", Title=" + appt.getTitle() + ", Desc=" + appt.getDescription()
+ ", StTime=" + appt.getStarttime().toString() + ", EnTime=" + appt.getEndtime().toString()
+ ", AccID=" + appt.getAccessinfo().getAccessinfoid() + ", Type=" + appt.getLookupscheduletype().getId();
System.out.println(outStr);
// Add the PrimeFaces Event object
DefaultScheduleEvent e = new DefaultScheduleEvent(appt.getTitle(), appt.getStarttime(), appt.getEndtime(), appt);
eventModel.addEvent(e);
//return "schedulexhtml";
} catch (Exception ex) {
System.out.println(ex.toString());
}
}
public void clearEvent() {
event = new DefaultScheduleEvent();
appt = new Schedule();
}
public void onEventSelect(ScheduleEntrySelectEvent selectEvent) {
System.out.println("-=-=-BEGIN EVENT SELECTION BINDING-=-=-");
System.out.println("SelectEvent=" + selectEvent.getScheduleEvent().toString());
System.out.println("EventID=" + selectEvent.getScheduleEvent().getId() + " Title=" + selectEvent.getScheduleEvent().getTitle());
event = selectEvent.getScheduleEvent();
System.out.println("Event Start=" + event.getStartDate().toString() + " Event End=" + event.getEndDate().toString());
startDate = event.getStartDate();
endDate = event.getEndDate();
if (event.getData() != null) {
System.out.println("SchID=" + event.getData().toString());
appt = new Schedule((Long)event.getData());
}
}
public void onDateSelect(DateSelectEvent selectEvent) {
event = new DefaultScheduleEvent(Math.random() + "", selectEvent.getDate(), selectEvent.getDate());
appt = new Schedule();
appt.setStarttime(selectEvent.getDate());
appt.setEndtime(selectEvent.getDate());
}
public void onEventMove(ScheduleEntryMoveEvent event) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Event moved", "Day delta:" + event.getDayDelta() + ", Minute delta:" + event.getMinuteDelta());
addMessage(message);
}
public void onEventResize(ScheduleEntryResizeEvent event) {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Event resized", "Day delta:" + event.getDayDelta() + ", Minute delta:" + event.getMinuteDelta());
addMessage(message);
}
private void addMessage(FacesMessage message) {
FacesContext.getCurrentInstance().addMessage(null, message);
}
// methods
public void scheduleSearch() {
if (!searched) {
Long currentuserid = new UserInfoBean().getSessionUser().getAccessInfoId();
// If no date range is specified, grab this month
if (this.startSearchRange == null) {
// Grab today's date and force the date to the first of the month
Calendar start = Calendar.getInstance();
start.set(Calendar.DAY_OF_MONTH, 1);
start.set(Calendar.HOUR_OF_DAY, 0);
start.set(Calendar.MINUTE, 0);
startSearchRange = start.getTime();
//System.out.println("Search Start=" + startSearchRange.toString());
}
if (this.endSearchRange == null) {
// Take the first of the current month, add a month, subtract a day to get the end of the month
Calendar end = Calendar.getInstance();
end.set(Calendar.DAY_OF_MONTH, 1);
end.set(Calendar.MONTH, end.get(Calendar.MONTH) + 1);
end.set(Calendar.DAY_OF_MONTH, end.get(Calendar.DAY_OF_MONTH) - 1);
end.set(Calendar.HOUR_OF_DAY, 0);
end.set(Calendar.MINUTE, 0);
endSearchRange = end.getTime();
//System.out.println("Search End=" + endSearchRange.toString());
}
List<Schedule> schList = new ScheduleHandler().findSchedules(currentuserid, startSearchRange, endSearchRange);
//System.out.println("Search Result Size=" + schList.size());
for (int x = 0; x < schList.size(); x++) {
eventModel.addEvent(new DefaultScheduleEvent(
schList.get(x).getTitle(), schList.get(x).getStarttime(), schList.get(x).getEndtime(), schList.get(x).getId()));
//System.out.println("Event Start=" + e.getStartDate() + " End=" + e.getEndDate() + " DataClass=" + e.getData().getClass());
}
}
}
// public String addschedulexhtml() {
// return "addschedulexhtml";
// }
//
// public String schedulexhtml() {
// return "schedulexhtml";
// }
//
// public String editschedulexhtml() {
// FacesContext context = FacesContext.getCurrentInstance();
// Long id = Long.parseLong((String) context.getExternalContext().getRequestParameterMap().get("scheduleid"));
// setObjectToSession(DNAConstants.SCHEDULE_ID, id);
// return "editschedulexhtml";
// }
//Getters and Setters
public List<DefaultScheduleEvent> getSearchResults() {
return searchResults;
}
public ScheduleEvent getEvent() {
return event;
}
public void setEvent(ScheduleEvent event) {
this.event = event;
}
public ScheduleModel getEventModel() {
return eventModel;
}
public void setEventModel(ScheduleModel model) {
this.eventModel = model;
}
public Schedule getAppt() {
return appt;
}
public void setAppt(Schedule appt) {
this.appt = appt;
}
public String[] getDays() {
return days;
}
public void setDays(String[] days) {
this.days = days;
}
public String getScheduleTypeStr() {
return this.scheduleTypeStr;
}
public void setScheduleTypeStr(String type) {
this.scheduleTypeStr = type;
}
public Date getStartDate() {
return this.startDate;
}
public void setStartDate(Date value) {
Calendar inVal = null;
Calendar newVal = null;
inVal.setTime(value);
newVal.setTime(this.startDate);
System.out.print("StartYear=" + inVal.get(Calendar.YEAR));
if (inVal.get(Calendar.YEAR) == 0) {
newVal.set(Calendar.HOUR_OF_DAY, inVal.get(Calendar.HOUR_OF_DAY));
newVal.set(Calendar.MINUTE, inVal.get(Calendar.MINUTE));
} else {
newVal.set(Calendar.YEAR, inVal.get(Calendar.YEAR));
newVal.set(Calendar.MONTH, inVal.get(Calendar.MONTH));
newVal.set(Calendar.DATE, inVal.get(Calendar.DATE));
}
this.startDate = newVal.getTime();
}
public Date getEndDate() {
return this.endDate;
}
public void setEndDate(Date value) {
Calendar inVal = null;
Calendar newVal = null;
inVal.setTime(value);
newVal.setTime(this.startDate);
System.out.print("EndYear=" + inVal.get(Calendar.YEAR));
if (inVal.get(Calendar.YEAR) == 0) {
newVal.set(Calendar.HOUR_OF_DAY, inVal.get(Calendar.HOUR_OF_DAY));
newVal.set(Calendar.MINUTE, inVal.get(Calendar.MINUTE));
} else {
newVal.set(Calendar.YEAR, inVal.get(Calendar.YEAR));
newVal.set(Calendar.MONTH, inVal.get(Calendar.MONTH));
newVal.set(Calendar.DATE, inVal.get(Calendar.DATE));
}
this.endDate = newVal.getTime();
}
}
The code in both is a bit of a mess I realize, but I've been trying dozens of things to find and work around. I'm also fairly new to Java, so maybe there's something simple I'm missing.
It also gets confusing because we are using a custom entity named "Schedule" to communicate with SQL through Hibernate persistence.
Using NetBeans 6.9.1, Tomcat 6.0.26, Catalina, Coyote.
PS If anyone knows a cleaner way to set the Date property from two separate inputs (date and time) I'd be open to it, but PM me so we don't derail the thread.