How to Let Users Pick a Date Range and Chart Type on a Dashboard in Oracle APEX

Add date pickers that refresh a chart and a report, a chart type switch that keeps the user's choice, and checks for wrong or forged ranges in Oracle APEX.

A dashboard is more useful when users can choose what they look at. Two controls cover most needs: a date range that limits the data, and a chart type that shows the same numbers as lines, bars or areas. Both should work at once, without reloading the whole page.

In Oracle APEX, this takes two date pickers, a select list and two dynamic actions. This guide builds a dashboard where a new date range refreshes a chart and a totals report, a wrong range shows an error, and the chart type switches in the browser and is kept after a reload.

The guide How to Build a Dashboard Page with KPI Cards and Charts in Oracle APEX builds a dashboard with fixed charts. This one adds the user controls: the date range filter, the region refresh, the chart type switch and the checks against invalid or forged values.

The example uses daily website visits from three traffic sources. The same steps work for any measure with a date, such as orders, tickets, bookings or sensor readings.

Step 1: Create the Tables

The example needs two tables. TRAFFIC_SOURCES holds the sources, and DAILY_VISITS holds the visits and signups per source and day. The insert generates data from 1 May to 23 October 2026:

Example:

create table traffic_sources (
  source_id    number generated by default on null as identity
               constraint traffic_sources_pk primary key,
  source_name  varchar2(30) not null
               constraint traffic_sources_name_uk unique,
  sort_order   number(3) not null
);

create table daily_visits (
  visit_id     number generated by default on null as identity
               constraint daily_visits_pk primary key,
  source_id    number not null
               constraint daily_visits_source_fk references traffic_sources,
  visit_date   date not null
               constraint daily_visits_date_ck check (visit_date = trunc(visit_date)),
  visits       number(8) not null
               constraint daily_visits_visits_ck check (visits >= 0),
  signups      number(8) default on null 0 not null,
  constraint daily_visits_signups_ck check (signups between 0 and visits),
  constraint daily_visits_uk unique (source_id, visit_date)
);

create index daily_visits_date_ix on daily_visits (visit_date);

insert into traffic_sources (source_name, sort_order)
values ('Search', 10), ('Social', 20), ('Email', 30);

insert into daily_visits (source_id, visit_date, visits, signups)
select source_id,
       visit_date,
       visits,
       round(visits * case source_name when 'Email' then 0.06 when 'Search' then 0.04 else 0.02 end)
from (
  select s.source_id,
         s.source_name,
         d.visit_date,
         round(
           case s.source_name when 'Search' then 900 when 'Social' then 520 else 260 end
           * case when d.visit_date - trunc(d.visit_date, 'IW') >= 5 then 0.6 else 1 end
           * (1 + (d.visit_date - date '2026-05-01') / 600)
           + mod(ora_hash(s.source_name || to_char(d.visit_date, 'YYYYMMDD')), 120)
         ) as visits
  from traffic_sources s
  cross join (
    select date '2026-05-01' + level - 1 as visit_date
    from dual
    connect by level <= date '2026-10-23' - date '2026-05-01' + 1
  ) d
  where not (s.source_name = 'Email'
             and d.visit_date between date '2026-10-05' and date '2026-10-09')
);

commit;

select s.source_name,
       count(*) as days,
       to_char(min(v.visit_date), 'YYYY-MM-DD') as first_day,
       to_char(max(v.visit_date), 'YYYY-MM-DD') as last_day,
       sum(v.visits) as visits,
       sum(v.signups) as signups
from daily_visits v
join traffic_sources s on s.source_id = v.source_id
group by s.source_name, s.sort_order
order by s.sort_order;

Output:

Table TRAFFIC_SOURCES created.

Table DAILY_VISITS created.

Index DAILY_VISITS_DATE_IX created.

3 rows inserted.

523 rows inserted.

Commit complete.

SOURCE_NAME       DAYS FIRST_DAY     LAST_DAY         VISITS    SIGNUPS
______________ _______ _____________ _____________ _________ __________
Search             176 2026-05-01    2026-10-23       170860       6834
Social             176 2026-05-01    2026-10-23       103418       2070
Email              171 2026-05-01    2026-10-23        54942       3297

