Oracle’s low-code platform is constantly improving. With the launch of Oracle APEX versions 22.1 and 21.2, the technology gained many powerful and useful features. Let’s look at them in detail and see what they can be used for.

Disclaimer (December 15, 2022): this article was originally published in July 2022, but it has been updated with new information regarding features added in Oracle APEX version 22.1.

In one of my previous articles – Oracle APEX tutorial: Uncover Oracle’s best-kept low-code secret – I’ve told you what Oracle APEX is, and what it can do. However, It’s an evolving technology, which constantly changes and improves. In this blog post, I’ll show you some of the most beneficial features that Oracle has introduced in versions 22.1 and 21.2.

Version: 22.1:

  • Data Generator
  • Task Definitions
  • YAML
  • Tokenized ROW Search
  • Workspace Static File Export
  • List Subscriptions + IG editing of List Entries
  • Monaco
  • CKEditor

Version 21.2:

  • REST Enhancements
  • Smart Filters
  • Email Enhancements
  • Map Enhancements
  • Static File Editor
  • Progressive Web App (PWA)

I’ll go over all of them in detail and show you how they work using a demo application I’ve made for this purpose. Also, this article is based on a presentation I made for Warsaw IT Days 2022 (also known as WDI). If you prefer the video format, you can always watch it on our channel on YouTube.

Introduction to Oracle’s low-code platforms

Let’s take a few steps back and start with a formal introduction to Oracle’s low-code solutions. The company has two of these:

  • Application Express (APEX) – a platform you can use to develop applications using wizards that allow you to connect ready-made features and elements. It allows you to create apps up to 20x faster than in the case of traditional development, and with 100x less coding required. It’s the topic of all my articles on the Pretius blog.
  • Visual Builder Cloud Service – a cloud service that is all about extending fusion applications. It’s good for modifying or improving something you already have. I won’t cover it in more detail here.

What you need to know about Oracle APEX

The important thing to note here is that Oracle APEX is a web-based solution. You develop, deploy and run your applications in the web browser. APEX works with mobile, standalone, desktop, and tablet browsers. The solution can be used by Database Developers, Front-End Developers, and Citizen Developers (non-technical people who take part in the process of software development thanks to APEX’s ease of use).

You can run APEX using Oracle’s Autonomous Cloud. The database there is self-repairing, self-driving, and self-running. It comes in two flavors: Autonomous Transaction Processing (ATP), and Autonomous Data Warehouse (ADW). However, you can also run APEX as a Database Cloud Service (DTS), on-premise, or using a private cloud. There are both official and community-made containers too – for example, the one using Docker, which I use in the examples in this article.

I won’t take you through APEX’s history, the advantages of working with it, examples of use, as well as the setup and basics of building applications with this solution. If you want more information on some or all of these things, you can find it in my Oracle APEX tutorial – the previous blog post.

Demo app setup

I start with logging in to APEX and clicking the Create button. Normally, you’d have three options to choose from. You could create an entirely new application, build one from a file (you can upload a CSV/XLSX/XML/JSON file or copy and paste data), or create a so-called Starter App – a pre-built, sample application.

A screen showing the sample app.

I run my app and authenticate myself. Out of the box, the app is pretty simple. I can navigate through the application, and check the navigation bar, including an About page and user details. I also have a footer at the bottom, but no actual content on the site. However, with this, I’m ready to show you all the exciting new features.

Oracle APEX new features – version 22.1

Oracle APEX version 22.1 is the largest update so far. It’s quite monumental and contains a record number of bug fixes. It also offers some cool new features.

Data Generator

The Data Generator feature lets you easily and quickly generate some test data for your tables. I’ll show you how it works, but first, let’s take a lookthe table I’ll use in my demos.

I’m going to use Quick SQL in my example. It’s fantastic for generating tables. I’ve typed the word “passengers” to create a table that looks like a list of passengers on a flight. I’ve got first and last name, an airport column, passport number, class, and so on. I’ve used the indent system by putting the name of the table, followed by space, and the columns I want.

