Rich Text Editor Pro v23.2 - Remastered Image Upload

Friday, September 29, 2023

In this article, we'll delve into one of the significant enhancements of our Rich Text Editor Pro 23.2: the new image upload mechanism. Let's explore why this feature is a game-changer for handling images in Oracle APEX applications.

The Challenge of Base64 Images

When end-users drag and drop images into their rich text documents, they are typically embedded as base64 images. This means the image is encoded using the base64 algorithm and added directly to the rich document's HTML. To illustrate, consider the following example of an image (5x5 px) encoded as base64 and included in the rich text document HTML:

alt="Red Dot">

The typical image size can vary from dozens of kilobytes to hundreds, or without any compression, it then can be easily counted in megabytes.

While browsers can display such images seamlessly, they pose several challenges:

  1. Increased storage requirements: Leaving images as base64 can significantly increase your storage needs, making your application more resource-intensive.
  2. Slower page loading: Loading documents with base64 images takes longer, as the entire CLOB value must be fetched from the database before the page can be rendered.
  3. Limited reusability: Reusing base64 images across different documents is impractical since each image must be manually copied and pasted.
  4. Lack of image insights: It's challenging to track how many images are embedded in saved documents unless you parse the CLOB and count HTML image attributes.

While this approach is mandatory when sending newsletters with images, it can only sometimes be helpful when you want to create documentation and have control over used images.


Images from the Web

The solution to problems #1,  #2, and #4 mentioned above is referencing images already available online via a unique URL address. Popular WYSIWYG editors (What You See Is What You Get) allow you to add an image from the web using an existing URL.

However, this approach doesn't address the problem of tracking images added to rich text documents from the database's perspective (point 3). Moreover, it can lead to unexpected issues when the third-party website deletes an image, rendering it unavailable.

The Solution: Intelligent Image Management

And here, after this extensive introduction, I can explain how cool Rich Text Editor Pro’s new upload mechanism is.

The solution to the above problems is simple (as an idea), and (fortunately for you) I already have it implemented for your convenience in our Rich Text Editor Pro.

The Plug-in Tracks Images in Rich Text Documents

When you load the CLOB value from the database, the plug-in collects information about images in rich text documents on page load. Additionally, whenever a new image is added or removed, the plug-in updates its session state, storing information about the image (type, when it was added, and whether it is removed from the rich text).

This collected information can be used when a page is submitted to either delete uploaded images from the database or store information on which rich text document the image is used.

Download Images Not Hosted in Your Database

When the update & upload mechanism is triggered (on-page submission or on-demand), the plug-in checks what images are delivered through the plug-in RESTful service. Once all images are collected (not uploaded by the plug-in RESTful service), the plug-in downloads them.

Upload Images and Save Them in the Database

Rich Text Editor Pro utilizes an APEX RESTful service to upload images and save them in the database table. The plug-in uploads images with predefined query parameters, including application ID, page ID, username, and session ID. These query parameters can be extended dynamically with any information you want to save along with the image. For example, you can send the currently edited document ID.

Uploaded images are under your control, and unless you delete them, they will always be available for your end-users to reuse in different rich text documents.

Uploaded image meta-data is saved in the plug-in session state, allowing developers to reference them as foreign keys in the database table when processing a page submission.

The supporting process plug-in reads the plug-in session state, and you can delete an image from the database or save it in the context of a currently edited rich text document. Both actions utilize PL/SQL code executed for each image separately.

Parallelization of the Uploading Process

In prior releases, when the plug-in started uploading images, it was slow since the Froala framework was uploading images individually. 

In version 23.2, I solved the problem by parallelizing the uploading images. Now, uploading images is much faster and more pleasant for end-users. 

Additionally, upload parameters are evaluated for each image separately in contrast to prior implementations when they were evaluated once for all images.

Upload Workflow and Summary for End-Users

The Rich Text Editor Pro upload process can be configured using JavaScript Initialization Code to let the plug-in decide what should happen when:

  • Any image failed to download - for example, due to CORS policy.
  • Any image failed to upload - due to image validation (mime type and maximum size), or an error was raised when saving the image in the database.

Why should you bother with any of these problems above? You might want to ignore these issues, cancel the whole process, or let the end user decide to ignore issues or stop the process.

Another enhancement is that the end-user can easily check which images failed to download or upload.

See the screenshot below presenting the result of canceling the upload process. The icons on the right show the number of failed images and open a preview of these images. Using the preview report, end-users can easily navigate to the image with a single click, remove (or replace) the troublesome image, and rerun the process!

Don't worry; uploaded images are saved in the database so that the next upload execution won't iterate over these images again!

Canceled Process

The update & upload workflow is quite a big topic to walk through, and I promise to shed some light on it in a separate blog post. 

For now, please reference the documentation which explains the technical nature of the plug-in update & upload workflow. You can also test it on the new example page in our brand-new sample application.

Upload Images on Demand

We value our customer feedback, and one question frequently asked was about triggering the upload process on demand without submitting the page. This wasn't possible with the previous implementation, but release 23.2 enables you to do so.

The supporting dynamic action plug-in exposes a new dynamic action, "Upload Images on Demand", and it performs all the same steps for uploading images, except it doesn't re-submit the page once the process finishes.

This feature allows developers to perform computations after uploading images and before saving a rich text document in the database. 

Since the upload process can be canceled or interrupted by an unexpected error, the dynamic action supports three optional JavaScript callbacks to be defined:

  • Done: When the uploading process finishes (everything was successful, or the plug-in/end-user ignored download/upload issues).
  • Cancel: When the plug-in automatically cancels the upload process or the end-user terminates it when prompted.
  • Fail: When the process is interrupted by an unhandled error while updating the plug-in session state.

You can utilize these callbacks to implement your application logic:

  • execute another dynamic action, 
  • perform an AJAX request, 
  • or simply submit the page with a new request.


I hope I shed some light on the remastered Rich Text Editor Pro upload mechanism and why it’s a good choice if you want to write rich text documents with images in your Oracle APEX applications.

Embrace simplicity and efficiency, and embrace a world where managing rich text documents with images has never been this easy.


If you would like to see the features I highlighted in action, please don't hesitate to give it a try in our brand-new sample application:

Solution: Image tracking and uploaded image processing

Go to Sample application \ Supporting Plug-ins \ Process \ Process Uploaded Images

This example page will teach you how the plug-in handles added, removed, and uploaded images. The key feature of this page is utilizing a supporting process plug-in to visualize whether an image was successfully uploaded and removed from the database.




Solution: Save uploaded images in the context of a document

Go to Sample Application \ Examples \ Save images in the context of rich text editor contents.


The page presents how the supporting process plug-in is used to save images in the context of an existing document. Processes utilize foreign keys to link uploaded images with edited documents. The result of page processing can then be previewed in a modal page presenting uploaded images existing in a rich document.




Feature: Update and upload image workflow

Go to Sample Application \ Examples \ Configure the plug-in update & upload images workflow.

This page allows you to test different configurations to ignore or cancel the upload process automatically or to ask the end-user at any step when an issue is raised. When the upload process fails or is canceled, the end user can preview the process summary by clicking the information icon in the top right corner.



Feature: Upload Images on demand

Go to Sample Application \ Supporting Plug-ins \ Dynamic Action \ Upload Images on demand.


This page presents the supporting dynamic action plug-in callbacks in action. Based on the upload process result, the three JavaScript callbacks are executed.