A few details matter for the dashboard:

  • The check constraint DAILY_VISITS_DATE_CK accepts only dates without a time, and the unique constraint DAILY_VISITS_UK allows one row per source and day.
  • DAILY_VISITS_SIGNUPS_CK keeps signups between 0 and the number of visits. SIGNUPS uses DEFAULT ON NULL 0, so no trigger is needed.
  • The Email source has no rows from 5 to 9 October. The chart must show these days as 0.
  • The index on VISIT_DATE supports the date range filter.

Step 2: Create a Blank Page

In App Builder, open the application and click Create Page. On the Component tab, select Blank Page:

Create a Page wizard with the Blank Page tile marked with a red box
Choose the Blank Page type.

Set Page Number to 1040 and Name to Visits Dashboard. Turn Use Breadcrumb off, keep Use Navigation on, set Icon to fa-dashboard and click Create Page:

Create Blank Page screen with Page Number 1040, Name Visits Dashboard, Use Breadcrumb off, Use Navigation on and Icon fa-dashboard marked with red boxes
The page number, name and navigation entry.

APEX opens the new page in Page Designer.

Step 3: Add the Date Range Items

In the Rendering tree, right-click Body and choose Create Region. Set Name to Filters and keep the Type Static Content:

Page Designer with the region Name Filters marked with a red box
A region for the three controls.

Right-click the Filters region and choose Create Page Item. Set Name to P1040_DATE_FROM, Type to Date Picker and Label to From:

Page item P1040_DATE_FROM with Name, Type Date Picker and Label From marked with red boxes
The start date of the range.

Under Appearance, set Format Mask to YYYY-MM-DD. A fixed format makes the value easy to convert in SQL, whatever the language of the user:

Appearance group of P1040_DATE_FROM with Format Mask YYYY-MM-DD marked with a red box
The date format of the item.

Under Default, set Type to SQL Query (return single value) and enter this query. The range then starts 29 days before the latest day with data:

Example:

select to_char(max(visit_date) - 29, 'YYYY-MM-DD')
from daily_visits
Default group of P1040_DATE_FROM with Type SQL Query (return single value) and the query marked with a red box
The default start date.

Create a second item in the Filters region. Set Name to P1040_DATE_TO, Type to Date Picker and Label to To:

Page item P1040_DATE_TO with Name, Type Date Picker and Label To marked with red boxes
The end date of the range.

Under Layout, turn Start New Row off. Under Appearance, set Format Mask to YYYY-MM-DD:

P1040_DATE_TO with Start New Row off and Format Mask YYYY-MM-DD marked with red boxes
The end date sits next to the start date.

Under Default, set Type to SQL Query (return single value) and enter this query. The default range covers the last 30 days with data:

Example:

select to_char(max(visit_date), 'YYYY-MM-DD')
from daily_visits
Default group of P1040_DATE_TO with Type SQL Query (return single value) and the query marked with a red box
The default end date.

Step 4: Add the Chart Type Item

Create a third item in the Filters region. Set Name to P1040_CHART_TYPE, Type to Select List and Label to Chart Type. Under List of Values, set Type to Static Values, and turn Display Extra Values and Display Null Value off:

Page item P1040_CHART_TYPE with Name, Type Select List, Label Chart Type and the List of Values settings marked with red boxes
A select list with fixed values.

Click the Static Values button. Enter Line with return value line, Bar with bar, and Area with area. Turn Sort at Runtime off, so the list keeps this order, and click OK:

Static Values dialog with Line line, Bar bar, Area area and Sort at Runtime off marked with red boxes
The return values are the chart type names that Oracle JET expects.

Under Layout, turn Start New Row off, so all three controls sit in one row:

Layout group of P1040_CHART_TYPE with Start New Row off marked with a red box
The chart type item shares the row.

Under Default, set Type to Static and Static Value to line:

Default group of P1040_CHART_TYPE with Type Static and Static Value line marked with a red box
The page opens with a line chart.

Step 5: Write the Chart Query

The chart shows one line per traffic source and one point per day. The query reads the two date items, creates one row per day in the range, and joins the visits to it:

Example:

with params as (
  select to_date(:P1040_DATE_FROM default null on conversion error, 'YYYY-MM-DD') as date_from,
         to_date(:P1040_DATE_TO default null on conversion error, 'YYYY-MM-DD') as date_to
  from dual
),
days as (
  select p.date_from + level - 1 as visit_date
  from params p
  where p.date_to >= p.date_from
    and p.date_to - p.date_from < 366
  connect by level <= p.date_to - p.date_from + 1
)
select s.source_name,
       d.visit_date,
       nvl(v.visits, 0) as visits