An image showing the Quick SQL string.

As you can see, the columns were automatically created. I’m also using /insert 10, which is a table directive that tells Quick SQL “please create 10 inserts with random data ”. Thanks to this, it generatedcolumns with fitting data, such as first name and last name, and even fake email addresses made based on these names. You can also use column directives such as vc64, which gives it a varchar2(64 char) limit.

When it comes to the date of birth, Quick SQL doesn’t recognize “dob”, so you have to follow it with “date”. It sets it to sysdate – 29, which makes it a date in the past. It’s enough for the purpose of this example.

Things are more complicated when it comes to more complex types like baggage since Quick SQL doesn’t understand what it is, so it gave it a random Latin string. That’s not enough for me, so I trick it by setting a check constraint – Carry on, Large, Trolley, or Bag. That makes it pick one of these options. The Class works the same way – a check constraint with Economy, Business, and First options.

This is kinda a workaround, as I don’t really want these check constraints there. But it’ll do for now. I let it do the script and then I remove these constraints.

Passport numbers are usually big numbers, so I use a constraint that forces Quick SQL to choose a random number between 1000000 and 9999999. I will also remove that later.

The Airport column is an even bigger headache since I can’t create a check constraint with 42 000 options (this is how many airports there are, according to my Alexa). So I leave the Latin string in this case.

How to use Data Generator

So, how to use this feature? When I have my table opened in the APEX Builder, I select SQL Workshop, Utilities, and then Data Generator.

An image showing the App Builder.

The next step is to create a blueprint – a JSON definition of how data should be supplied to that specific table. I can base it on an existing table or even a fictitious table. For example, you have a table, and I don’t have access to it. You tell me about it, and I create it for you and give you the blueprint, which you can upload to populate your table.

Aside from basing a table on an existing one, I can also build a blueprint from scratch or import it from a JSON file (of course, not just any, it has to be a valid blueprint). Well… at least in theory, because in practice, there are currently some bugs with importing JSON files, and it doesn’t always work as well as it should.

I’ve decided to create my blueprint from an existing table. It’s worth noting that I can copy and paste from a table or manually search for tables I’ve used previously. I can also change the number of rows. For the purpose of this demo, I’ve chosen the previously created Passengers table.

An image showing creaing a blueprint from a table.

Creating the blueprint takes a lot of time, especially if you use more than one table as a source, so keep that in mind.

The blueprint has a name, a display name, and a description. There are also IDs and display names for tables and columns. I can also change the sequence (the order in which it appears in the table list) and the number of rows. Additionally, I can specify the data source (Built-in, Inline, Sequence, or Formula – in the last case, I have to enter it into a field below) and change various details.

I’d also like to mention that when it comes to the date of birth (DOB) column, I’ll have to use the same format mask (you can see it on the screen below) everywhere. Otherwise, it won’t work when I – or anyone else – try to import the CSV file later.

An image showing the format mask.

Another thing worth pointing out – one I don’t like very much about the Blueprint Designer – is that I can’t use drag & drop to, for example, change the sequence. I have to enter data manually for each column to change its place in the order.

I can also create a custom data source which I did in the case of my Class column. I simply selected the Custom Data Source option, clicked Add Data Source, and entered the details I wanted.

An image showing how to add a data source in the Blueprint Designer.

I’ve created a custom data source called SEATING_CLASS with the specification you see below, and I can now select it as my Custom data source.

An image showing the custom data source.

I can export the blueprint as a JSON or a CSV file. I can also scale it to change the number of rows. Finally, data from the blueprint can be inserted into the database.

Task Definitions (or Human Tasks)

Another new feature is Task Definitions, also known as Human Tasks. To describe it in the simplest way possible, it’s a way to request something for your managers to approve so that you can move on with it. For further explanation, look at the following diagram.

An image showing the Approvals diagram.

