15.1 Introduction to Creating a Calendar Application

ADF Faces includes a calendar component that by default displays created activities in daily, weekly, monthly, or list views for a given provider or providers (a provider is the owner of an activity). Figure 15-1 shows an ADF Faces calendar in weekly view mode with some sample activities.

Figure 15-1 ADF Faces Calendar Showing Weekly View

You can configure the calendar so that it only displays a subset of those views. For example, you may not want your calendar to use the month and list views. You can configure it so that only the day and week views are available, as shown in Figure 15-2. Because only day and week views are available, those are the only buttons displayed in the toolbar.

Figure 15-2 Calendar Configured to Use Only Week and Day Views

By default, the calendar displays dates and times based on the locale set in the trinidad-config.xml file (for example, Section A.6, "Configuration in trinidad-config.xml"). If a locale is not set in that file, then it is based on the locale sent by the browser. For example, in the United States, by default, the start day of the week is Sunday, and 2 p.m. is shown as 2:00 PM. In France, the default start day is Monday, and 2 p.m. is shown as 14:00. The time zone for the calendar is also based on the setting in trinidad-config.xml. You can override the default when you configure the calendar. For more information, see Section 15.3, "Configuring the Calendar Component."

The calendar uses the CalendarModel class to display the activities for a given time period. You must create your own implementation of the model class for your calendar. If your application uses the Fusion technology stack, then you can create ADF Business Components over your data source that represents the activities, and the model will be created for you. You can then declaratively create the calendar, and it will automatically be bound to that model. For more information, see the "Using the ADF Faces Calendar Component" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

If your application does not use the Fusion technology stack, then you create your own implementation of the CalendarModel class and the associated CalendarActivity and CalendarProvider classes. The classes are abstract classes with abstract methods. You must provide the functionality behind the methods, suitable for your implementation of the calendar. For more information, see Section 15.2, "Creating the Calendar."

The calendar includes a toolbar with built-in functionality that allows a user to change the view (between daily, weekly, monthly, or list), go to the previous or next day, week, or month, and return to today. The toolbar is fully customizable. You can choose which buttons and text to display, and you can also add buttons or other components. For more information, see Section 15.5, "Customizing the Toolbar."

Tip:

When these toolbar buttons are used, attribute values on the calendar are changed. You can configure these values to be persisted so that they remain for the user during the duration of the session. For more information, see Chapter 31, "Allowing User Customization on JSF Pages."

You can also configure your application so that the values will be persisted and used each time the user logs into the system. For this persistence to take place, your application must use the Fusion technology stack. For more information, see the "Allowing User Customizations at Runtime" chapter of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

The calendar component displays activities based on those activities and the provider returned by the CalendarModel class. By default, the calendar component is read-only. That is, it can display only those activities that are returned. You can add functionality within supported facets of the calendar so that users can edit, create, and delete activities. When certain events are invoked, popup components placed in these corresponding facets are opened, which can allow the user to act on activities or the calendar.

For example, when a user clicks on an activity in the calendar, the CalendarActivityEvent is invoked and the popup component in the ActivityDetail facet is opened. You might use a dialog component that contains a form where users can view and edit the activity, as shown in Figure 15-3.

The calendar component supports the ADF Faces drag and drop architectural feature. Users can drag activities to different areas of the calendar, executing either a copy or a move operation, and can also drag handles on the activity to change the duration of the activity. For more information about adding drag and drop functionality, see Section 32.7, "Adding Drag and Drop Functionality to a Calendar."

By default, the calendar displays activities using a blue ramp. Color ramps are groups of colors all based on the same hue, for example, blue. In the default calendar, for a short-duration activity shown in the daily view, the time of an activity is shown with a dark blue background, while the title of the activity is shown with a light blue background, as shown in Figure 15-1. You can customize how the activities are displayed by changing the color ramp.

Each activity is associated with a provider, that is, an owner. If you implement your calendar so that it can display activities from more than one provider, you can also style those activities so that each provider's activity shows in a different color, as shown in Figure 15-4.

Figure 15-4 Month View with Activities from Different Providers

15.2 Creating the Calendar

Before you can add a calendar component to a page, you must implement the logic required by the calendar in Java classes that extend ADF Faces calendar abstract classes. For an ADF Faces application, create the classes as managed beans. After you create the classes, you can add the calendar to a page.

Note:

If your application uses the Fusion technology stack, implement the calendar classes using ADF Business Components. This will allow you to declaratively create and bind your calendar component. For more information, see the "Using the ADF Faces Calendar Component" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