from days d
cross join traffic_sources s
left join daily_visits v
       on v.source_id = s.source_id
      and v.visit_date = d.visit_date
order by s.sort_order, d.visit_date

The query works in three parts:

  • PARAMS converts the two item values to dates. DEFAULT NULL ON CONVERSION ERROR turns a text that is not a valid date into NULL instead of an error.
  • DAYS creates one row per day, only when the end date is on or after the start date and the range is at most 366 days long.
  • The cross join with TRAFFIC_SOURCES and the left join to DAILY_VISITS give every source a value for every day, with NVL turning a missing day into 0.

Run the query with P1040_DATE_FROM set to 2026-10-03 and P1040_DATE_TO set to 2026-10-10:

Output:

Session altered.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

SOURCE_NAME    VISIT_DATE       VISITS
______________ _____________ _________
Search         2026-10-03          796
Search         2026-10-04          699
Search         2026-10-05         1242
Search         2026-10-06         1139
Search         2026-10-07         1171
Search         2026-10-08         1233
Search         2026-10-09         1185
Search         2026-10-10          751
Social         2026-10-03          396
Social         2026-10-04          472
Social         2026-10-05          756
Social         2026-10-06          765
Social         2026-10-07          764
Social         2026-10-08          674
Social         2026-10-09          671
Social         2026-10-10          446
Email          2026-10-03          271
Email          2026-10-04          217
Email          2026-10-05            0
Email          2026-10-06            0
Email          2026-10-07            0
Email          2026-10-08            0
Email          2026-10-09            0
Email          2026-10-10          259

24 rows selected.

Email returns 0 from 5 to 9 October, although DAILY_VISITS has no rows for these days. Without the generated days, the Email line would simply skip them.

Step 6: Add the Chart Region

Right-click the Filters region and choose Create Region Below. Set Name to Daily Visits and Type to Chart:

Page Designer with the region Name Daily Visits and Type Chart marked with a red box
The chart region below the filters.

Under Advanced, set HTML DOM ID to visits_chart. The JavaScript code in Step 10 finds the chart by this ID:

Advanced group of the chart region with HTML DOM ID visits_chart marked with a red box
A fixed ID for JavaScript.

In Page Designer, the Static ID shown under Advanced is locked. The HTML DOM ID is the id that ends up on the page.

Click the Attributes tab. Set Type under Chart to Line, and under Settings set Time Axis Type to Enabled. The time axis spaces the days evenly and prints the month only where it changes:

Attributes tab of the chart region with Chart Type Line and Time Axis Type Enabled marked with red boxes
A line chart with a time axis.

Under Advanced, enter this function in Initialization JavaScript Function. It sets the chart type from the select list before the chart is drawn:

Example:

function (options) {
  var type = apex.item('P1040_CHART_TYPE').getValue();
  if (['line', 'bar', 'area'].indexOf(type) > -1) {
    options.type = type;
  }
  return options;
}
Advanced group of the chart attributes with the Initialization JavaScript Function marked with a red box
The chart type comes from P1040_CHART_TYPE.

The function only accepts the three known types. Any other value leaves the type set in Page Designer, which is Line.

Step 7: Create the Chart Series

Expand Series under the chart region and select New. Set Name to Visits. Under Source, set Type to SQL Query and enter the query from Step 5:

Series Visits with Name, Source Type SQL Query and the query marked with red boxes
One series reads the chart query.

Set Page Items to Submit to P1040_DATE_FROM,P1040_DATE_TO. Under Column Mapping, set Series Name to SOURCE_NAME, Label to VISIT_DATE and Value to VISITS:

Series with Page Items to Submit P1040_DATE_FROM,P1040_DATE_TO and Column Mapping Series Name SOURCE_NAME, Label VISIT_DATE, Value VISITS marked with red boxes
The Series Name column creates one line per source.

Page Items to Submit sends the current date values with every data request of the chart. It also stores them in session state, so the page keeps the range when it is opened again.

Expand Axes and select y. Set Title to Visits:

Axis y with Title Visits marked with a red box
The y-axis title.

Step 8: Add the Totals Report

A dashboard usually has more than one region that follows the date range. This example adds a report with the totals per source. The query uses the same date checks as the chart:

Example:

with params as (
  select to_date(:P1040_DATE_FROM default null on conversion error, 'YYYY-MM-DD') as date_from,
         to_date(:P1040_DATE_TO default null on conversion error, 'YYYY-MM-DD') as date_to
  from dual
)
select s.source_name,
       count(v.visit_id) as days_with_data,
       nvl(sum(v.visits), 0) as visits,
       nvl(sum(v.signups), 0) as signups,
       round(100 * sum(v.signups) / nullif(sum(v.visits), 0), 1) as conversion_pct
from params p
cross join traffic_sources s
left join daily_visits v
       on v.source_id = s.source_id
      and v.visit_date between p.date_from and p.date_to
where p.date_to >= p.date_from
  and p.date_to - p.date_from < 366
group by s.source_name, s.sort_order
order by s.sort_order

Run it for 1 to 10 October:

Output:

Session altered.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

SOURCE_NAME       DAYS_WITH_DATA    VISITS    SIGNUPS    CONVERSION_PCT
______________ _________________ _________ __________ _________________
Search                        10     10560        423                 4
Social                        10      6354        125                 2
Email                          5      1526         91                 6

DAYS_WITH_DATA counts the days that have a row in DAILY_VISITS, so Email shows 5 days for these 10 days. The left join keeps every source in the report, even one without any rows in the range.

Right-click the Daily Visits region and choose Create Region Below. Set Name to Totals by Source and Type to Classic Report. Under Source, set Type to SQL Query, enter the query above and set Page Items to Submit to P1040_DATE_FROM,P1040_DATE_TO:

Classic report Totals by Source with Name, Type, Source Type SQL Query, the query and Page Items to Submit marked with red boxes
The report reads the same date items.

Under Advanced, set HTML DOM ID to totals_report:

Advanced group of the report with HTML DOM ID totals_report marked with a red box
A fixed ID for the report.

Click the Attributes tab. Under Messages, set When No Data Found to No visits for this date range.:

Attributes of the report with When No Data Found No visits for this date range. marked with a red box
The message for an empty or invalid range.

Expand Columns under the report. Select VISITS and set Format Mask to 999G999G990. Do the same for SIGNUPS:

Column VISITS with Format Mask 999G999G990 marked with a red box
Thousands separators for the counts.

Select CONVERSION_PCT, set Heading to Conversion % and Format Mask to 990D0. Also set the Heading of SOURCE_NAME to Source:

Column CONVERSION_PCT with Heading Conversion % and Format Mask 990D0 marked with red boxes
The conversion rate with one decimal.

Step 9: Refresh the Regions When the Dates Change

In the Rendering tree, right-click P1040_DATE_FROM and choose Create Dynamic Action:

Context menu of P1040_DATE_FROM with Create Dynamic Action marked with a red box
Create a dynamic action on the date item.

Set Name to Refresh on Date Change. Keep Event Change and Selection Type Item(s), and set Item(s) to P1040_DATE_FROM,P1040_DATE_TO. Under Client-side Condition, set Type to JavaScript expression and enter this expression:

Example:

(function () {
  var f = apex.item('P1040_DATE_FROM').getNativeValue(),
      t = apex.item('P1040_DATE_TO').getNativeValue();
  return f instanceof Date && t instanceof Date && f <= t && (t - f) / 86400000 < 366;
})()
Dynamic action Refresh on Date Change with Name, Event Change, Item(s) P1040_DATE_FROM,P1040_DATE_TO and the JavaScript expression marked with red boxes
The condition decides between the True and False actions.

getNativeValue returns the date picker value as a JavaScript Date. The expression is true only for two valid dates, with the start on or before the end and at most 366 days between them. These are the same rules as in the SQL queries.

Select the True action Show. Set Action to Execute JavaScript Code and enter this code. It removes an error message left from an earlier wrong range:

Example:

apex.message.clearErrors();
True action with Action Execute JavaScript Code, the code apex.message.clearErrors(); and Fire When Event Result Is True marked with red boxes
The first True action clears old errors.

Right-click the dynamic action and choose Create TRUE Action. Set Action to Refresh, Selection Type to Region and Region to Daily Visits:

True action Refresh with Selection Type Region and Region Daily Visits marked with red boxes
Refresh the chart.

Create one more True action with Action Refresh and Region Totals by Source:

True action Refresh with Selection Type Region and Region Totals by Source marked with red boxes
Refresh the totals report.

