One issue that I run into periodically–especially when working with dynamic actions–is that the value of a page item in session state doesn’t match its value in the browser (what I call the DOM state). The simplest way to think about it is to view every page item as part of a form. Logically, when the user is entering data into a form, the HTML page elements have values that are not stored in APEX session state until the form is submitted. This is true whether the user is typing values in, or if the values are being set by a Set Value dynamic action or the $s(…) javascript function. And it’s true regardless of whether or not the page is actually a data entry form.
The issue that I run into is generally when I’m working on a different sort of page–typically, a report or a dashboard–that happens to include page items and dynamic actions. As an example, consider a page with two report regions, where the first region includes links; when the user clicks on a link, we want to set a page item and refresh the second report with details about the clicked-on link. This is a fairly straight-forward scenario, and can provide the user with a lot of relevant information in a compact, usable fashion.
My standard approach to this is to define the link target as a call to $s(…), which sets the value of a hidden page item. Then a dynamic action, set to fire on change of the hidden item, triggers the refresh of the second report region. But it turns out, this isn’t enough–because the $s(…) call sets the DOM state, while the report’s SQL is referencing the session state of the item. So although the report refreshes, it doesn’t reflect the new value of the hidden page item.
The solution, of course, is to set the session state of the hidden page item with the value from the DOM state. My first approach to doing this was to change the dynamic action to use two steps, with the first step being a PL/SQL action that looked like this:
The trick, of course, is the Page Items to Submit field, which is only present on PL/SQL actions; the values from any page items listed here are copied from the DOM state into session state when this action fires. There’s nothing else going on here, hence the null; code body. This solution works, but it’s pretty cumbersome, and isn’t self-documenting–someone looking at the dynamic action who doesn’t understand the trick is likely to be very confused by this action that “does nothing”.
Luckily, there’s a better way. When you edit a report, whether classic or interactive, you’ll note that there’s a Page Items to Submit field there, too! And it turns out that the submission happens whenever the report is refreshed, so by specifying the hidden page item in the list for the report, the original dynamic action–that just refreshed the report region–does exactly what we need it to. Much cleaner.
So, in general: whenever you build a report that depends on page or application items, go ahead and include those in the Page Items to Submit field. That way, if you ever decide to refresh the report via dynamic action, you won’t run into this issue.