There are two tasks here (the green tiles). When you start to create a task, you specify what the primary key is, and the definition it’ll use. All tasks have an ID and a State (e.g., Claimed, Rejected). There’s also task monitoring. These, rather than views, are a set of pipelined functions that provide details about the tasks.

When you start looking at a task, there are severalthings you can do with it. You can Claim it (pick it up), Approve it, Reject it, Release it, set it as a Priority, or give it to someone else. These task-related activities are called Events.

How to use Task Definitions

Now, I’ll show you how to use the Task Definitions feature. We’ll start with the passengers table I’ve shown you before. When I open it in SQL Workshop there’s a Create app button right there. I click it.

An image showing the SQL Workshop.

I start with customizing my app’s icon, theme style (Redwood Light in my case) and navigation style (I’ve chosen Mega Menu and I encourage you to use that in your applications too – it’s great).

For features, I’ve selected Install Progressive Web App (you can read more about that in the next part of this article, where I talk about features introduced in version 21.2), and About Page. Then I simply clicked Create application. I found that it takes a little bit more time when you create an app through the table, instead of the standard page.

Next, I run my app and sign in. As you can see, the app has four main sections: Dashboard, Passengers Search, Passengers Report and Calendar (if you’re curious about that last element, I can tell you that it’s there because I’ve added the date of birth column to my table).

An image showing my app.

I take a look at the Passengers Report and check the first passenger on the list – a person called Luciana.

An image showing the table.

Luciana’s flying the Economy class, so let’s make her a Christmas present and bump her up. But I don’t want to have to type the class each time I upgrade a passenger, so in order to do that, I quickly edit the Class field and change its type to Select list. I also have to specify a List of Values for it to work, so I choose Static Values, define them as Economy, First and Business.

After saving the changes and refreshing the page, my app has a drop-down list in the Class field.

An image showing the drop-down list.

However, when I hit the button and apply changes, APEX will have to process the form to update the data, and I want to change this to an approval step.

I click the button next to Type under Server-side Condition and select Never – this deactivates the process. Next, I create a new process, which will be my “Human Task – Create”. I need to provide the Task Definition, however I don’t have one yet, so I’ll need to create that next.

An image showing the App Builder.

To do that, you need to select Task Definitions from the App Builder’s main page and then click the green Create button.

I name it Seat Change, specify the Subject as “Upgrade of &PASSENGER. from &OLD_SEAT. to &NEW_SEAT.” and give it a Static ID: “SEAT_CHANGE”. I also set the Priority to 3-Medium. When I click Create, APEX tells me that I also need to create Participants to assign additional owners and parameters for the task. I’ll do that soon, but first, let’s look at the task details page.

An image showing task definiions.

When someone is working on a task, you probably want to display important information on the Task Details Page if you have one. I want one, so I click the Create Task Details Page button and let APEX assign it the next available page number.

In the Settings there’s also the Action Source field. Actions have to work on some kind of data, so I have to specify what that data is. I can pick a table manually, but I can also select SQL Query, which is the option I decide to use. I type in the query you can see on the screen below. It basically tells APEX to pick data from the Passengers table, where the ID is:APEX$TASK_PK” (if you want to know why it had to be written that way, you can see details on the help page).

An image showing task definitions.

The query also needs to set a NEW_SEAT parameter, so let’s set that up now. I enter the required details in the field below. I select String as the Data Type and label it as Required and Visible. The former means I won’t be able to start a new task without this parameter, and the latter specifies that the task owner will be able to see the parameter on the details page.

An image showing task definiions.

You can also set the Deadline by selecting from several Due on Type options (Interval, SQL Query , Function Body, Expression and Scheduler Expression), but I decided not to do that.

Now, it’s time to add Participants. I create a “Potential Owner” with a SQL Query Value Type and the Value of “SELECT ‘BO’ FROM DUAL UNION ALL SELECT ‘DEMO’ FROM DUAL” – you would normally use a user table. I also add a “Business Administrator” and this type uses a Static Value Type – I enter my e-mail address as the Value.

An image showing task definitions.

