My Favorite APEX Plug-ins

Plug-ins are a great way to gain functionality in your applications without having to re-invent the wheel.  There are several plug-ins that I use regularly in my applications that I highly recommend:

  • Skillbuilders SaveBeforeExit 3.0.2 (www.skillbuilders.com) – easily warn users before leaving a page of unsaved changes and highlight the unsaved changes
  • Skillbuilders SuperLOV 3.0 (www.skillbuilders.com) – multiple column pop-up LOV with filtering
  • Alertify (www.apex-plugin.com) – give your alerts/confirmations/prompts extra style
  • Simple Checkbox (apex.oracle.com/plugins) – easily display a  single checkbox that allows you to set 2 values; perfect for Y/N
  • Dropzone (github.com/Dani3lSun/apex-plugin-dropzone) – I really want to use this plug-in!  I’m very impressed with the demo.  This plug-in allows you to easily upload files either via drag and drop, file upload dialog box, or copy/paste.  The only reason I have not implemented this yet in my applications is that not all browsers/versions are supported.  It appears at this time Chrome and Firefox 50+ are supported but not IE.

The following plug-ins I exported from the sample packaged APEX applications. These plug-ins are great for developing dashboards and displaying metrics:

  • Badge List
  • CSS Bar Chart
  • Big Value List
  • D3 Bar Chart
  • D3 Pie Chart

Remember to show your plug-in developers some love.  Many of them develop their plug-ins in their spare time and allow others to use them free of charge.  If you like a plug-in, like the developers page and/or give them a positive review!

Multiple tabular forms on a single page workaround

I’m sure many of you are like me and are anxiously awaiting the production release of APEX 5.1 that includes the new data grid control.  The ability to effectively create pages with multiple tabular forms to handle multiple child tables and/or master-detail-detail relationships is a necessity for me and in the meantime I’ve had to get creative and come up with a workaround.

One approach is to use reports on your page to display the multiple detail tables and then launch edit pop-ups from each of the reports to edit the detail records.  This works great in some instances but for a particular project the users wanted to be able to directly enter the data for the parent and all of the detail records on the same page without having to invoke multiple pop-ups.

Another approach would be to have multiple regions where the region source is a PL/SQL block calling a database function that returns a SQL statement to generate a manual tabular form (see my series on Developing Dynamic Tabular Forms for more information on how to do this).

The approach I took, while not 100% perfect, does the trick.  First, you will need to set the Embed in Frames attribute in your application’s Security settings to “Allow from same origin” for this to work.

For each child table, I created a separate page with a tabular form. From my main page where the data entry is to occur, I created iframe regions that call the tabular form pages.  In the src of the iframe I passed the values for the foreign keys.  Each tabular form has its own set of Submit buttons, but I wanted users to also be able to click on just one Submit button to save everything.  To do this, I created a javascript function that is called by the main Submit button.  This function will cycle through all of the iframe regions on the page and submit them.  Then the main page is submitted.  Since I used the SaveBeforeExit plug-in on my page, I had to manually disable the warning before submitting the main page. If you don’t use SaveBeforeExit, you’ll need to remove this part from the setTimeout function:

$(document).apex_save_before_exit('disableWarning');

The setTimeout function is used to ensure that all of the iframes have had time to submit before submitting the main page, otherwise the iframes would not finish submitting before the main page was submitted which caused issues.  This function would need to be added to the HTML Header of your page enclosed in script tags:

function submitAll(pRequest)
{
 var frames = document.getElementsByTagName('iframe');
 var count = frames.length;
 
 for (i = 0; i < count; i++){
 top.frames[i].apex.submit('SUBMIT'); 
 }
 
 setTimeout(function(){$(document).apex_save_before_exit('disableWarning');apex.submit(pRequest)}, 3000); 
}

Then in your Submit button set the Action to Redirect to URL and enter this as your URL Target:

javascript:submitAll('SAVE');

You can access the demo application here (credentials are guest/demo): Multiple Tabular Forms Demo

