Skip to Main Content

APEX

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

How to add resourceTimeLine view in Calendar control in Oracle APEX 26.1

Kinjan BhavsarAug 3 2026 — edited Aug 3 2026

I was using FullCalendar library in APEX 20.2 and was able the achieve the following UI but it is using very old library. Now as APEX 26.1 supports FullCalendar 6.1.20, can I achieve similar UI using inbuilt Calendar feature? or even custom JS is fine for me, so that I can fully utilise the latest library of FullCalendar.

Here is my JS code

var gData;
var myPopup;

/* ------------------------------------------------------------------
* 1) Attach the qtip DIRECTLY to an element.
* This is the original, known-good code path -- it always worked
* for grid events. We simply reuse it for popover events too.
* ------------------------------------------------------------------ */
function attachTaskTooltip(event, element) {
var vHoldTd = "";
var end = !event.end ? event.start : event.end;

if (event.holding) {
var vHoldingNm = event.holding.substring(0, event.holding.indexOf("~@~"));
var vHoldingColor = event.holding.substring(
event.holding.indexOf("~@~") + 3
);
vHoldTd =
'<tr><td colspan="2" style="text-align: center;background-color: ' +
vHoldingColor +
'"><B>' +
vHoldingNm +
"</B></td></tr>";
}

var vPriority = !event.tpriority ? "" : event.tpriority;
var vunm = !event.username ? "" : event.username;
var vContributor = !event.contributor ? "" : event.contributor;

element.qtip({
content:
'<table border="0" cellpadding="1" cellspacing="1" class="schedule-tile-title"><tbody><tr><td style="text-align: left;"><strong>Task #:&nbsp;</strong></td><td>' +
event.id +
'</td></tr><tr><td style="text-align: left;"><strong>Subject:&nbsp;</strong></td><td>' +
event.title +
'</td></tr><tr><td style="text-align: left;"><strong>Type:&nbsp;</strong></td><td style="background-color: ' +
event.color +
'">' +
event.ttype +
'</td></tr><tr><td style="text-align: left;"><strong>Status:&nbsp;</strong></td><td>' +
event.tstatus +
'</td></tr><tr><td style="text-align: left;"><strong>Priority:&nbsp;</strong></td><td>' +
vPriority +
'</td></tr><tr><td style="text-align: left;"><strong>Start:&nbsp;</strong></td><td>' +
moment(event.start).format("DD-MMM-YYYY h:mm a") +
'</td></tr><tr><td style="text-align: left;"><strong>End:&nbsp;</strong></td><td>' +
moment(end).format("DD-MMM-YYYY h:mm a") +
'</td></tr><tr><td style="text-align: left;"><strong>Owner:&nbsp;</strong></td><td>' +
vunm +
'</td></tr><tr><td style="text-align: left;"><strong>Contributor:&nbsp;</strong></td><td>' +
vContributor +
"</td></tr>" +
vHoldTd +
'<tr><td colspan="2" style="text-align: center;">Click for more details..</td></tr></tbody>\n</table>',
style: {
classes: "qtip-bootstrap qtip-rounded qtip-shadow",
},
position: {
my: "bottom middle",
at: "top middle",
target: "mouse",
container: $("body"),
viewport: $(window),
adjust: {
mouse: true,
},
},
});
}

/* ------------------------------------------------------------------
* 2) Apply that same attachment to every event inside the open
* "+N more" popover.
*
* Confirmed from the console: those elements carry
* .data('fc-seg').event, so we can read the event straight off
* them. They are already in the DOM at this point, which is the
* condition qtip needs.
* ------------------------------------------------------------------ */
function attachPopoverTooltips() {
$(".fc-more-popover")
.find(".fc-event")
.each(function () {
var $el = $(this);

if ($el.data("qtip")) {
return; // already has one
}

var seg = $el.data("fc-seg");
var ev = seg && seg.event;

if (ev) {
attachTaskTooltip(ev, $el);
}
});
}