Before you implement your logic, it helps to have an understanding of the CalendarModel and CalendarActivity classes, as described in the following section.

15.2.1 Calendar Classes

The calendar component must be bound to an implementation of the CalendarModel class. The CalendarModel class contains the data for the calendar. This class is responsible for returning a collection of calendar activities, given the following set of parameters:

Provider ID: The owner of the activities. For example, you may implement the CalendarModel class such that the calendar can return just the activities associated with the owner currently in session, or it can also return other owners' activities.

Time range: The expanse of time for which all activities that begin within that time should be returned. A date range for a calendar is inclusive for the start time and exclusive for the end time (also known as half-open), meaning that it will return all activities that intersect that range, including those that start before the start time, but end after the start time (and before the end time).

A calendar activity represents an object on the calendar, and usually spans a certain period of time. The CalendarActivity class is an abstract class whose methods you can implement to return information about the specific activities.

Activities can be recurring, have associated reminders, and be of a specific time type (for example, hour or minute). Activities can also have start and end dates, a location, a title, and a tag.

The CalendarProvider class represents the owner of an activity. A provider can be either enabled or disabled for a calendar.

15.2.2 How to Create a Calendar

Create your own implementations of the CalendarModel and CalendarActivity classes and implement the abstract methods to provide the logic.

To create the calendar model classes:

Create a managed bean that will hold logic for the calendar. This bean must:

Implement any other needed functionality for the calendar. For example, you might add logic that sets the time zone, as in the oracle.adfdemo.view.calendar.rich.model.DemoCalendarBean managed bean in the ADF Faces demo application (for more information about the demo application, see Section 1.4, "ADF Faces Demonstration Application").

Create a managed bean that will hold logic for the activities. This bean must:

Extend the oracle.adf.view.rich.model.CalendarActivity class.

Implement the abstract methods.

Implement any other required functionality for the calendar. As an example, see the oracle.adfdemo.view.calendar.rich.model.DemoCalendarActivity managed bean in the ADF Faces demo application.

Tip:

If you want to style individual instances of an activity (for example, if you want each provider's activities to be displayed in a different color), then the getTags method must return a string that represents the activity instance. For more information, see Section 15.6.1, "How to Style Activities."

Create a managed bean that will hold information and logic for providers.

Extend the oracle.adf.view.rich.model.CalendarProvider class.

Implement the abstract methods.

Implement any other required functionality for the provider.

To create the calendar component:

In the Component Palette, from the Common Components section, drag a Calendar and drop it onto a JSF page.

Tip:

The calendar component can be stretched by any parent component that can stretch its children. If the calendar is a child component to a component that cannot be stretched, it will use a default width and height, which cannot be stretched by the user at runtime. However, you can override the default width and height using inline style attributes. For more information about the default height and width, see Section 15.3, "Configuring the Calendar Component." For more information about stretching components, see Section 8.2.1, "Geometry Management and Component Stretching."

Expand the Calendar Data section of the Property Inspector, and enter an EL expression for Value that resolves to the managed bean that extends the CalendarModel class.

15.3 Configuring the Calendar Component

Configure the many display attributes for the calendar, for example, the day that a week starts, and the time displayed at the beginning of a day.

15.3.1 How to Configure the Calendar Component

You configure the calendar using the Property Inspector.

To configure a calendar:

With the calendar component selected, expand the Common section of the Property Inspector, and set the following:

View: Select the view (either day, list, month, or week) that should be the default when the calendar is displayed. Users change this value when they click the corresponding button in the calendar's toolbar.

StartDayOfWeek: Enter the day of the week that should be shown as the starting day, at the very left in the monthly or weekly view. When not set, the default is based on the user's locale. Valid values are:

sun

mon

tue

wed

thu

fri

sat

StartHour: Enter a number that represents the hour (in 24 hour format, with 0 being midnight) that should be displayed at the top of the day and week view. While the calendar (when in day or week view) starts the day at 12:01 a.m., the calendar will automatically scroll to the startHour value, so that it is displayed at the top of the view. The user can always scroll above that time to view activities that start before the startHour value.

dayCount: Shows a number of days including the active day and after, based on the value of the listCount attribute.

month: Shows all the activities for the month to which the active day belongs.

week: Shows all the activities for the week to which the active day belongs

ListCount: Enter the number of days' activities to display (used only when the listType attribute is set to dayCount).

Figure 15-5 shows a calendar in list view with the listType set to dayCount and the listCount value set to 7.

Figure 15-5 LIst View Using dayCount Type

Expand the Calendar Data section of the Property Inspector, and set the following:

ActiveDay: Set the day used to determine the date range that is displayed in the calendar. By default, the active day is today's date for the user. Do not change this if you want today's date to be the default active day when the calendar is first opened.

Note that when the user selects another day, this becomes the value for the activeDay attribute. For example, when the user first accesses the calendar, the current date, February 6, 2009 is the active day. The month view will show February. If the user uses the next button to scroll to the next month, the active date will become March 6, 2009.

TimeZone: Set the time zone for the calendar. If not set, the value is taken from AdfFacesContext. The valid value is a java.util.TimeZone object.

Expand the Other section of the Property Inspector and set AvailableViews. The value can be one of or a combination of the following:

month

week

day

list

all

If you want to enter more than one value, enter the values with a space between. For example, if you want the calendar to use day and week views, you would enter the following:

day week

Note:

If all is entered, then all views are available, regardless if one is left out of the list.

The corresponding buttons will automatically be displayed in the toolbar, in the order they appear in the list.

If you do not enter day as an available view, then activities will be listed as plain text rather than as links in the list and week views (provided you do not also enter all).

Note:

In order to handle an overflow of tasks for a given day in the month view, if you enter month and do not also enter all, then you must also enter day.

If you want the user to be able to drag a handle on an existing activity to expand or collapse the time period of the activity, then implement a handler for CalendarActivityDurationChangeListener. This handler should include functionality that changes the end time of the activity. If you want the user to be able to move the activity (and, therefore, change the start time as well as the end time), then implement drag and drop functionality. For more information, see Section 32.7, "Adding Drag and Drop Functionality to a Calendar."

15.3.2 What Happens at Runtime: Calendar Events and PPR

The calendar has two events that are used in conjunction with facets to provide a way to easily implement additional functionality needed in a calendar, such as editing or adding activities. These two events are CalendarActivityEvent (invoked when an action occurs on an activity) and CalendarEvent (invoked when an action occurs on the calendar, itself). For more information about using these events to provide additional functionality, see Section 15.4, "Adding Functionality Using Popup Components."

The calendar also supports events that are fired when certain changes occur. The CalendarActivityDurationChangeEvent is fired when the user changes the duration of an activity by dragging the box that displays the activity. The CalendarDisplayChangeEvent is fired whenever the component changes the value of a display attribute, for example when the view attribute changes from month to day.

When a CalendarDisplayChangeEvent is fired, the calendar component adds itself as a partial page rendering (PPR) target, allowing the calendar to be immediately refreshed. This is because the calendar assumes that if the display changed programatically, then the calendar must need to be rerendered. For example, if a user changes the view attribute from day to month, then the calendar is rerendered automatically.

15.4 Adding Functionality Using Popup Components

When a user acts upon an activity, a CalendarActivityEvent is fired. This event causes the popup component contained in a facet to be displayed, based on the user's action. For example, if the user right-clicks an activity, the CalendarActivityEvent causes the popup component in the activityContextMenu to be displayed. The event is also delivered to the server, where a configured listener can act upon the event. You create the popup components for the facets (or if you do not want to use a popup component, implement the server-side listener). It is in these popup components and facets where you can implement functionality that will allow users to create, delete, and edit activities, as well as to configure their instances of the calendar.

Table 15-1 shows the different user actions that invoke events, the event that is invoked, and the associated facet that will display its contents when the event is invoked. The table also shows the component you must use within the popup component. You create the popup and the associated component within the facet, along with any functionality implemented in the handler for the associated listener. If you do not insert a popup component into any of the facets in the table, then the associated event will be delivered to the server, where you can act on it accordingly by implementing handlers for the events.

Table 15-1 Calendar Faces Events and Associated Facets

User Action

Event

Associated Facet

Component to Use in Popup

Right-click an activity.

CalendarActivityEvent

activityContextMenu: The enclosed popup component can be used to display a context menu, where a user can choose some action to execute against the activity, for example edit or delete.

menu

Select an activity and press the Delete key.

CalendarActivityEvent

activityDelete: The enclosed popup component can be used to display a dialog that allows the user to delete the selected activity.

dialog

Click or double-click an activity, or select an activity and press the Enter key.

CalendarActivityEvent

activityDetail: The enclosed popup component can be used to display the activity's details.

dialog

Hover over an activity.

CalendarActivityEvent

activityHover: The enclosed popup component can be used to display high-level information about the activity.

noteWindow

Right-click the calendar (not an activity or the toolbar).

CalendarEvent

contextMenu: The enclosed popup component can be used to display a context menu for the calendar.

menu

Click or double-click any free space in the calendar (not an activity).

CalendarEvent

create: The enclosed popup component can be used to display a dialog that allows a user to create an activity.

dialog

15.4.1 How to Add Functionality Using Popup Components

To add functionality, create the popups and associated components in the associated facets.

To add functionality using popup components:

In the Structure window, expand the af:calendar component node so that the calendar facets are displayed, as shown in Figure 15-6.

Figure 15-6 Calendar Facets in the Structure Window

Based on Table 15-1, create popup components in the facets that correspond to the user actions for which you want to provide functionality. For example, if you want users to be able to delete an activity by clicking it and pressing the Delete key, you add a popup dialog to the activityDelete facet.

To add a popup component, right-click the facet in the Structure window and choose Insert insidefacetName>ComponentName.

Figure 15-7 shows how the dialog is displayed when a user clicks an activity and presses the Delete key.

Figure 15-7 Delete Activity Dialog

Implement any needed logic for the calendarActivityListener. For example, if you are implementing a dialog for the activityDeleteFacet, then implement logic in the calendarActivityListener that can save-off the current activity so that when you implement the logic in the dialog listener (in the next step), you will know which activity to delete. Example 15-2 shows the calendarActivityListener for the calendar.jspx page in the ADF Faces demo application.

Implement the logic for the popup component in the handler for the popup event. For example, for the delete dialog, implement a handler for the dialogListener that actually deletes the activity when the dialog is dismissed. For more information about creating dialogs and other popup components, see Chapter 13, "Using Popup Dialogs, Menus, and Windows."

15.5 Customizing the Toolbar

By default, the toolbar in the calendar allows the user to change the view between day, week, month, and list, go to the next or previous item in the view, go to the present day, and also displays a text description of the current view, for example in the day view, it displays the active date, as shown in Figure 15-8.

Figure 15-8 Toolbar in Day View of a Calendar

Figure 15-9 shows a toolbar that has been customized. It has added toolbar buttons, including buttons that are right-aligned on the top toolbar, and buttons in a second toolbar.

Figure 15-9 Customized Toolbar for a Calendar

15.5.1 How to Customize the Toolbar

Place the toolbar and toolbar buttons you want to add in custom facets that you create. Then, reference the facet (or facets) from an attribute on the toolbar, along with keywords that determine how or where the contained items should be displayed.

To customize the toolbar:

In the JSF page of the Component Palette, from the Core panel, drag and drop a Facet for each section of the toolbar you want to add. For example, to add the custom buttons shown in Figure 15-9, you would add four facet tags. Ensure that each facet has a unique name for the page.

Tip:

To ensure that there will be no conflicts with future releases of ADF Faces, start all your facet names with customToolbar. For example, the section of the toolbar that contains the alignment buttons shown in Figure 15-9 are in the customToolbarAlign facet.

In the ADF Faces page of the Component Palette, from the Common Components panel, drag and drop a Toolbar to each facet and add toolbar buttons and configure the buttons and toolbar as needed. For more information about toolbars and toolbar buttons, see Section 14.3, "Using Toolbars."

In the Property Inspector, from the dropdown menu next to the toolboxLayout attribute, choose Edit.

In the Edit Property: ToolboxLayout dialog set the value for this attribute. It should be a list of the custom facet names, in the order in which you want the contents in the custom facets to appear. In addition to those facets, you can also include all, or portions of the default toolbar, using the following keywords:

all: Displays all the toolbar buttons and text in the default toolbar

dates: Displays only the previous, next, and today buttons

range: Displays only the string showing the current date range

views: Displays only the buttons that allows the user to change the view

Note:

If you use the all keyword, then the dates, range, and views keywords are ignored.

For example, if you created two facets named customToolbar1 and customToolbar2, and you wanted the complete default toolbar to appear in between your custom toolbars, the value of the toolboxLayout attribute would be the following list items:

customToolbar1

all

customToolbar2

You can also determine the layout of the toolbars using the following keywords:

newline: Places the toolbar in the next named facet (or the next keyword from the list in the toolboxLayout attribute) on a new line. For example, if you wanted the toolbar in the customToolbar2 facet to appear on a new line, the list would be:

customToolbar1

all

newline

customToolbar2

If instead, you did not want to use all of the default toolbar, but only the views and dates sections, and you wanted those to each appear on a new line, the list would be:

customToolbar1

customToolbar2

newline

views

newline

dates

stretch: Adds a spacer component that stretches to fill up all available space so that the next named facet (or next keyword from the default toolbar) is displayed as right-aligned in the toolbar. Example 15-3 shows the value of the toolboxLayout attribute for the toolbar displayed in Figure 15-9, along with the toolbar placed in the customToolbarAlign facet. Note that the toolbar buttons displayed in the customToolbarBold facet are right-aligned in the toolbar because the keyword stretch is named before the facet.

activityStyles: Allows you to individually style each activity instance. For example, you may want to show activities belonging to different providers in different colors.

dateCustomizer: Allows you to display strings other than the calendar date for the day in the month view. For example, you may want to display countdown or countup type numbers, as shown in Figure 15-10. This attribute also allows you to add strings to the blank portion of the header for a day.

Figure 15-10 Customized Display of Dates in a Calendar

15.6.1 How to Style Activities

The activityStyles attribute uses InstanceStyles objects to style specific instances of an activity. The InstanceStyles class is a way to provide per-instance inline styles based on skinning keys.

The most common usage of the activityStyles attribute is to display activities belonging to a specific provider using a specific color. For example, the calendar shown in Figure 15-11 shows activities belonging to three different providers. The user can change that color used to represent a provider's activities in the left panel. The activityStyles attribute is used to determine the color displayed for each activity, based on the provider with which it is associated.

Figure 15-11 Activities Styled to Display Color for Different Providers

Note that instead of using a single color, a range of a color is used in the calendar. This is called a color ramp. A color ramp is a set of colors in a color family to represent the different states of activities. For example, T.F.'s activities use the Blue ramp. Activities whose time span is within one day are displayed in medium blue text. Activities that span across multiple days are shown in a medium blue box with white text. Darker blue is the background for the start time, while lighter blue is the background for the title. These three different blues are all part of the Blue color ramp.

The CalendarActivityRamp class is a subclass of InstanceStyles, and can take a representative color (for example, the blue chosen for T.F.'s activities) and return the correct color ramp to be used to display each activity in the calendar.

The activityStyles attribute must be bound to a map object. The map key is the set returned from the getTags method on an activity. The map value is an InstanceStyles object, most likely an instance of CalendarActivityRamp. This InstanceStyles object will take in skinning keys, and for each activity, styles will be returned.

To style activities:

In your CalendarActivity class, have the getTags method return a string set that will be used by the activityStyles attribute to map the returned string to a specific style. For example, to use the different color ramps for the different providers shown in Figure 15-11, you must return a string for each provider. In this case, an activity belonging to the current user might return Me, an activity belonging to L.E. might return LE, and an activity belonging to T.F. might return TF. For more information about implementing the CalendarActivity class, see Section 15.2.2, "How to Create a Calendar."

Create a map whose key is the string returned from the getTags method, and whose value is an InstanceStyles object (for example, a CalendarActivityRamp instance).

For example, to use the different color ramps shown in Figure 15-11, you would create a map using the values shown in Table 15-2.

In the Structure window, select the calendar component, and in the Property Inspector, bind the activityStyles attribute to the map.

15.6.2 What Happens at Runtime: Activity Styling

During calendar rendering for each activity, the renderer calls the CalendarActivity.getTags method to get a string set. The string set is then passed to the map bound to the activityStyles attribute, and an InstanceStyles object is returned (which may be a CalendarActivityRamp).

Using the example:

If the string set {"Me"} is passed in, the red CalendarActivityRamp is returned.

If the string set {"LE"} is passed in, the orange CalendarActivityRamp is returned.

If the string set {"TF"} is passed in, the blue CalendarActivityRamp is returned.

15.6.3 How to Customize Dates

If you want to display something other than the date number string in the day header of the monthly view, you can bind the dateCustomizer attribute to an implementation of a DateCustomizer class that determines what should be displayed for the date.

To customize the date string:

Create a subclass of the oracle.adf.view.rich.util.DateCustomizer class. This subclass should determine what to display using the following skinning keys:

af|calendar::month-grid-cell-header-misc: Determines what to display in the left side of the header for a day in the month view.

af|calendar::month-grid-cell-header-day-link: Determines the string to display for the date.

Example 15-4 shows the DemoDateCustomizer class that displays the week number in the first day of the week, and instead of the day of the month, a countdown number to a specific date, as shown in Figure 15-10.