I save the changes and then proceed to add actions by clicking the Add Action button, which takes me to another page.

My action is called “Upgrade”. I can either run some code (the Execute Code option) or Send Email. I choose the former and select Complete from the list of On Event options. I specify the Outcome as Approved and enter the Success Message.

Under code I type in “update passengers set class = :NEW_SEAT WHERE id = :APEX$TASK_PK;” and my task definition is done.

We can go back to editing the page in App Builder. Now, when I click Create Process, I can select “Human Task – Create” under Identification -> Type and set the Definition as “Seat Change”. To get everything working, I also need to enter the Primary Key (“P5_ID”), change the New Seat parameter’s Type to Item and point to the “P5_CLASS”.

Now, when I apply all the changes and go back to Luciana’s entry in my table, I can finally bump her up to first class. However, this change doesn’t happen automatically – it has to be done by a human, so it isn’t visible in the table yet. Clicking Apply simply means my Human Task was started behind the scenes.

How to see if it works as it should? Well, if I want a visual representation of this task – and I do – I’ll need to create a new page.

An mage showing creating a page.

I choose the Create Page option and select Unified Task List from the menu – this allows me to use one task list in all my applications. I name it “My Tasks” and specify My Tasks as Report Context.  I do this for all three of these unified tasks lists.

Now, when I check the mega menu of my application, I can see three types of task lists: My Tasks, Admin Tasks and Initiated by Me. I select the last option.

An image showing the task lists.

As you can see, Luciana’s upgrade to first class is the first position on the list. However, there’s a problem – the task hasn’t been assigned to anyone yet, so the poor passenger could be waiting forever! We’ll help her out, but before we get to that, let’s address the issue you’re probably wondering about: what are the other entries on the task list?

An image showing the tasks.

These come from my other applications. If I don’t want to see them here, I’ll need to change my pipelined function by adding a “WHERE DETAILS_APP_ID = :APP_ID” line into the SQL Query to hook the DETAILS_APP_ID. I’ll need to do that on all my pages to change this. So, word of caution: try not to use the APP_ID column if you want to avoid such problems.

An image showing the SQL query.

Now, let’s get back to Luciana’s task. To see how everything works, I need to log in as a second user – the Potential Owner called “BO” I defined before – in a different browser.

An image showing both users.

That user – on the right – now sees the task and can either Approve or Reject it. They can also enter Task Details to see the relevant information, leave comments or request additional info. As you can see, any changes made to this task are visible for the other Participant (on the left) and vice versa. The task is switching between them.

An image showing the exchange of messages.

Everything seems to be working correctly: in a fictional place, a fictional employee is now working on changing the flight class for my fictional person. After a short exchange between my two alter egos, Luciana’s class is finally changed. Lets hope she enjoys her flight!

An image showing the updated class.

Overall, I think Human Tasks are a really great feature. I haven’t found too many problems with it, and I like that It’s possible to customize the app to see the details page. It simplifies work on workflows substantially, so I recommend using it. I think it’s a welcome feature for Oracle APEX.

YAML Export

The last big feature I’d like to mention is the YAML Export which allows you to export your application into a readable YAML format.

To test this, I click export, download the package that contains my app and look inside. There’s my app split into pages, the installation file, but there’s also a separate “readable” folder which contains a set of YAML files – one for each page.

An image showing the folder.

When I open the task_definition.yaml file in the Visual Studio Code, it looks like this:

An image showing the file in VSC.

There are headings by column, I have SQL queries, nothing is quoted, and everything looks very readable.

YAML allows you to do comparisons very easily. You’d normally download SQL as your file format which is kind of readable, but far from perfect to work with.

An image showing the SQL exports.

Now, look at how clear and understandable YAML is by comparison. It’s a night and day difference.

An image showing YAML exports.

Using VSCode to compare the files makes noticing differences even easier. I’ve changed some details in the file to highlight how it works.

An image showing YAML comparisons.

Finally, SQL Statements are unquoted within the YAML notation. This makes copying entire SQL queries easier.