apex.server.process(
"GET_PLANNER_LIST",
{
x01: 1,
},
{
success: function (gData) {
var todayDate = moment().startOf("day");
var YESTERDAY = todayDate.clone().subtract(1, "day").format("YYYY-MM-DD");
var TODAY = todayDate.format("YYYY-MM-DD");
var TOMORROW = todayDate.clone().add(1, "day").format("YYYY-MM-DD");

var src_data = gData;
var VJSON = gData.PLANNER_LIST;

const currentView = apex.item("P700_CURRENT_VIEW").getValue()
? apex.item("P700_CURRENT_VIEW").getValue()
: "timelineDay";

$("#calendar").fullCalendar({
timeFormat: "hh:mm a",
now: TODAY,
editable: true,
aspectRatio: 1.8,
scrollTime: "00:00",
header: {
left: "today prev,next, createtask",
center: "title",
right: "timelineDay,timelineThreeDays,month",
},
defaultView: currentView,
eventLimit: {
month: 4,
timelineThreeDays: 3,
},
views: {
timelineThreeDays: {
type: "timeline",
duration: { days: 7 },
slotDuration: "24:00",
eventLimit: true,
},
},
customButtons: {
createtask: {
text: "Create task",
id: "create_task",
click: function () {
var PageURL = "";
PageURL =
"f?p=" +
$v("pFlowId") +
":859:" +
$v("pInstance") +
":::859:P859_PAGE:700";
apex.server.process(
"GETCHECKSUMURL",
{
p_arg_names: ["APP_ITV_CS_URL"],
p_arg_values: [PageURL],
},
{
dataType: "text",
success: function (data) {
eval(
data.replace(
"width:'920'",
"height:'960'",
"id:'id_page'"
)
);
$(".t-Dialog-page--standard .t-Dialog-page--standard").html(
"Add Task"
);
},
}
);
},
},
},
resourceLabelText: "Users",

resources: VJSON,
resourceRender: function (resourceObj, labelTds, bodyTds) {
if (resourceObj.name || resourceObj.email) {
labelTds.qtip({
content:
'<table border="0" cellpadding="1" cellspacing="1" class="schedule-tile-title"><tbody><tr><td style="text-align: left;"><strong>Name:&nbsp;</strong></td><td>' +
resourceObj.name +
'</td></tr><tr><td style="text-align: left;"><strong>Email:&nbsp;</strong></td><td>' +
resourceObj.email +
'</td></tr><tr><td style="text-align: left;"><strong>Address:&nbsp;</strong></td><td>' +
resourceObj.addr +
"</td></tr></tbody>\n</table>",
style: { classes: "qtip-bootstrap qtip-rounded qtip-shadow" },
position: {
my: "bottom middle",
at: "top middle",
target: "mouse",
adjust: { mouse: false },
},
});
}
},

events: function (start, end, timezone, callback) {
apex.server.process(
"GET_TASK_LIST",
{
x01: moment(start).format("DD-MMM-YYYY"),
x02: moment(end).format("DD-MMM-YYYY"),
},
{
success: function (pData) {
$("#apex_wait_popup").remove();
$("#apex_wait_overlay").remove();
callback(pData);
},
}
);
},

eventClick: function (event) {
if (event.url) {
window.open(event.url);
return false;
}
},

/* Original known-good path for grid events */
eventAfterRender: function (event, element) {
attachTaskTooltip(event, element);
},

/* eventLimitClick fires BEFORE the popover is inserted, so we
defer to the next tick and then attach to its children. */
eventLimitClick: function (cellInfo, jsEvent) {
setTimeout(attachPopoverTooltips, 0);
return "popover";
},

loading: function (isLoading) {
if (isLoading) {
$("#loading").show();
myPopup = apex.widget.waitPopup();
} else {
$("#loading").hide();
myPopup.remove();
}
},

eventResize: function (event, delta, revertFunc) {
updateTask(event, revertFunc);
},

eventDrop: function (event, delta, revertFunc) {
updateTask(event, revertFunc);
},
});
},
}
);
Duplicate Post
This post has already been added here:
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Marked as duplicate
Added on Aug 3 2026
0 comments
42 views