APEX Dynamic Action only fired once. ( Static vs Dynamic Event Scope of Dynamic Action )

Picture this:

You've created an awesome interactive report with a new column to display icons or links. Now, you've added a dynamic action to this new column. When users click on the icon or link, you want it to update the status in the table and refresh the report. You've set up the dynamic action, saved the report, and eagerly run the page. Clicking the icon in the first row works like a charm! But, uh-oh, the dynamic action doesn't work when you click on the icon in the second row. Confused, you head back to the page designer to inspect the dynamic action. Everything seems to be in order there. You give the report another run to see if anything changes. This time, the dynamic action works for the second row. But wait, now it's failing for the third row! Suddenly, you've noticed that the dynamic action only fired once upon page load each time. The inconsistency leaves you scratching your head, wondering what's causing this hiccup.

Does this scenario seem all too familiar? Have you ever encountered a situation where your dynamic action fired only once?

Let's dive into why this is happening and find a solution together.

Refer to the interactive report I mentioned in this blog. In that report, I have created a column "Mark as Received". I created a dynamic action "Mark Product as Received" on that column to update the "Status" column in the table.

In APEX, Dynamic action has an attribute "Event Scope". The default value of this attribute when you create a new dynamic action is "Static". This attribute is responsible for the above behavior of our report. Let's explore how.

When you create a dynamic action, you will define Event (when the dynamic action will fire), Event Handler (what action the dynamic action will perform), and Triggering Element (which element will trigger the dynamic action when certain event occurs over them).

What is Binding?

Binding generally refers to the process of associating an event handler to an event on a particular element.

In APEX, binding occurs when our page is loaded. This is like setting up the rules for how our page behaves.

During this loading process:

  1. The browser parses and builds the Document Object Model (DOM) for our page.

  2. At same time, based on the definitions/details we have set within dynamic action are attached to elements of our page - think of it like sticking a note on these element "this is what you should do when interacted with". This "sticking" is what we call 'binding'.

  3. Now once that's done - From hereon whenever user interacts with any these 'bound' elements, corresponding events get fired triggering the actions we defined in the dynamic action.

It means, when the page loads, the dynamic actions are attached with all the matching triggering elements on the page and all the dynamic actions are available to execute at least once if any event occurs on those triggering elements.

Great! Everything is going so well until the triggering element is updated (through partial page refresh), or new elements are dynamically added using JavaScript after the initial page load.

If any of these occur on the page then whether the dynamic action executes a second or successive time depends on the value of Event Scope attribute of dynamic action.

So let's understand the "Event Scope" attribute.

The Event Scope in a dynamic action determines whether the dynamic action remains active or 'bound' to a triggering element when that triggering element is refreshed (through partial page refresh) or dynamically added/altered(using JavaScript) after the page has initially loaded.

The possible options for these attribute are Static, Dynamic, and Once.

  1. Static (Default):

    • In a static event scope, the dynamic action is bound to the elements present in the DOM (Document Object Model) only once at the time of page load.

    • If elements are added, updated, or removed from the DOM dynamically after the page load (e.g., through Partial Page Refresh or JavaScript), the previously set dynamic action will no longer be bound to it and its static bindings are lost and the dynamic action is not triggered again until after the next full refresh of the page.

    • Static event scope is suitable for elements that are present on the page when it initially loads and do not change dynamically after the initial page load.

  2. Dynamic:

    • In a dynamic event scope, the dynamic action is still bound to the elements present in the DOM at the time of page load. However, if elements are added or updated to the DOM dynamically after the page load, the binding between between triggering elements and their attached events continues working seamlessly post-refresh operations also.

    • Dynamic event scope is suitable for scenarios where elements are added or updated dynamically after the initial page load, and you want the dynamic action to apply to all elements, including those added dynamically.

  3. Once:

    • In this event scope, the dynamic action will be triggered only once after the page load, and then it will unbind from the triggering element right after the first execution, regardless of whether the triggering element continues to exist within the Document Object Model (DOM) afterwards or not.

    • The dynamic action is not triggered again until after the next full refresh of the page.

If this is clear to you, then let's come back to our report.

In our report, the dynamic action has a click event as the trigger, with the event handler containing all the actions defined in the true actions. The triggering element is the "markReceived" CSS class. Whenever any element on our page with this class is clicked, it triggers the dynamic action, initiating the actions specified in the True Action section. One of the actions is Refresh using which we are refreshing our interactive report region.

What happened when you refresh the region using dynamic action:

When you refresh a region in Oracle APEX using a Dynamic Action, the following steps typically occur:

  1. The AJAX Call: When this dynamic action is triggered, an AJAX call is made to the server from your web browser. This process runs asynchronously and does not block or interfere with user interaction on your page.

  2. Processing on Server-Side: The server-side processes for that region (like SQL queries or PL/SQL function returning SQL Query) are rerun during call which pulls updated data for that particular region.

  3. Return of Data & Update of UI: The server returns fresh HTML generated by processing updated – this HTML then replaces old content currently present inside given region within page – All of these happens without needing any full-page reload thus giving seamless experience end-users by updating only needed parts quickly & efficiently.

This means that whenever the interactive report region is refreshed using a dynamic action, the old DOM is replaced with the new DOM freshly fetched from the server.

So in our report, if we set the Event Scope of the dynamic action to "Static", then after the page load, when we click on the icon for the first time, it will work. However, since the "Refresh" action refreshes the region and replaces the old DOM with the new DOM, the event that was bound to the triggering element will no longer be attached to the triggering element. As a result, dynamic action stops functioning, and it is not executed anymore despite clicking on the icon, until the next full refresh of the page.

To ensure it works consistently, we need to set the Event Scope to "Dynamic." This way, even after the region is refreshed, the dynamic action will continue to work seamlessly without any issues.

2
Subscribe to my newsletter

Read articles from Rutvik Prajapati directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rutvik Prajapati
Rutvik Prajapati