Right-click the dynamic action and choose Create FALSE Action. Set Action to Execute JavaScript Code and enter this code:

Example:

apex.message.clearErrors();
apex.message.showErrors([{
  type: 'error',
  location: 'page',
  message: 'Pick a From date on or before the To date, no more than 366 days apart.',
  unsafe: false
}]);
False action with Action Execute JavaScript Code, the showErrors code and Fire When Event Result Is False marked with red boxes
A wrong range shows a page error instead of a refresh.

Fire on Initialization stays off for all four actions. On page load, the regions already use the default dates.

Step 10: Switch the Chart Type

Right-click P1040_CHART_TYPE and choose Create Dynamic Action. Set Name to Switch Chart Type and keep Event Change with the item P1040_CHART_TYPE:

Dynamic action Switch Chart Type with Name, Event Change, Selection Type Item(s) and Item(s) P1040_CHART_TYPE marked with red boxes
A dynamic action on the chart type item.

Select the True action Show, set Action to Execute JavaScript Code and enter this code:

Example:

var type = $v('P1040_CHART_TYPE');
if (['line', 'bar', 'area'].indexOf(type) > -1) {
  apex.region('visits_chart').widget().ojChart('option', 'type', type);
}
True action Execute JavaScript Code with the ojChart code marked with red boxes
The chart type changes in the browser.

apex.region('visits_chart').widget() returns the Oracle JET chart of the region. Setting its type option redraws the same data as bars or areas, without a new request to the server.

Right-click the dynamic action and choose Create TRUE Action. Set Action to Execute Server-side Code, Language to PL/SQL, PL/SQL Code to null; and Items to Submit to P1040_CHART_TYPE:

True action Execute Server-side Code with Language PL/SQL, PL/SQL Code null; and Items to Submit P1040_CHART_TYPE marked with red boxes
Save the choice in session state.

The PL/SQL block does nothing. Items to Submit is what matters: it sends the new chart type to the server and stores it in session state. When the page is opened again, the Initialization JavaScript Function from Step 6 reads it and draws the chart with the chosen type.

Step 11: Turn Off the Unsaved Changes Warning

In a first test, the page asked "Leave site?" every time a user had changed a filter and then left the page. APEX treated the changed items as unsaved data. Filters are not data to save, so turn the warning off for this page.

Select the page node Page 1040: Visits Dashboard. Under Navigation, turn Warn on Unsaved Changes off and click Save:

Page 1040 properties with Warn on Unsaved Changes off marked with a red box
No warning when users leave the dashboard.

Step 12: Test the Dashboard

Run the page as a user with read-only access. It opens with the last 30 days and a line chart. The Email line drops to 0 from 5 to 9 October:

Visits Dashboard with From 2026-09-24, To 2026-10-23, Chart Type Line, a line chart with three sources and the Totals by Source report
The dashboard with its default settings.

The report matches the SQL output for the default range:

Output:

Session altered.

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

SOURCE_NAME       DAYS_WITH_DATA    VISITS    SIGNUPS    CONVERSION_PCT
______________ _________________ _________ __________ _________________
Search                        30     32212       1290                 4
Social                        30     19523        389                 2
Email                         25      8554        514                 6

Select Bar in the Chart Type list. The chart changes at once, and the report stays as it is:

Visits Dashboard with Chart Type Bar marked with a red box and the same data as grouped bars
The same data as a bar chart.

Select Area. The areas are drawn on top of each other, not stacked, so each area still ends at the visits of its own source:

Visits Dashboard with Chart Type Area marked with a red box and an area chart
The same data as an area chart.

Now select Bar again and click into the From field. The date picker opens on the current value:

Date picker popup of the From item showing September 2026 with the 24th selected
The date picker of the From item.

Set From to 2026-10-01 and To to 2026-10-10. After each change, the chart and the report refresh. The chart keeps the Bar type:

Visits Dashboard with From 2026-10-01 and To 2026-10-10 marked with a red box, a bar chart for ten days and the totals for this range
Ten days as bars, with matching totals.

The report shows the same totals as the SQL output in Step 8. The values in the chart were also read from the chart widget in the browser for 3 to 10 October. All 24 values matched the SQL output in Step 5.

Reload the page. It opens with 1 to 10 October and the Bar chart, because the dates and the chart type are in session state.

Now set From to 2026-10-15, after the To date. The error message appears, and no request is sent:

