Skip to main content

Oracle APEX Calendar Region - Beyond the Basics

This article explains how to build a complete Internal Meeting Scheduler using the APEX Calendar with dynamic UI behavior, registration tracking, and strong business validations. .

Oracle APEX PL/SQL JavaScript Calendar Region

Table of Contents

  1. Overview & Features
  2. Step 1 — Table Design
  3. Step 2 — Calendar Page Setup
  4. Step 3 — Calendar Attribute Mapping
  5. Step 4 — Filter Control
  6. Step 5 — Calendar Customization
  7. Step 6 — Meeting Details Popup
  8. Step 7 — Registration Handling
  9. Step 8 — Add New Meeting
  10. Step 9 — Save Meeting Logic
  11. Step 10 — Register Button Action
  12. Step 11 — Department-Based Styling
  13. Step 12 — Business Validations

Overview

This solution provides a structured and interactive way to manage internal meetings using Oracle APEX. Here are the key capabilities it offers:

Calendar-based session visualization
Department-based color coding
Filters for Upcoming, Completed, and All sessions
Registration and unregistration functionality
Audience tracking using a colon-separated format
Visual indicators for registered sessions
Popup-based session details and creation
Strong business rule validations — max 3 sessions per day; no duplicate sessions at the same date and time

1

Table Design

Create a table named INTERNAL_MEETINGS to store all session details. The table uses the following columns:

ColumnDescription
MEETING_IDUnique identifier for each session
TITLE_DOMAINDomain or category of the session
TITLE_NAMESession topic name
PRESENTER_IDPresenter identifier
PRESENTER_NAMEPresenter name
PRESENTER_DEPT_NODepartment number (used for color coding)
MEETING_DATEScheduled date
MEETING_TIMESession time
APPROVED_STSApproval status
AUDIENCEColon-separated list of registered users

2

Calendar Page Setup

Create a Calendar Region on a new page using the INTERNAL_MEETINGS table. Use the SQL query below as the region source:

SQL — Calendar Region Source
SELECT
  m.meeting_id,
  m.title_domain || ' - ' || m.title_name
    || '||' || NVL(m.meeting_time,   'N/A')
    || '||' || NVL(m.presenter_name, 'N/A')
    || '||' || TO_CHAR(m.presenter_dept_no)
    || '||' || NVL(m.audience,       '')
    || '||' || m.title_domain
    || '||' || CASE
               WHEN INSTR(':' || NVL(m.audience,'') || ':',
                          ':' || :APP_USER || ':') > 0
               THEN 'Y' ELSE 'N'
             END
    || '||' || CASE
               WHEN TRUNC(m.meeting_date) < TRUNC(SYSDATE)
               THEN 'PAST' ELSE 'FUTURE'
             END                           AS event_title,
  TRUNC(m.meeting_date)               AS start_date,
  TRUNC(m.meeting_date)               AS end_date,
  CASE m.presenter_dept_no
    WHEN 10 THEN 'dept-10'
    WHEN 20 THEN 'dept-20'
    WHEN 30 THEN 'dept-30'
    WHEN 40 THEN 'dept-40'
    ELSE        'dept-default'
  END                                 AS css_class_col
FROM internal_meetings m
WHERE m.approved_sts = 'Y'
AND   EXTRACT(YEAR FROM m.meeting_date) = EXTRACT(YEAR FROM SYSDATE)
AND   (
        :P23_CAL_FILTER IS NULL
        OR :P23_CAL_FILTER = 'ALL'
        OR ( :P23_CAL_FILTER = 'UPCOMING'
             AND TRUNC(m.meeting_date) >= TRUNC(SYSDATE) )
        OR ( :P23_CAL_FILTER = 'COMPLETED'
             AND TRUNC(m.meeting_date) <  TRUNC(SYSDATE) )
      )

3

Calendar Attribute Mapping

Configure the Calendar attributes in APEX as follows:

AttributeValue
Display ColumnEVENT_TITLE
Start Date ColumnSTART_DATE
End Date ColumnEND_DATE
Primary Key ColumnMEETING_ID
CSS Class ColumnCSS_CLASS_COL

4

Filter Control

Create a hidden page item P23_CAL_FILTER with a default value of ALL. This item drives the calendar filter dynamically without a page reload, supporting three states:

ALL — Shows every approved session in the current year
UPCOMING — Shows only sessions from today onwards
COMPLETED — Shows only past sessions

5

Calendar Customization

Enhance the Calendar using the Initialization JavaScript Function. The customization covers three areas:

AreaDetails
Custom ButtonsUpcoming Sessions, Completed Sessions, All Sessions, Add Session
Event RenderingTime badge display, registered session indicator, tooltip info
Event ClickOpens session details popup, loads dynamic data, controls registration state

6

Meeting Details Popup

