The improvement to Interactive Reports in APEX 5.0 has gotten mixed responses. Many people are very happy with the improvements, which include: multiple interactive reports per page, fixed headings, improved looks, improved usability, improved markup, and new features such as pivot.
However, people that had previously customized their apps by leveraging internal unsupported functions of Interactive Reports are lamenting the loss of the
gReport variable that enabled those customizations.
The improvements in 5.0 and any future improvements necessitated restructuring the code to isolate the internal details. What was left out is an API to the useful features that people had discovered and shared. As Anthony mentioned on the OTN forums this is something that we hope to rectify in the future. The rest of this article is for the curious and impatient.
While I was migrating Survey Builder to 5.0 I came across a place where it was using
gReport. On the Survey Responses page there is a Download button that did the same thing as the Actions > Download menu item. It accomplished this by using the undocumented
gReport.dialog2 function. This was not something that I had worked on originally (I didn’t do any of the Survey Builder reporting) but someone must have thought that it was useful to have a button to make the download capability more noticeable.
I was faced with a choice of removing the Download button or finding a way to do the same thing with the new Interactive Report widget. Luckily I am very familiar with the menu widget so I knew how to make a button do the same thing as a menu action.
I will explain how Survey Builder implements the Download button and in the process you will learn something about the APEX menus. I should point out that just because the Survey Builder packaged app does something doesn’t mean that it is supported. This is still undocumented stuff. In my opinion the aspects of the menu widget that I will be showing are reasonably stable. I don’t foresee them changing anytime soon and we use the menu widget API in many places in Page Designer and elsewhere.
There is lots that you can explore and learn by poking around in the browser console. To follow along run the Sample Database Application. Click on Customers in the side navigation to display the Customers Interactive Report. Then open Firebug or Developer Tools and select the Console tab.
Widgets (this applies to jQuery UI widgets) are attached to DOM elements and you can call methods on them as follows:
This customer report region has the Static ID
_ir” to the region static id and it will append “
_actions_menu” to the actions menu widget id. You can access the IR widget but there is not much you can do with it. To see what options it was initialized with enter the following in the console:
To see all the options of the IR actions menu type:
Menus are created not with markup but with the options object that is passed to the menu widget when it is created. Use the console to explore the options object returned by the above code (the details of how to do this are different for each browser). The items property is an array and each element of the array defines a menu item. You can read more about this structure in the code comments in
libraries/apex/widget.menu.js. The two menu item properties that we need to know about are id and action. We can use the id to look up a menu item. The action property is a function that implements the behavior. When the user selects an action menu item the action function is run. Note this applies to action menu items. Toggle and radio group menu items are different; they have set and get functions.
If you type the following in the console you will see that it does the same as selecting the Download menu item.
This uses the find method of the menu widget to lookup and return a menu item by id. Then it calls the action function of that menu item.
This technique applies to all new APEX menus for items that have an action. You just need to know or find the DOM id of the menu widget and the item id, which you can do using the browser console as shown above. Keep in mind that the menu item id is an optional property. If the menu item doesn’t have an id you can still access the action function but you would need to index into the items array or search for the label. Neither of these methods are as robust as finding by id.
How safe is it to do this? What is the risk of it breaking in the future? Well the code relies on three things.
- A small part of the menu API staying the same
- Interactive Reports will continue to use _actions_menu as the ID suffix for the actions menu
- Interactive Reports will continue to use irDownload as the download menu item id
The risk seems reasonable to me. If any of these assumptions fails in the future I won’t complain because I know that I’m relying on an undocumented interface. I can adjust to the change then or in the worst case remove the Download button.
I know that this doesn’t cover all the cases where
gReport was used to access Interactive Report internals but it may help some people in some cases.