Visits Dashboard with From 2026-10-15 marked with a red box and the error Pick a From date on or before the To date, no more than 366 days apart.
A From date after the To date is refused.

The chart and the report still show 1 to 10 October, while the From field shows the new date. The error message tells the user why. The same message appeared for a range from 1 January 2025 to 23 October 2026 and for the text abc. The next valid change cleared the message.

Step 13: Test Forged Values

A user can skip the client-side check from the browser console. Signed in as a read-only user, the item values were set without the change event, and both regions were refreshed directly:

Visits Dashboard with From abc, the chart message No data to display and the report message No visits for this date range.
A forged date only returns empty regions.

The texts abc, 2026-02-30 and 2026-10-01' or 1=1 --, a reversed range and a range from 1 January 2024 to 23 October 2026 were tried. Each time the chart showed No data to display, and the report showed its no-data message. No request failed. This query shows why:

Example:

set linesize 200
alter session set nls_date_format = 'YYYY-MM-DD';
column date_from_text format a24
column date_to_text format a12
column result format a8
select t.date_from_text,
       t.date_to_text,
       to_date(t.date_from_text default null on conversion error, 'YYYY-MM-DD') as date_from,
       to_date(t.date_to_text default null on conversion error, 'YYYY-MM-DD') as date_to,
       case when to_date(t.date_to_text default null on conversion error, 'YYYY-MM-DD')
               - to_date(t.date_from_text default null on conversion error, 'YYYY-MM-DD') between 0 and 365
            then 'rows' else 'no rows' end as result
from (
  select '2026-10-01' as date_from_text, '2026-10-10' as date_to_text from dual union all
  select 'abc', '2026-10-10' from dual union all
  select '2026-02-30', '2026-03-05' from dual union all
  select '2026-10-10', '2026-10-01' from dual union all
  select '2025-01-01', '2026-10-23' from dual union all
  select '2026-10-01'' or 1=1 --', '2026-10-10' from dual
) t;

Output:

Session altered.

DATE_FROM_TEXT           DATE_TO_TEXT    DATE_FROM     DATE_TO       RESULT
________________________ _______________ _____________ _____________ __________
2026-10-01               2026-10-10      2026-10-01    2026-10-10    rows
abc                      2026-10-10                    2026-10-10    no rows
2026-02-30               2026-03-05                    2026-03-05    no rows
2026-10-10               2026-10-01      2026-10-10    2026-10-01    no rows
2025-01-01               2026-10-23      2025-01-01    2026-10-23    no rows
2026-10-01' or 1=1 --    2026-10-10                    2026-10-10    no rows

6 rows selected.

Every text that is not a valid date becomes NULL, and the range checks reject the rest. The values are bind variables, so the text with or 1=1 is never run as SQL.

A forged chart type was tested too. The values pie and line');alert(1);// were added to the select list from the console and selected. The chart kept its type, because the code only accepts line, bar and area. After a reload, the chart was a line chart again and no alert appeared.

Things to Know

  • Set Page Items to Submit on every region that reads the date items. A region refresh sends only the items listed there.
  • Generate the days of the range and left join the data, so missing days show as 0 instead of disappearing from a line.
  • Check the range twice: in the client-side condition for a clear message, and in SQL for forged requests.
  • Use a fixed date format such as YYYY-MM-DD for the date items, and convert the text with DEFAULT NULL ON CONVERSION ERROR.
  • The chart type can change in the browser with the ojChart type option. The data stays the same and no request is needed.
  • Store the chart type in session state and read it in the Initialization JavaScript Function, or a reload brings back the type from Page Designer.
  • Turn off Warn on Unsaved Changes on pages where items only filter data.
  • When the client-side check fails, the regions keep their old data. Keep the error message visible until the user fixes the range.

Related Guides

Conclusion

Date range and chart type controls turn a fixed dashboard in Oracle APEX into one that users can explore. Two date pickers and a dynamic action refresh any number of regions, and a select list with a few lines of JavaScript switches the chart between line, bar and area.

The details make it reliable: Page Items to Submit on each region, generated days for gaps, a clear message for a wrong range, safe SQL for forged values, and session state that keeps the user's choices after a reload.

Get more Vinish.dev tutorials on Google

See my articles more often when you search Google.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE, author of four books on Oracle APEX, SQL and PL/SQL, and Oracle Forms, and a software developer building Oracle database applications since 2001.

guest

0 Comments
Oldest
Newest Most Voted