Create an Inline Dialog region with static ID MEETING_POPUP. It displays:

Domain and title
Presenter and department
Date and time
Number of attendees

The register button changes dynamically based on whether the session is in the past or future and whether the user is already registered.


7

Registration Handling

Implement an AJAX process to manage registrations. The process handles:

Adding a user to the audience list
Removing a user from the audience list
Returning a UI response for instant feedback
Automatically refreshing the Calendar after each action

8

Add New Meeting

Calendar Attributes → Create Link → Type: URL → Set URL to javascript:open_region(); to open the "New Scheduled Session" popup region.

Create a popup region with static ID New_Session containing the following input fields:

FieldPurpose
DomainSession category
TitleSession topic name
Presenter DetailsName and ID of the presenter
DepartmentDept number for color coding
Date and TimeScheduled date and time
Approval StatusY / N flag for visibility on calendar

The Add Session button in the Calendar toolbar triggers this popup to open.


9

Save Meeting Logic

Use an AJAX process to handle saving. The process:

Validates all required fields
Converts the date format before insert
Inserts the record into the INTERNAL_MEETINGS table
Returns success or error response to the UI

On success: a confirmation message is shown, the form is cleared, the popup closes, and the Calendar refreshes automatically.


10

Register Button Action

A Dynamic Action on the register/unregister button ensures the following:

Registration is blocked for past sessions
Proper feedback messages are displayed
Button state updates to reflect current registration status
Calendar stays in sync after every action

11

Department-Based Styling

Sessions are visually differentiated on the calendar using department-based CSS classes. A legend is displayed above the Calendar for user reference:

CSS ClassDepartmentColor
dept-10 Development Blue
dept-20 Testing Green
dept-30 Design Orange
dept-40 Management Purple
dept-default Others Grey

12

Business Validations

The following business rules are enforced to maintain data integrity:

RuleStatus
A maximum of 3 sessions per day is allowedEnforced
Only one session per department per dayEnforced
No duplicate sessions at the same date and timeEnforced
All mandatory fields must be filledEnforced
Registration is disabled for past sessionsEnforced
Time input must be in a valid formatEnforced

Conclusion

Using Oracle APEX, you can build a complete and interactive meeting scheduler with minimal complexity and a highly responsive user experience. This implementation demonstrates how to effectively combine Calendar components, JavaScript customization, and backend processing to create a practical and scalable internal application.

Comments

Popular posts from this blog

APEX - Tip: Fix Floating Label Issue

Oracle APEX's Universal Theme provides a modern and clean user experience through features like floating (above) labels for page items.  These floating labels work seamlessly when users manually enter data, automatically moving the label above the field on focus or input.  However, a common UI issue appears when page item values are set Dynamically the label and the value overlap, resulting in a broken and confusing user interface. once the user focuses the affected item even once, the label immediately corrects itself and displays properly. When an issue is reported, several values are populated based on a single user input, causing the UI to appear misaligned and confusing for the end user. Here, I'll share a few tips to fix this issue. For example, employee details are populated based on the Employee name. In this case, the first True Action is used to set the values, and in the second True Action, paste the following code setTimeout(function () {   $("#P29_EMAIL,#P29_...

Oracle APEX UI Tip: Display Page Title Next to the APEX Logo

In most Oracle APEX applications, every page has a Page Title displayed at the top. While useful, this title occupies vertical space, especially in apps where screen real estate matters (dashboards, reports, dense forms). So the goal is simple: Show the page title near the APEX logo instead of consuming page content space. This keeps the UI clean, professional, and consistent across all pages. Instead of placing the page title inside the page body:         ✅ Fetch the current page title dynamically         ✅ Display it right after the APEX logo         ✅ Do it globally, so it works for every page All of this is achieved using:         ✅ Global Page (Page 0)         ✅ One Dynamic Action         ✅ PL/SQL + JavaScript Simple, effective, and reusable. 1️⃣ Create a Global Page Item On Page 0 (Global Page), create a hidden item:      P0_PAGE_TITLE This item wi...

Building a Custom Debug Package for Oracle APEX Using PL/SQL

While developing Oracle APEX applications, debugging page processes and backend PL/SQL logic can be challenging—especially when values are lost between processes or execution flow is unclear.  Although DBMS_OUTPUT is useful, it doesn’t work well inside APEX runtime. To solve this, I built a custom PL/SQL debug Package that logs execution flow and variable values into a database table.  This approach helps trace exactly where the code reached, what values were passed, and whether a block executed or not - even inside page-level processes and packaged procedures Why a Custom Debug Package? Works seamlessly inside Oracle APEX page processes Persists debug information even after session ends Helps trace execution flow Captures runtime values Can be turned ON/OFF dynamically Does not interrupt business logic The Package consists of:- Debug Table                         -  Stores debug messages Sequence ...