Scheduler for Java Tutorial

1. HTML

We will assume that your HTML file (either .html or .jsp) is located in Scheduler directory of your web application. If you use a different location you must change the relative URLs accordingly.

Add the references to the required JavaScript libraries to the header or to the body:

<script type="text/javascript" src="../js/common.js"></script>
<script type="text/javascript" src="../js/scheduler.js"></script>

Put a placeholder for the Scheduler into the <body> :

<div id="dps">
</div>

Add the JavaScript initialization code:

<script type="text/javascript">
var dps = new DayPilot.Scheduler("dps");
dps.heightSpec = 'Fixed';
dps.height = 200; 
dps.backendUrl = '${pageContext.request.contextPath}/dps';
dps.Init();
</script>

It is necessary to specify the backendUrl property. That's the URL which handles the AJAX callback requests.

The complete API reference for the Scheduler client-side object can be found here:

2. Libraries

JavaScript libraries

  • Copy common.js and scheduler.js to js directory of your web application.

Java libraries

  • Copy daypilot-x.x.x.jar (e.g. daypilot-1.0.30.jar) to WEB-INF/lib directory of your web application.

3. Servlet

Create a new servlet and map it to "/dps" Url. You can do it by adding the following declaration to web.xml file:

<servlet>
  <description /> 
  <display-name>DpsServlet</display-name> 
  <servlet-name>DpsServlet</servlet-name> 
  <servlet-class>org.daypilot.demo.DpsServlet</servlet-class> 
</servlet>
<servlet-mapping>
  <servlet-name>DpsServlet</servlet-name> 
  <url-pattern>/dps</url-pattern> 
</servlet-mapping>

The servlet class will be very simple:

package org.daypilot.demo;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.daypilot.demo.db.Db;
import org.daypilot.ui.DayPilotScheduler;
import org.daypilot.ui.args.scheduler.BeforeCellRenderArgs;
import org.daypilot.ui.args.scheduler.BeforeEventRenderArgs;
import org.daypilot.ui.args.scheduler.BeforeResHeaderRenderArgs;
import org.daypilot.ui.args.scheduler.EventMoveArgs;
import org.daypilot.ui.args.scheduler.EventResizeArgs;
import org.daypilot.ui.args.scheduler.TimeRangeSelectedArgs;
import org.daypilot.ui.enums.UpdateType;

public class DpsServlet extends HttpServlet {

  private static final long serialVersionUID = 1L;

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");

    Dps dps = new Dps(); 
    dps.process(request, response);
  }

}

This will forward the POST request to a special Dps class which we will create in the next step.

4. Dps Class

Create a new Dps class (it must inherit from org.daypilot.ui.DayPilotScheduler):

public class Dps extends DayPilotScheduler {

  @Override
  public void onInit() throws Exception {

    // map the database column names
    setDataResourceField("event_resource");
    setDataIdField("event_id");
    setDataTextField("event_name");
    setDataStartField("event_start");
    setDataEndField("event_end");

    // assign the collection of events
    setEvents(Db.getEvents(getRequest(), getStartDate().toDate(), getStartDate().addDays(getDays()).toDate() ));

    // set the resources
    getResources().clear();
    getResources().add("Room A", "A");
    getResources().add("Room B", "B");
    getResources().add("Room C", "C");

    // request a full update of the control on the client side
    update(UpdateType.FULL);
  }
} 

The onInit() method is called using an AJAX callback right after the Scheduler is initialized on the client side.

5. Event Moving

In order to handle event move action, we need to override onEventMove() method. The event arguments are available in EventMoveArgs class (ea parameter).

@Override
public void onEventMove(EventMoveArgs ea) throws Exception {
  // update the DB
  Db.moveEvent(getRequest(), ea.getValue(), ea.getNewStart().toTimeStamp(), ea.getNewEnd().toTimeStamp(), ea.getNewResource());
  update();
}

It has to be enabled on the client-side as well:

dps.eventMoveHandling = "CallBack"; 

6. Prepare and Finish

There are two special methods available for overriding:

  • onPrepare()
  • onFinish()

They are called during every AJAX callback request (before and after the main event method).

We will use onPrepare() to initialize an in-memory instance of a HSQLDB embedded database (which we will use for testing purposes):

public void onPrepare() throws Exception {
  // create the in-memory DB if it's not ready
  if (!Db.tableExists("EVENTS")) {
   Db.createTable();
  }
}

We will also move the event loading code there to the onFinish():

@Override
public void onFinish() throws Exception {

  if (getUpdateType() == UpdateType.NONE) {
    return;
  }

  // set the database fields
  setDataResourceField("event_resource");
  setDataIdField("event_id");
  setDataTextField("event_name");
  setDataStartField("event_start");
  setDataEndField("event_end");

  // reload events
  setEvents(Db.getEvents(getRequest(), getStartDate().toDate(), getStartDate().addDays(getDays()).toDate() ));

  if (getUpdateType() == UpdateType.EVENTS_ONLY) {
    return;
  }

  getResources().clear();
  getResources().add("Room A", "A");
  getResources().add("Room B", "B");
  getResources().add("Room C", "C");

7. Handling Other Events

Implementing event handlers is very similar to onEventMove(). Just add the required database changes. Since we already added onFinish() method, you don't need to care about refreshing the events.

Our new onEventResize handler:

@Override
public void onEventResize(EventResizeArgs ea) throws Exception {
  Db.resizeEvent(getRequest(), ea.getValue(), ea.getNewStart().toTimeStamp(), ea.getNewEnd().toTimeStamp());
  update();
}

And timeRangeSelected handler:

@Override
public void onTimeRangeSelected(TimeRangeSelectedArgs ea) throws Exception {
  Db.insertEvent(getRequest(), "New event", ea.getStart().toTimeStamp(), ea.getEnd().toTimeStamp(), ea.getResource());
  update();
}

Both events need to be enabled on the client side:

dps.eventResizeHandling = "CallBack";
dps.timeRangeSelectedHandling = "CallBack";