Sunday, September 21, 2014

Application Express - using the sort arrows in a tabular form - Updated for Apex 4.x

In a previous post (already a few years back) I demonstrated how to get the Apex sort arrows as seen in Apex builder in your own applications.



This was done in Apex 3.x, and in the meanwhile someone pointed out that in Apex 4.0 this was not working anymore. Not having the time to go into that in detail, I left it at that. Recently, someone else reported errors with this approach, again for the Apex 4.x versions. So I sat down and figured out the new way to do this for Apex 4.x

Again, we will be using a simple Tabular Form:



First step: create the arrows

This step is different from what you did in Apex 3.x because there is an additional DIV section and an extra TABLE around Tabular Forms now. The surrouding section carries the report region as an ID, the Tabular Form itself has no ID to work with. In order to get an ID, we are going to modify the template on which the Tabular Form is based.
In this case, I modify the template directly, you should always choose to create a new template (copy it from this one) and assign that template to the region... Otherwise, all other reports using this template will get sort-arrows and that might not be what you wanted.

In the Apex Builder, go to "Shared Components - User Interface / Templates - Report / Standard". Normally, the Tabular Forms use this template. If you use another template modify that one (or rather: copy that one for modifying). In the "Before Rows" section, modify the last line (modify the class and add an ID):
  • from <td><table cellpadding="0" border="0" cellspacing="0" summary="" class="report-standard">
  • to <td><table cellpadding="0" border="0" cellspacing="0" summary="" class="report-standard-sort" ID="report_#REGION_ID#_sortable">

In the "After Rows" section, add this block right after the </table> tag (and before any other code already there):

<script src="/i/libraries/apex/minified/builder.min.js" type="text/javascript"></script>
<script type="text/javascript">
  var g_rpreview_global = 'report_#REGION_ID#_sortable';
  var g_#REGION_ID#_sortable;
  function f_#REGION_ID#_sortable(){
    g_#REGION_ID#_sortable = new apex.tabular.sort(g_rpreview_global);
    g_#REGION_ID#_sortable.row.after_move = function(){rpreview()};
  }
  addLoadEvent(f_#REGION_ID#_sortable);
</script>

Do this for all templates that you will be using for sortable reports. When switching themes, you will need to do this again!
Note the extra JS library included: the builder.min.js contains the necessary Javascript do implement the sorting.

After this, the form has the up/down arrows next to every line.



Second step: hide the order column and make it orderable

To enable ordering and make the order column hidden, just take these steps:
  • Edit the form properties and set the "order" item property "show" unchecked
  • Edit the column properties for "order" and set "Element Attributes" to class="orderby"

Now we have a simple form which we can order using the arrows.


Third step: adjusting the style

The last step we need to take is to make the background and header to look like the template we use. Regrettably, I found no really easy (configurable) way to do this. So, we'll do this the hard way.

First of all, you'll have to get the style you're using in the application. The stylesheet is referenced in your application and viewable by just showing the source of your page in your browser. In this example I ran the application, selected "show source" after right-clicking and searched for the stylesheet. This shouldn't be too hard to find (was on line 34 for me, first mention of themes).

When you look at this stylesheet (by either downloading it from the application server, or looking it up in an APEX software download), you should be able to find the section of interest by searching for "report-standard th.header". The section you'll find and the section for "report-standard th.data" are to be used.
Depending on the template you chose, the numbers and settings will be somewhat different. These sections will be used to create .report-standard-sort qualifiers (that is why we modified the class in step 1).

We must set the background color for the header, which is not directly mentioned in the section we just found. There is an url pointing to the background image, but that is relative to the stylesheet itself. Modify it to reflect the theme (theme_2 for me) and make the path relative to the apex page itself. Place the style tags around this block. We now have (after reformatting):

<style>
.report-standard-sort th {color: #ffffff; background-color: #cccccc; padding: 2px 10px; border-bottom: 1px solid #cccccc; background-image: url(../../i/themes/theme_2/images/report_bg.gif); background-repeat: repeat-x;}
.report-standard-sort td { background-color: #f0f0f0; padding: 4px 10px; border-bottom: 1px solid #cccccc;}
</style>


By placing this as a style tag in the HTML header of the page, our tabular form is now ready to go.



Keep in mind:
  • When using a new template, you should also (copy and) modify that template for the region
  • When using a new theme, all templates should be (copied and) modified again
  • When creating a new Tabular Form, change the report region template to the sorting template and copy the HTML header section for the style

Thursday, January 16, 2014

Oracle DataGuard 12: Standby database not starting after failover

I created a 12c DataGuard setup on Windows (2012 Server) using 3 machines:

  • Primary database server (DB1 on server1)
  • Standby database server (DB2 on server2)
  • separate Observer machine


I created the setup "manually" (scripted, not using EM) and everything worked fine (using FAST_START FAILOVER). Everything, except that after a failover from server2 (initially the standby) to server1 (initially the primary), the database on server2 would not start automatically.

Failing over from server1 to server2 works fine:

  • Shutdown server1 (disconnect virtual power)
  • Observer notices failure and starts DB2 as primary
  • Startup server1
  • Observer sees server1 online, re-instates DB1 and starts DB1 as standby

And after re-instatement, the DataGuard configuration works fine again.

When I failover from server2 to server1, DB2 will not restart and not be re-instated after the server comes online again. After such a failover, I had to mount the database manually and then the Observer took over and re-instated the database.

After much searching, I found that in the Windows registry, one key was missing. In the registry (HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraDB12Home1), there was no entry for "ORACLE_SID". I created the entry "ORACLE_SID=DB2" and set "ORA_DB2_AUTOSTART=TRUE". This was set to TRUE initially, but was set to FALSE on restart of the machine (probably because ORACLE_SID was not set).

I think that the "oradim" command for creating the service does not work properly. It does not create the ORACLE_SID key in the registry. This stops the database from autostarting (in mount mode) and DataGuard (the Observer) was not able to re-instate the database.  This is already automatically done on the (initial) primary server, probably by DBCA, so that database works fine after a restart.

So, as a quick solution, you should create the ORACLE_SID key in the Windows registry for the standby server in order to start the database automatically. I hope this helps anyone facing this problem!