An image showing he SQL statements.

YAML Exports are very handy and useful indeed. I have a couple of observations that should help you understand when and how to use it:

  • YAML only contains values where there’s an attribute
  • YAML is only exportable in full APP, not at Page Level
  • YAML isn’t importable (if it was, we could do full merges with the YAML format, which is probably the future)
  • Binary files aren’t exported, even base64 (so even if I could import YAML, it wouldn’t be my whole app, because image files would be missing)
  • YAML is always split – no single file, unlike SQL

Overall, this is probably the future of APEX imports and exports, as it should allow faster and easier merging and maybe even possible backporting.


Finally, here are some additional smaller features in version 22.1 that are worth mentioning.

  1. Tokenized ROW Search – you can search for a word sequence like “large bag” and it’ll also show results for “bag large”, order of words doesn’t matter since each word is a token.
  2. Workspace Static File Export – you can now export static files directly from your workspace. It was very awkward to do that previously, and now you can simply do it from the export page.
  3. List Subscriptions + IG editing of List Entries – you can now subscribe to a list and use it in all your applications. List entry editing can be performed in an interactive grid.
  4. Monaco – some changes were made to the code editor. It displays bad characters, and it can also auto-complete code. All JavasScript code editors are aware of JS functions in the Function and Global Variables box at the page level.
  5. CKEditor – CKEditor has seen significant improvements as well. You can now have a full editor, and you can use plugins, which extend the feature set (for example, you can use them to allow pasting an image into the rich text editor).

Oracle APEX new features – version 21.2

The 21.2 version wasn’t as groundbreaking as the 22.1, but it still brought many useful improvements. Let’s look at some of them.

REST Enhancements

The first feature I’ll present to you is REST Enhancements, and there are several of them. Let’s go over them one by one.


I start by going to Shared Components from my app’s main screen in APEX. This option allows me to set things up for pages to use. I select REST Data Sources to source some employee information – this is pre-built data, I’ve made it ready beforehand.

I choose Simple HTTP on purpose so that APEX knows nothing about this web URL apart from the name. I call it “EMP” and enter the URL address.

A screen showing the data source.

My data source has information – first and last name, phone number, email address, and salary, among other things – on several employees. All of this is made up, of course. There’s a limit of 30 employees per page, but there could be more Employees in total since there’s more than one page in the data source.

A screen showing the data.

I go back to the wizard and click Next several times. There’s no authentication, and I’ll detail pagination later. The last step is data source discovery – APEX goes into the data source and shows you all the information on the screen. I’m happy with it so I click the Create REST Data Source button and finish. Now, I have a REST source called “EMP”.

I’ll now present that data on the page by using an interactive report. I edit my page by clicking the button in the right corner (I prefer to do it this way, instead of dragging the report from Gallery, as it’s faster this way), and selecting Body and Create Region. I call the region “Employees”, enter all the necessary information, and select Interactive Report as the type. I also choose the location – REST Source – and select my “EMP” source. I can customize things further by changing the columns you can see on the left.

A screen showing the report.

My page has data from my REST endpoint now. I only have 30 rows there, but I know there are more than 30 entries. This is where the new feature comes in!

Previously, to navigate through all the pages, and find all the data, I’d have to do something clever like writing a plug-in – which is not an easy feat. Now, I can use pagination. The Oracle APEX Team has looked through many different endpoints, identified patterns in pagination, and represented them in APEX.

An image showing pagination settings.

I choose Page Size and Fetch Offset and set the parameters by copying data from my data source. The Page Size URL Parameter is “limit”, Rows Offset URL Parameter is “offset”, and Has More Rows Selector is “hasMore”. I have no Page Size Maximum. After that, I click the Apply Changes button.

An image showing the pagination settings.

When I go back to my application and refresh the page, I can see I have 50 records on the page. There are more, I can cycle through them all by changing the page.

I can also use the search field to look for a specific person – for example, if I type “Abanda” it’ll show me all the people with that phrase in the email address. Very handy!

A screen showing search results.

REST catalog

Let’s move on to the next point. Consider you’ve got several REST endpoints and you want to bundle them together so that they can be shared between different workspaces. This is what the REST catalog is for.

To show you how it works, I have to get back to the App Builder level and click the Workspace Utilities button. This is because the feature I’m talking about here actually isn’t in the app itself, but a level above it. I choose the REST Source Catalogs option.

A screen showing the REST catalogs option.

I need to start by creating a catalog group, so I click the Create Group button in the right corner. I call it “HR Function (Group)”.

After that, I can start creating a catalog. I click the Create Catalog option, select my “HR Function (Group)” group and name my catalog “EMP”. The Internal Name is the same. I type in a description and click Create once again.

An image showing catalog details.

I now have a catalog, but it doesn’t have any services yet. I go to Shared Components (there’s an icon in the right corner of the screen – next to the Edit Page button – that you can use to quickly switch to that screen) and select REST Data Sources. When I click my “EMP” data source, it gets assigned to that catalog. I click the Save to Catalog button and go back into Workspace Utilities -> REST Source Catalogs. My “EMP” catalog now has 1 service assigned to it.

An image showing assigned services.

It’s worth noting that the Catalog Services screen – the one I can get to by clicking the 1 Services field you see above – is itself a report. You can search for a specific name and it’ll return corresponding records with their description and information about their operations – in the case of my “EMP”, it’s GET. I can also export the catalog by selecting the option on the right and then clicking the Export button.

If I go back a level – to the REST Source Catalogs screen – I can import that file by dragging and dropping it on the field in the center of the screen.

An image showing importing.

You can use this to import catalogs – for example, when you go from one environment to another or when you have a catalog you want to share. APEX will notify you if a catalog with such name already exists but you can override it.

Smart Filters

Smart Filters are another new feature I’d like to show you. From my application’s screen, I click Edit Page 1 and create a new page by using the + icon in the corner. After that, I select Report and Smart Filters.

An image showing page creation.

I accept the defaults until the Data Source page, where I choose the REST Data Source option. I select my “EMP” as the source that is to be used. APEX shows me a list of filters I can include in my report.

An image showing smart filters creation.

Notice that only some of them – those that are searchable and have checkboxes – can be “smart filter enabled”. I select every filter I can – EMAIL (varchar2), JOB_ID (varchar2), LAST_NAME (varchar2), FIRST_NAME (varchar2) and PHONE_NUMBER (varchar2) – and click Create to finish creating the page.

When I run my page now, you can see the changes. If I click the search field, I’m offered a number of options I can use to specify what I want to look for. When I choose any one of them, additional details will appear that’ll help you narrow your search down even further. For example, clicking Last Name immediately shows names along with a number of entries that have them.

An image showing search results.

Checking some of these boxes will enable the filters and limit the entries shown to those that fit the criteria which can be very handy.

Of course, you can change the layout any way you want – for example, you can move the search screen to the left side using a page template.

An image showing search results.

Email Enhancements

Okay, let’s talk about emails. In APEX 21.2 I can send them in several ways. I can use the Processing tab in the Page Designer. To do so, I click Create Process and select Send E-Mail in the Type field in the Identification section. After that I just fill in the details – I can also use an email template to make the message more appealing and readable.

An image showing e-mail templates.

I can also send an email through the APEX_MAIL package. In itself, this is nothing new – I could always do that. However, now I can also use automation. It’s a background process that can run tasks– including emailing – via a scheduled event at the database level. So, I can send things automatically every hour, day, etc.

Let’s take a look at email templates. I go back to the Shared Components screen, and this time I select the Email Templates option. I click the Create Email Template button and I can fill in whatever details I want in several sections of the message – the Header, the Body, and the Footer. I can also change the formatting.

It’s worth noting that I can also load ready-made templates – such as Order (see picture below), Event, Scheduled Outage, and so on – and then customize them further.

An image showing template details.

APEX even gives you the exact code you can use to send an email that uses that template through an API. You can also copy templates to use in another application.

An image showing the copying of e-mail templates.

Map Enhancements

The next feature I want to show you has to do with the way APEX handles maps. First, I need to create a little table for holding addresses that’ll also have a map. I’ll do it using the Quick SQL tool that you can find in SQL Workshop->Utilities. It’s a quick and easy way to create tables.

I type in what you can see on the left side of the screen and the tool automatically generates the code required for that SQL script. I Save it and then Review and Run it. Quick SQL is a very cool and handy utility tool. I could even create an app based on that script alone, though I don’t need to do that right now.

An image showing QuickSQL.


Now that I have my table, I can get back to my application to start showing off some new features. Geolocation will be the first one.

I start by creating a set of two new pages. I click Create Page on my app’s main screen, select Report, and then Report with Form. I fill out the Report Page Name and Form Page Name fields by typing in Addresses and Address respectively. I then select Modal Dialog under Form Page Mode so that my application displays a dialog screen on that – like the one that I’m typing all of this in, in fact.

An image showing the modal screen.

I specify the Navigation Preference (Create a new navigation entry) and choose my “X_ADDRESS_DET” table under Table / View Name. I also select the ID (Number) as the Primary Key Column. I also modify the look of components, give them proper names, change the spacing, size of fields that seem too big, and so on.

A screen showing the settings.

I also need to configure the Geolocator element. The minimum is street name and city which I set up under Street Item and City Item, linking them to “P4_ADDR_1” and “P4_CITY”, respectively. I also set Country Type to Item and select “P4_Country”.

To make everything work correctly in the app, I also have to create a Dynamic Action under Trigger Geocoding – the result will be a search button on the bottom of the dialog screen. To do that, I right-click and choose Create Dynamic Action which I call “Search”. I configure the template and give my button an icon by typing its name (“fa-search”) in the Icon field. I also switch the Hot option on to make it theme-specific.

After that, I still need to create yet another Dynamic Action – this time it’s for that “Search” button so that pressing it triggers geocoding. I right-click Search, select Dynamic Action, and call it “Click”. After that, I click Show on the left side and select the action Trigger Geocoding from the drop-down menu at the very top of the screen. Then, I select the “P4_GEOLOCATOR” item under Affected Elements.

An image showing the geolocator.

With that, I’m pretty much done. In my app, the result of my work looks like this:

An image showing the app.

Now, if I type an address in, it’ll show me the place I look for on the map. What’s more, if the application can’t find that precise location, but locates a similar address – and I decide that’s the correct one – it’ll automatically change the address.

I can also line up the Match Vector. It’s a string of 17 digits – corresponding to the same number of address attributes, such as Address Point, House Number, Street Prefix and Street Suffix, among others. To put things simply, it’ll give me more information about how the address was determined – how well it matches what I look for. To do this, I select “P4_GEOLOCATOR” element from Region Body section on the left, and change the Match Vector Item in Settings to “P4_MATCH_VECTOR”.

An image showing the match vector settings.

Now, when you type in an address and select the result offered by the Geolocator, you’ll see the Match Vector string under the County and Country fields.

An image showing match vector in the app.

It’s worth noting that the Match Vector is saved into the database. The Geolocator represents the map, but saves it as a GEOJSON object.

An image showing the address.

Display Map

I’ll use that GEOJSON to show you the display map. I go back to Page Designer and edit the third page of my app. I create a new page item – “P3_MAP” – in the Region Body and change its Identification to Display Map. Keep in mind that “Display” usually means the item is read-only, and that’s the case here. I set the Height (300 pixels), specify the source as a Static Value and copy-paste the GEOJSON string from before, but I change the numbers slightly – just to play with it a bit, see where it takes me.

The result is a nice-looking map that shows me an area near Swadlincote, north-east of Birmingham (UK).

An image showing the map.

However, I think the map is too zoomed in for my taste, so I get back to Page Designer and modify the Zoom Level value in the Settings – I change it to 7 (default was 14). Now, that’s much better – pretty much what I wanted.

An image showing a zoomed out map.

The map is interactive, so I can move around, check different places out, and so on. I can also add a tooltip that’ll display when you click the pin. It can be edited in the Label section of the “P3_MAP” object’s settings in the Page Designer. It supports HTML, so the text can be formatted in a numnber of useful ways.

It’s also worth mentioning that the map technology only works in the browser – not at the database level. So, you don’t have to worry about ECL access issues.

Static File Editor

Let’s go back to the Shared Components section of APEX, so that I can show you another useful feature – the new Static File Editor.

Automatic minification

I click on Static Application Files under Files. It’s an area that allows me to easily upload files into the database and access them through the browser. I could click Create File and drag whatever I want to upload onto the Drag and Drop Files field. However, I decide I want to create a new file I name “CSS.css”. I copy-paste its content from a different file I have ready. This is what it looks like:

An image showing the CSS.css file.

Now, the cool thing is that when I click the Save Changes button, the file is saved and automatically minified at the same time. When I go back to the Static Application Files area, I find both versions of the file there. I didn’t have to do anything. I like this and I think it’s gonna be very useful.

Less Compiler

Less (Leaner Style Sheets) are popular way of extending CSS by including constructs such as variables, embedding classes (known as mixins) and even functions. Less examples can increasingly be found across the internet. Unfortunately Less support is not native in your browser unless its compiled in to CSS

Now, thanks to APEX’s new Less Compiler, which automatically compiles Less into CSS, things are much easier. To show you what I mean, I quickly create a “less.less” file – the very same way I created the “CSS.css” file just a few minutes ago. I paste some Less code in there.

An image showing the Less compilier.

And now, if I go back to the static files, I can see it has been both compiled and minified. It has all the references, so it can be used in your application. And, it does the same in JavaScript, though I won’t show you that here. Very handy indeed.

Progressive Web Apps (PWA)

The last feature I want to show you is Progressive Web Apps – also known as PWAs. As you probably know, it’s the ability to install your applications natively to your operating system – iOS, Android, and Windows, which is what I’m using here.

First, I go back to my app’s main screen and click the Edit Application Properties button. I need to check if the Friendly URLs option is checked. This will make my PWA app very secure. Thankfully, the feature is on, and the Progressive Web Apps option is also turned on already. I change the Installable setting under it and provide a description for my app.

An image showing the progressive web apps settings.

I leave Display and Screen Orientation options as is. I change theme color to blue and background color to yellow, and click Apply Changes.

What did that do? It created another entry on my app’s navigation bar, which allows me to install my progressive web app.

An image showing the installed app.

When I install it, I can run my application as a native app which I can pin to my task bar. I can navigate, use all the features, click on the interactive map – everything works exactly the same. It also adjusts to my screen size. I could also change the layout and look further, if I decided it doesn’t work well on, say, a mobile device.

An image showing the installed app.

As you can see, it was very easy to install, and it’s just as easy to remove from your PC – just click the Uninstall *Application Name* option under the Settings menu (it’s the icon with three dashes on the top bar).

An image showing the Uninstall option.

New features in Oracle APEX – the plaform keeps evolving

Oracle APEX has changed in considerable ways with the launch of the latest version, and even the version before it. It’s already a pretty powerful low-code solution, but the team behind it is still working on new things. As new features are released, I’ll also keep you up to date with the most important changes. I also encourage you to try out the features I showed so far. I hope this article inspires you to learn more about Oracle APEX and perhaps consider it for your business application or another low-code project in the future. Feel free to tweet or e-mail me if you have any questions (contact details are below – in my bio).

Do you need certified low-code developers?

Pretius Low-Code has a deep understanding of low-code platforms, and Oracle APEX development is our specialty. If you’re interested in a powerful app or system created with this technology, drop us a line at (or using the contact form below). We’ll get back to you in 48 hours.