Ever wanted to give your Oracle APEX app a beautiful and modern Date Range Picker instead of those plain calendar items? Well… buckle up because we’re going to do exactly that — using a mix of JavaScript, jQuery, and the powerful daterangepicker.js library.
By the end of this post, you’ll have a sleek date range picker that looks professional, interacts with your APEX page items, and stores its values in session using Dynamic Actions.
![]() |
| Custom Date Picker in Oracle APEX |
🎥 Watch the Full Tutorial
If you’re a visual learner like me, check out my YouTube tutorial below — where I walk you through each step and show the picker in action inside Oracle APEX 👇
🎯 Step 1: Add Required JS Libraries
We’ll be using the following libraries — add them to your page’s File URLs section (under the JavaScript category):
https://cdn.jsdelivr.net/jquery/latest/jquery.min.js
https://cdn.jsdelivr.net/momentjs/latest/moment.min.js
https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js
These libraries give us access to moment.js (for date manipulation) and daterangepicker.js (for the actual date picker magic).
🎨 Step 2: Add the HTML Structure
Now, add the below div wherever you’d like the date range picker to appear — maybe inside a region or within a template. This will be our date range selector container:
<div id="reportrange">
<i class="fa fa-calendar"></i>
<span id="datevalue">Select Date Range</span>
<i class="fa fa-caret-down"></i>
</div>
This will display a simple box with a calendar icon, the selected date range, and a dropdown icon. We’ll make it look stunning in the next step.
💅 Step 3: Include CSS Library + Custom Styling
First, add the CSS file in the CSS File URLs section:
https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css
Then, add this inline CSS to your page’s Inline CSS or within your theme’s stylesheet for a clean, professional look:
/* Container styling */
#reportrange {
background: #ffffff;
cursor: pointer;
padding: 10px 14px;
border: 1px solid #d6d6d6;
border-radius: 8px;
width: 100%;
max-width: 320px;
display: flex;
align-items: center;
justify-content: space-between;
transition: all 0.25s ease-in-out;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
#reportrange:hover {
border-color: #2684ff;
box-shadow: 0 0 5px rgba(38,132,255,0.3);
}
#reportrange i {
color: #2684ff;
font-size: 16px;
}
#reportrange span {
font-size: 14px;
color: #333;
margin: 0 10px;
flex-grow: 1;
text-align: center;
}
.fa-calendar {
margin-right: 8px;
}
/* Optional: Dark mode-friendly datepicker popup */
.daterangepicker {
font-family: "Poppins", "Segoe UI", sans-serif;
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
⚙️ Step 4: JavaScript Initialization
Now comes the fun part — initializing the date range picker. The below code sets default values, updates the selected date range display, and even syncs the values to your APEX Page Items (P2_START_DATE and P2_END_DATE).
$(function() {
var start = moment().subtract(29, 'days');
var end = moment();
function cb(start, end) {
$('#reportrange span').html(start.format('MMM D, YYYY') + ' - ' + end.format('MMM D, YYYY'));
apex.item('P2_START_DATE').setValue(start.format('YYYY-MM-DD')); // provide correct item name
apex.item('P2_END_DATE').setValue(end.format('YYYY-MM-DD')); // provide correct item name
}
$('#reportrange').daterangepicker({
startDate: start,
endDate: end,
opens: 'right',
ranges: {
'Today': [moment(), moment()],
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'Last 7 Days': [moment().subtract(6, 'days'), moment()],
'Last 30 Days': [moment().subtract(29, 'days'), moment()],
'This Month': [moment().startOf('month'), moment().endOf('month')],
'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
}
}, cb);
cb(start, end);
});
👉 Replace P2_START_DATE and P2_END_DATE with your actual item names.
🧩 Step 5: Create APEX Items
Create two text items on your page:
- P2_START_DATE
- P2_END_DATE
We’ll store our selected dates into these items dynamically through the JavaScript function.
💾 Step 6: Keep Values in Session (Dynamic Action)
By default, JavaScript changes only exist on the browser side. To make sure your selected date range is available in session (for further PL/SQL processes or reports), we’ll use a simple Dynamic Action.
For both P2_START_DATE and P2_END_DATE:
- Event: Change
- Action: Execute Server-side Code
- PL/SQL Code:
null; - Items to Submit: Select the same item
This ensures every time your user picks a date range, APEX automatically pushes those values into session. 🚀
🧠Bonus Tip
You can easily modify the date formats or preset ranges (like “This Quarter”, “Last Year”, etc.) within the JavaScript initialization section — just update the ranges parameter accordingly.
🚀 Wrapping It Up
And that’s a wrap! 🎬 You’ve just built a clean, responsive, and APEX-integrated Custom Date Range Picker — one that not only looks awesome but also syncs perfectly with your Oracle APEX session. From adding the libraries to wiring it up with page items, you now have a powerful, production-ready component at your fingertips.
The best part? You can extend this setup endlessly — change the preset ranges, style it to match your theme, or trigger APEX reports dynamically whenever the user picks a date range. That’s the true beauty of mixing JavaScript + APEX together. 😎
If you’ve scrolled all the way down here — first off, kudos! 💪 That means you’re someone who actually finishes what they start (and trust me, that already puts you ahead of 90% of developers 😉). Now it’s time for the next step:
🔥 Head over to my YouTube channel Into The Oracle Verse 🔥
There, I’ve got a full step-by-step video of this exact implementation — plus plenty more tutorials on Oracle APEX, JavaScript integrations, and real-world tricks to make your apps shine.
👉 Click here to visit the channel & subscribe for more APEX awesomeness!
Until next time, keep experimenting, keep building, and may your APEX apps always stay bug-free! ⚡
— Jenish from Into The Oracle Verse
data:post.title
Written by
Published on October 28, 2025

No comments: