Report Link: Save before Navigation
“We always click ‘Apply Changes’, then we click the button we actually wanted” – a user
Typically an Apex report with an “Open” or “Edit” icon will simply do an immediate navigation to the target page, passing the ID of the record to edit. When the user clicks this link, the page is not submitted and the user is instead redirected.
It’s easy to quickly build large and complex applications in Apex but it’s also very easy to build something that confuses and disorients your users. They only need one instance when something doesn’t work how they expected it to, and they will lose trust in your application.
For example: if most buttons save their changes, but one button doesn’t, they might not notice straight away, and then wonder what happened to their work. If you’re lucky, they will raise a defect notice and you can fix it. More likely (and worse), they’ll decide it’s their fault, and begrudgingly accept slow and unnecessary extra steps as part of the process.
You can improve this situation by taking care to ensure that everything works the way your users expect. For most buttons in an Apex page, this is easy and straightforward: just make sure the buttons submit the page. The only buttons that should do a redirect are those that a user should expect will NOT save the changes – e.g. a “Cancel” button.
For the example of an icon in a report region, it’s not so straightforward. The page might include some editable items (e.g. a page for editing a “header” record) – and if the user doesn’t Save their changes before clicking the report link their changes will be lost on navigation.
To solve this problem you can make the edit links first submit the page before navigating. The way I do this is as follows (in this example, the report query is on the “emp” table:
- Add a hidden item
P1_EDIT_ID
to the page- Set Value Protected to No
- Add something like this to the report query (without the newlines):
'javascript:apex.submit( {request:''SAVE_EDIT_ROW'', set:{''P1_EDIT_ID'':''' || emp.rec_id || '''} })' AS edit_link
- Set this new column to Hidden Column
- Modify the edit link Target:
- Type = URL
- URL =
#EDIT_LINK#
- Add a Branch at point “After Processing”
- Set the Target to the page to navigate to
- Set the item for the record ID to
&P1_EDIT_ID.
- Set the Condition to the following PL/SQL Expression:
:REQUEST='SAVE_EDIT_ROW' AND :P1_EDIT_ID IS NOT NULL
- Make sure the branch is evaluated before any other branches (at least, any others that might respond to this request)
- Modify any existing Processing so that the request SAVE_EDIT_ROW will cause any changes on the page to be saved.
You can, of course, choose different item names and request names if needed (just update it in the code you entered earlier). For example, to make it work with the default Apex DML process you might need to use a request like “APPLY_CHANGES_EDIT_ROW”.
Now, when the user makes some changes to the form, then clicks one of the record Edit links, the page will first be submitted before navigating to the child row.
Adding buttons to Apex pages is easy. Making sure every last one of them does exactly what the user expects, nothing more, and nothing less, is the tricky part!
Juergen Schuster
31 October 2016 - 3:45 pm
Love your easy to understand and simple solutions for complex problems 🙂
David Kyánek
5 November 2016 - 12:03 am
Jeff, one note to you or others, target page at Branch could not be the modal page… or ….?
Thanks for your work:-)
Farzad Soltani (@FarzadSo)
5 November 2016 - 3:21 pm
Wow, this is an amazing tip and it’s something I had never considered.
Thanks so much for sharing
Farzad Soltani (@FarzadSo)
5 November 2016 - 3:22 pm
Wow, such a nice tip. I had never noticed such problems could exist. And it was so easy to implement.
Thanks so much for sharing.