At some point in the future after 5.1 is released, I will probably look into redoing this page using the data grid control.  In the meantime this gets the job done.

Modal Dialogs – Removing the ‘X’ cancel button and using Skillbuilders SaveBeforeExit

Modal dialogs…I love them, I hate them.  Since I’ve discovered them I find them to be very useful but not without their challenges.  Two issues I recently had to deal with was being able to use the Skillbuilders SaveBeforeExit plug-in in my modal dialogs, and how to keep the built in ‘X’ cancel button from appearing on select pages.  I wanted the ‘X’ to not appear on modal dialogs that have data entry to keep better control over the user exits to prevent accidental data loss.  I also wanted to be able to use the SaveBeforeExit plug-in since I have already used extensively throughout my applications and my users were accustomed to it.

If you want to across the board remove the ‘X’ from all modal dialogs called from a page, you can simply include the following in the inline .css on the calling page.  However, if you do this and you have help items on your page, it will also remove the ‘X’ on your help pop-ups, which means you won’t be able to close them.

button.ui-button.ui-widget.ui-state-default.ui-corner-all.ui-button-icon-only.ui-dialog-titlebar-close { 
 visibility: hidden !important; 
}

To remove the ‘X’ on select pages, add the following code in the Dialog Attributes for the modal page you wish to remove the ‘X’:

open:function(event,ui){parent.$('.ui-button.ui-widget.ui-state-default.ui-corner-all.ui-button-icon-only.ui-dialog-titlebar-close').hide();}

I was finding that the Skillbuilders SaveBeforeExit plug-in was not firing to warn users on my modal dialogs.  After some research I learned this is a timing issue with when the warning fires and the fact that the modal has already closed and the markup is gone.  I came up with a workaround, and although it won’t get you the full features of the plug-in such as highlighting the changed fields, it at least allows you to leverage the change detection and warn the user there are unsaved changes.  My modal dialogs that have data entry contain a ‘Close’ button and I wanted to warn users when clicking the button if there were unsaved changes.  To do this:

  • Create a dynamic action on the Click event of your button.  In the Condition attribute, select JavaScript expression and enter the following for the Value:
$(document).apex_save_before_exit('modificationDetected');
  • For your first True action, you will want to use the built in Confirm that comes with APEX (or I like to use the Alertify plug-in) to warn the users there are unsaved changes and ask if they wish to continue.
  • Your second True action will be a Close Dialog action.
  • Create a False action that will also be a Close Dialog action.

That’s all there is to it!  If changes are detected, the user will be warned and prompted whether to close, otherwise the modal will close.

Return to last edited row in a tabular form after Submit

I have a tabular form page that has the potential to get very lengthy.  Due to the nature of the work users will be doing on this page, it is essential that they do not lose their work.  Saving often is a must, but can create a bad user experience if users must keep scrolling back to where they were after each save/submit.  Here’s how I solved that problem by navigating users back to the row they last edited after submitting the page.

  • Create a hidden page item on your page that will store the row number (in my example, P39_LAST_ROW_UPDATED).
  • In the HTML Header section of your page, add the following function enclosed in script tags:
function setLastRowUpdated(p_this) {

  var p_rownum = Number($x(p_this).id.substr(4));

  $s("P39_LAST_ROW_UPDATED", p_rownum);

}
  • For each column in the tabular for that is editable, add the following code in the Element Attributes:
onchange="javascript:setLastRowUpdated(this);"
  • Create a Dynamic Action that fires on page load that executes the following javascript (substitute f02 with the jquery selector of the field you wish focus to go to)
var f02 = document.getElementsByName("f02");

$x(f02[$x("P39_LAST_ROW_UPDATED").value - 1].focus();
  • Lastly, this setup assumes you will be calling the page containing the tabular form from a link from another page.  In the calling page, you will want to make sure P39_LAST_ROW_UPDATED gets set to 1 in your link or button.

You can access the demo application here (credentials guest/demo): Tabular Form Return Demo