Sitemap

Building a Dynamic Vertical Timeline in Oracle APEX

3 min readSep 2, 2026

--

A timeline is a simple but powerful way to present a person’s activities, career history, transactions, or important events in chronological order.

While working with Oracle APEX, I wanted to create a dynamic vertical timeline where timeline entries are generated directly from database records instead of manually creating HTML for every event.

Recently, I worked on implementing a dynamic vertical timeline in Oracle APEX using a Dynamic Content region. Instead of creating timeline cards manually, the timeline is generated dynamically from database records using PL/SQL, SQL, HTML, and CSS.

This approach makes the timeline reusable and data-driven.

Step 1: Create a Dynamic Content Region

In Oracle APEX, create a region with:

Region Type → Dynamic Content

The Dynamic Content region allows us to generate HTML dynamically using PL/SQL.

Instead of returning static HTML, we can loop through database records and build the timeline item by item.

Step 2: Prepare the SQL Query

If the table already exists, prepare a query that returns all the information required by the timeline (i.e step 3 ).

If the table does not exist, create a table first so you can test the timeline implementation.

For example:

CREATE TABLE employee_activities (
activity_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
employee_id NUMBER,
activity_date DATE,
activity_name VARCHAR2(100),
activity_type VARCHAR2(50),
organization_name VARCHAR2(200),
remarks VARCHAR2(500)
);

Then insert some sample records:

INSERT INTO employee_activities (
employee_id,
activity_date,
activity_name,
activity_type,
organization_name,
remarks
)
VALUES (
101,
DATE '2024-01-01',
'Joining',
'JOINING',
'Head Office',
'Joined the organization'
);

Step 3: Prepare the SQL Query

First, I prepared a query that returns all the information required by the timeline.

A simplified example:

SELECT
a.activity_date AS item_date,
    TO_CHAR(
a.activity_date,
'DD-Mon-YYYY'
) AS item_date_display,
a.activity_name AS item_name, CASE
WHEN a.activity_type = 'JOINING'
THEN 'fa fa-user-plus'
WHEN a.activity_type = 'PROMOTION'
THEN 'fa fa-arrow-up'
WHEN a.activity_type = 'TRANSFER'
THEN 'fa fa-exchange'
WHEN a.activity_type = 'TRAINING'
THEN 'fa fa-book'
ELSE
'fa fa-history'
END AS item_icon,
'Activity' AS item_type, a.organization_name AS item_subtitle, a.remarks AS item_detailsFROM table_name aWHERE a.id = :P1_idORDER BY a.activity_date DESC;

The important idea here is to create a standard structure for every timeline record.

Step 4: Generate HTML Using PL/SQL

Now the Dynamic Content region can loop through the query results and generate the HTML and add code as per requirement in dynamic content pl/sql.

Get Pragya Nemkul’s stories in your inbox

Join Medium for free to get updates from this writer.

For example:

DECLARE
l_html CLOB;
BEGIN
    l_html := '<div class="timeline">';    FOR r IN (
SELECT
activity_date,
activity_name,
activity_type,
organization_name,
remarks
FROM employee_activities
WHERE employee_id = :P10_EMPLOYEE_ID
ORDER BY activity_date DESC
)
LOOP
l_html := l_html ||
'<div class="timeline-item">' ||
'<div class="timeline-icon">' || CASE
WHEN r.activity_type = 'JOINING'
THEN '<i class="fa fa-user-plus"></i>'
WHEN r.activity_type = 'PROMOTION'
THEN '<i class="fa fa-arrow-up"></i>'
WHEN r.activity_type = 'TRANSFER'
THEN '<i class="fa fa-exchange"></i>'
WHEN r.activity_type = 'TRAINING'
THEN '<i class="fa fa-book"></i>'
ELSE
'<i class="fa fa-history"></i>'
END ||
'</div>' || '<div class="timeline-content">' || '<div class="timeline-date">' ||
TO_CHAR(
r.activity_date,
'DD-Mon-YYYY'
) ||
'</div>' ||
'<h3>' ||
apex_escape.html(r.activity_name) ||
'</h3>' ||
'<h4>' ||
apex_escape.html(r.organization_name) ||
'</h4>' ||
'<p>' ||
apex_escape.html(r.remarks) ||
'</p>' ||
'</div>' || '</div>'; END LOOP; l_html := l_html || '</div>'; RETURN l_html;END;

Step 5: Add CSS

Once the HTML is generated, CSS is used to create the visual timeline.Add css as per requirement.

A simplified example:

.timeline {
position: relative;
max-width: 900px;
margin: auto;
padding: 30px 20px;
}

Overall Architecture

The implementation can be summarized as:

Database Records

↓

SQL Query

↓

PL/SQL Loop

↓

Dynamic HTML

↓

APEX Dynamic Content

↓

CSS

↓

Vertical Timeline UI

--

--