Dynamic click handling with APEX actions in 22.1
Use Case
#Sometimes we need to do something in APEX that is not as declarative as other things and therefore requires some frontend code or complex dynamic actions with custom code. It is super great to have this option because these extra steps can have huge benefits for the users. For me, one of these cases is when I need to dynamically handle click user clicks e. g. for slightly different actions for every link in a report row.
One specific use case is shown in the following video:
The table shows some basic info, to get more we can click the details link. Because the details report is on the same page as an inline drawer we need to do some manual steps:
- Listen to the click on all the links in the table
- Check which of the many rows was clicked (specifically grab the PK ID from that row)
- Refresh the details info to fetch the data for the clicked row
- Open the inline drawer
How I did it before 22.1
#I created an HTML column in the report with a link that has a href-attribute to nothing (#
) and added a specific class that I can target later. I also added a data attribute that includes the ID of each row as a value (data-id="#ID#"
).
In a dynamic action, we can then listen to a click on the used class (modal-trigger
). It is also important to set the event scope to dynamic and use the report region ID for the static container. Otherwise, the click listener does not work when the report is refreshed after pagination or search.
After a click happened we can extract the ID from the data attribute with the following JS code inside the dynamic action:
After fetching the ID and putting it into a page item we can refresh the detail report in the modal via a Refresh
action (make sure page items to submit
is set to the changed ID item). Afterward, we can open the modal with the Open Region
action.
The new actions link syntax
#John Snyders recently shared a great blog post about JavaScript APIs in the new APEX 22.1 release.
In there he showed a way to call APEX actions from a link href-attribute. It offers a great way to omit manual listening for a click. It also has a great URL like syntax to pass parameters:
Previous use case with action links
#Back to the previous use case, we can now get rid of our data attribute in the link as well as the class. Instead, we change the href-attribute to the following:
Then we can define an action in the execute on page load JavaScript field. The action and argument names have to match the ones specified in the link:
We could also manually refresh the report and open the model in that action with JavaScript. Instead, I created a dynamic action that listens to changes to the P99_ID
item and defined these steps in the declarative way there.
John Snyders also mentioned in his post that in the future there may be a way to directly trigger dynamic actions with these actions. That would be a great addition.
A question of personal preference
#In the end, you have to decide if you like doing the listening to the action yourself or letting APEX handle it. As my excitement about this small change may indicate I prefer the apex.actions
way and will use that in the future (this is the way :) ).
The actions API also comes in handy if you want to add keyboard shortcuts (e.g. apex.actions.addShortcut("Ctrl+Shift+E", "send-email")
).
But I think the proposed integration with dynamic actions would put the nail into the coffin as it would be very declarative. Today you have to know where the actions are defined to know how this magic works. I think new developers would expect the handling of actions would be in the dynamic actions section.
If you have a different way to reach the same goal let me know!
Bonus: I thought this would also be possible before 22.1
#As I still develop mostly in older versions of APEX I thought there could be a way to still use actions in the same manner there. As I thought only the link href
syntax for actions was new I thought I could achieve the same effect with some JavaScript from the href-attribute. The actions API has an invoke method that can be used to trigger manually actions:
Note that we have to pass null to the 2nd and 3rd parameters (pEvent
, pFocusElement
) as we have no way of capturing them this way. So we can’t use the event source in the action itself. This only works again in a manual click handler:
I thought I can use this syntax till the environments are upgraded to 22.1 and then easily switch to the new syntax. Unfortunately while trying this out I noticed there also was a new change to the invoke function. In versions before 22.1 there is no fourth parameter for passing values (here is the new API).
So in this case I still need to add data attributes with IDs to the links and manually listen for the events as I need the ID to set a page item.