I got this info from John Snyders (who looks after IG internally), so a big thanks to John.
There are 3 main parts to it.
1) Use various UI affordances to do custom processing in the context of current detail row
2) The custom processing is done in an ajax call to a PL/SQL procedure
3) Extract data from the detail row and the master row.
1 - They give many options for the UI and all are possible. In each case I recommend implementing the behavior with an action. Most of the IG examples use this method. (See interface actions
https://docs.oracle.com/en/database/oracle/application-express/20.1/aexjs/actions.html ) Keep in mind that defining the action and defining the UI to invoke the action are two different steps. For IG the action is defined by adding code to Advanced: JavaScript Initialization Code. In the initActions function add the action. There are examples in the Sample Interactive Grids app on pages 5 and 53. There are also many examples in the IG Cookbook (get the cookbook here:
https://hardlikesoftware.com/weblog/2019/11/04/apex-ig-cookbook-update-for-19-2/ ).
Actions often act on the selection or the current row. The example on page 53 uses an old (no longer recommended way to get the context row. It is best to use the getContextRecord method (
https://docs.oracle.com/en/database/oracle/application-express/20.1/aexjs/interactiveGridView.html#getContextRecord ). There are examples of using getContextRecord in IG cookbook pages 18, 25, 26. The general pattern is:
action: function(event, el) {
...
rec = view.getContextRecord( el )[0];
...
To act on the selection use the view getSelectedRecords method (
https://docs.oracle.com/en/database/oracle/application-express/20.1/aexjs/interactiveGridView.html#getSelectedRecords ) or the IG method by the same name (
https://docs.oracle.com/en/database/oracle/application-express/20.1/aexjs/interactiveGrid.html#getSelectedRecords )
A nice thing about using actions is that you can define a keyboard shortcut.
UI Options
A) A button in a column. A good example of this can be found in Sample Interactive Grids page 10. Look at the SRV column. It invokes a built in action. In this customers case they would invoke the action they define (for example it might be called "cancel-order").
B) Add to the row actions menu. This is the hamburger menu in the actions column row. I don't have an example of adding to the row actions menu but it is very simimilar to adding to the selection actions menu. See page 12 of the IG cookbook for example. The general idea looks like this (add to execute when page loads):
var view = apex.region("emp").call("getViews", "grid"),
menu$ = view.rowActionMenu$;
// add to the menu
menu$.menu("option").items.push({
type:"action",
action: "cancel-order"
});
C) Add to the selection actions menu. This is the one in the column header of the row actions column. It seems the customer wants to act on the row so this may not be what they are looking for. See IG Cookbook page 12 for example.
D) Add to the toolbar or toolbar Actions menu. This is possible but not ideal if you want the context of the current row.
2 - If all the custom behavior can be done with just JavaScript then they would be mostly done at this point but they want to call the server. There are 2 ways to do this.
1) is to use a DA Execute Pl/SQL Code action. This is the easiest option for most cases especially when all the inputs and outputs can be put in page or column items. The problem is this can only be done from a DA event and the above described action is not a DA.
2) Use the apex.server.process API. This gives more control and can easily be called from any JavaScript code. If they are comfortable defining a page or app process and calling this way then that is a good option.
If they want to use option 1 then they have to cause an event to be triggered from the action and define a DA on that event. If the action sets the value of a hidden page item then there is a natural change event that happens that they can use. Otherwise they can make up their own custom event.
3 - Accessing data from the current record and parent record. If the DA event is from a column item then you can just specify the column items from the same IG region in the Items to Submit attribute. A big limitation is that you can't reference columns from the parent IG region(s). And if the DA is triggered from a custom event or an event on any element outside the IG region then you can't specify columns in the items to submit. One option is to move the data that you need from the IG model into page items. This is an extra step and it negates some of the benefit of using the simpler DA Execute PL/SQL Code action.
Often all you really need is the row primary key to do any server processing. You can take additional data from the IG model record but you need to take more care that the user has not tampered with the data. If the values can be edited and you want to take in the edited values then no problem but if you need to make sure that the values have not changed then putting them in a page item first is not as safe.
To get around the limitation of not having access to data in the parent IG you can duplicate that data in the detail IG as hidden columns. This is wastefull of bandwidth and client memory but may be considered worth it in some cases.
If they want to use a DA and only need the detail record primary key then my suggestion is similar to Jayson's except I would define an action and put the $s inside the action function taking the primary key from the model record. I would use a column button (UI option A)
If they need more data from the detail and master records then I would define an action that uses apex.server.process to call a page or app process.
Note that unlike tabular forms, IG does not currently have the option to submit selected rows (it only sends the rows that have *changes*).
One way to work similar to the way tabular forms did is to define a button outside the IG region (e.g. "Cancel Order") that sets a hidden column of the selected rows to say "C" for cancel. This means that the row is now changed and will be submitted. Then the button submits the page. This can all be done from a dynamic action. (Beware bug 25891453 and use its workaround to set a hidden column.)