The modal dialogs are a very nice feature, easy to use and well integrated in the Apex framework. One thing that annoys me is the vertical sizing of the dialog window.
Normally I will create a page as a Modal dialog. When running it I notice that the window is way too high or not high enough. I go back to the builder and enter a number of pixels for the height and look what the result is. I repeat this process a few times until I am satisfied.

When the page is changed this may  change the height of the page, so… :-(.
This is typically one of these boring jobs I like to automate. So I examined the structure of the Apex modal dialog.
One thing that is counter intuitive is that the header of the modal dialog is part of the calling page. Only the red part is generated from the modal dialog page.

The height of the modal window is defined in the calling page. This is the reason why you have to refresh the calling page when you change the height of the modal dialog.

Inside the red square the height is determined by three div elements: dialog header, dialog body and dialog footer.
The JavaScript code below determines the total height of the dialog and sets the height of the determining element on the calling page to this value.

function resize_dialog()
{
  var header  = $('.t-Dialog-header');
  var height  = parseInt($(header).height());  
    
  var body    = $('.t-Dialog-body');
  var padding = parseInt($(body).css('padding-top')) + parseInt($(body).css('padding-bottom'));
  height += padding;
    
  var container = $(body).children().first();
  height   += parseInt($(container).height());  
    
  var footer    = $('.t-Dialog-footer');
  height   += parseInt($(footer).height());  
  console.log('total height = '+ height );

  parent_container = window.parent.$('.ui-dialog-content');
  $(parent_container).height(height);
}

This code can be called in the On page load section of the dialog page.

It is also possible to call the function in a Dynamic Action that changes the height of the dialog content. Two examples of this behavior can be seen in the example page here. You can change the number of rows or number of items and the dialog is resized automatically.

Happy Apexing!

Source Article from http://dickdral.blogspot.com/2016/12/automatic-resizing-of-modal-dialogs.html

Some years ago I attended a presentation of John Scott in which he demonstrated the use of substitution for producing a string from a number of variables.

Up to that moment I used concatenation for generating strings from variables:

l_html &nbsp;:= '<input id="'||l_id||'" onclick="test('''||l_value||''')" type="text" />';  

Even a relative simple expression like this is hard to read. Moreover it is not easy to see whether the quotes are placed at the right position and quantity.

So John’s solution to this is to start with a string with delimited placeholders and replacing the placeholders with their value one by one. So the code gets:

l_html := q'!<input id="#ID#" onclick="test('#VALUE#')" type="text" />!';  
l_html := replace(l_html,'#ID#',l_id);  
l_html := replace(l_html,'#VALUE#',l_value);  

This code is much more readable and the html can be checked easily.
I have been using this design pattern a lot since then.

But the typing annoys me. Typically something to automate! So this morning, when I was getting ready to type a list of replace statements for the 1001st time I decided to create a small tool to generate these lines.

Paste the string with placeholders into the form and change the other parameters to your preferences. Press generate and you can copy the resulting code into your PL/SQL.
The generation presumes that the names of the variables containing the values to be replaced are equal to the placeholder names. Doing this also improves the readability of the code.

The utility can be used online at http://www.speech2form.com/ords/f?p=141:600

Happy apexing!

Source Article from http://dickdral.blogspot.com/2016/11/stop-typing-and-generate-you.html

Today I was asked to implement change detection in an Apex page. This page used a custom PL/SQL process instead of the standard Apex transaction processing. In this setup users can overwrite each others transaction. This can be fixed by calculating a checksum over the queried items and comparing that to a checksum on the same items before applying the changes. If the checksums are equal, no one else has changed these items, otherwise the current user should be warned.

I decided to create a checksum item P200_CHECKSUM at the top of the page. The page contained a dynamic form that was generated in a PL/SQL region. In order to preserve performance I added the checksum calculation to the PL/SQL region. The resulting checksum was written to :P200_CHECKSUM in session state. With PL/SQL code at the beginning of the save process the checksum was checked.

But it did not work! The checksum was calculated and I could see the value with Show session. But debugging showed that the checksum used in the save process was empty. It took me a while to figure out what was happening.

It was all about rendering order:
– at first the P200_CHECKSUM item was rendered with value null
– then the checksum was calculated and put into session state

At submit the value of P200_CHECKSUM in session state was updated with the value from the page (which was null).
This is why the value of P200_CHECKSUM was empty in the save process.

Once I understood this the solution was easy: just put the P200_CHECKSUM item in a region that is rendered after the calculation.

An alternative solution is to use a PL/SQL Dynamic Action with the P200_CHECKSUM in the Page items to return. The PL/SQL code can be null;. The DA fills the value of the page item P200_CHECKSUM with the value in session state. Drawbacks of this solution are extra network traffic and a slight delay in the setting of the value.

Experiment

The above led me to set up an experiment on session state and items rendered. The session state is set at several process points, with items showing the result on the page. Session state is set by either using bind variable notation or with apex_util.set_session_state.
The image below comprises the result after the page is run.

Several conclusions can be drawn:
– there is no difference between using bind variables and set_session_state
– from the normal Apex process points only the value set After Region is not rendered
– as expected from my experience the item set in the PL/SQL procedure is only rendered after the procedure has run
– the session state set in a display item is also available in previous items. The debug listing shows that the query for populating the display item is executed before the regions.

Happy apexing!

Source Article from http://dickdral.blogspot.com/2016/11/wrestling-with-session-state.html

Sometimes you want to show data without the user being able to change it. The easiest way in Apex to use reports and read only items. There are use cases however for which this is not good enough.
For example when you want to change from read only to editable item dynamically or vv. Or if you want to disable items in a tabular form selectively.
In these cases it is necessary to generate the editable items and to disable them afterwards. In this blogpost you can read how you can do this without compromising the functioning of your page. A special chapter describes the way to selectively disable items in a tabular form.

How to disable items correctly with JavaScript

So disabled is dangerous to use and readonly is limited in item types.

So the correct way to disable an item is applying the class apex_disabled and the attribute tabindex=”-1″. It takes care that the item cannot be reached by the user either by mouse or by keyboard.

function disable_item ( itemName )  
{ 
   $('#'+itemName).addClass('apex_disabled').attr('tabindex','-1');    
}
function enable_item ( itemName )  
{ 
   $('#'+itemName).removeClass('apex_disabled').removeAttr('tabindex');    
}

How to selectively disable items in a tabular form

In the after refresh Dynamic Action JavaScript is used to loop along all the rows and perform the disabling of the items. You can use the code below:

function disable_tabform_items ( tabSelector )  
{ 
    // loop along all the rows with a DISABLE_ITEMS cell
    $(tabSelector).find('[data-item="DISABLE_ITEMS"]').each( 
      function() 
    {
      // make array of item names to be disabled
      list = $(this).val().split(':');
      if ( list.length > 0 ) 
      { 
        // identify the row
        var tr = $(this).closest('tr');

        // disable all the item in the list  
        for ( i=0 ; i < list.length ; i++ ) 
        {
          $(tr).find('[headers="'+list[i]+'"]')
               .find('input,textarea,select,button.ui-datepicker-trigger')
               .addClass('apex_disabled')
               .attr('tabindex','-1');
        }       
      }
    });
}

An example of this you can find in action here.
There you can also download the demo application in order to see how it works form the inside.

Happy apexing!

Source Article from http://dickdral.blogspot.com/2016/11/disabling-apex-items-right-way.html

function reportToColumns ( tabSelector, numCols )  
{ var numRows  = 0;  
  var curtable = null;
  // calculate the number of rows per column
  var table = $(tabSelector).addClass('reportColumn'); 
  var rowsPerCol = Math.ceil( ( $(table).find(' tr').length-1 )/numCols);  
  var baseName = 'reportColumn';   
  
  // create table template for columns 
  var template = $(table).clone();
  $(template).find('tr').has('td').remove();
  

  for ( i = 2; i 

The parameter tabSelector should contain the JQuery selector of the table containing the report.
For Universal Theme this is:

'#report_report static id table.t-Report-report'

in which the report static id should be replaced by the static ID defined for your report region. Actually this code can be used for any HTML table. You can find the table selector using FireBug or Chrome Inspector.
I personally like to work with Firebug because of its multiline code pane. It is very easy to test JQuery selectors because the code pane remains unaltered while you can see and scroll the console output. I also use this to develop and test my JavaScript.

Add the class below to your CSS definitions. It makes sure that the columns are displayed next to each other with a distance of 30 px between them.

.reportColumn {
    display: block;
    float: left;
    margin-right: 30px;
    position: relative;
}

You can see it in action here.

Happy Apexing

Source Article from http://dickdral.blogspot.com/2016/11/splitting-reports-into-columns-revisited.html

You are limited by the columns in the responsive layout.

It is possible to position the items much closer and have much control over their position. For this you need to call JavaScript function with the names of the two columns as parameter:

position_after('P3000_FROM,'P3000_TO');

You can download the JavaScript code here.

The JavaScript removes the col-x classes from the input container of the first item and the label and input container of the second item. This class determines the fixed width of the container. Without this class the container’s width is determined by the content, so it fits tightly around the input or the label.
After removing the classes the JavaScript positions the label and input containers of the second item behind the input container of the first item.

You can decrease the width of the items and they still stay together.


And there is control over the spacing applying left and right margins no the second label container.

#P3000_TO_LABEL {
   margin-left: 20px;
   margin-right: 20px;
}

In the result you see a larger spacing around the label:

The downside of this approach is that the responsive behavior is not optimal. Developing just for desktop this is no problem.
But if you really want a perfect responsiveness on all screen sizes you should stick to the column model of UT.

Happy Apexing

Source Article from http://dickdral.blogspot.com/2016/09/positioning-items-next-to-each-other.html

As many people I am used to use the link images that Apex proposes when creating Forms with reports. And I end up with a bit grey images like:

Well, we are all used to it, aren’t we?
Now would not it be much nicer if it would look like this:

This fits much better into the Universal Theme.

It is possible and in fact very easy. If you look at the properties of the link column in the report you see:

You just change the Link Text to   and define the class report-icon:

.report-icon { font-size: 1.6em; }

And you are done.
NB You can by the way use any font-awesome icon you want by changing the fa-xxx class. 

And if you want to use these icons in all your reports, you can define them once as a subsitution variable in the application properties:

 … and use them in all your reports:

Happy Apexing

Source Article from http://dickdral.blogspot.com/2016/09/using-nice-icons-for-links.html

While developing the dashboard for the Apex Dashboard Competition I found the challenge of presenting large numbers in a readable form. If you want to display the population of countries in a report there is China and India with more than 1 billion inhabitants and Tuvalu does not reach 10,000.
With a straight forward report it would look like the left image. The application apply of thousands separator improves the readability, but there is still too much detail in the numbers to easily get the meaning. The right image, where the numbers are formatted using size prefixes is much more readable.

Source Article from http://dickdral.blogspot.com/2016/09/displaying-large-numbers-in-human_11.html

While developing the dashboard for the Apex Dashboard Competition I found the challenge of presenting large numbers in a readable form. If you want to display the population of countries in a report there is China and India with more than 1 billion inhabitants and Tuvalu does not reach 10,000.
With a straight forward report it would look like the left image. The application apply of thousands separator improves the readability, but there is still too much detail in the numbers to easily get the meaning. The right image, where the numbers are formatted using size prefixes is much more readable.


You can see this in a useful example in the Apex World Dashboard. Select a country and look at the ranking table.

In Oracle Apex you can implement such formatting in your query, using a PL/SQL function. This solution has several disadadvantages:

  • Column header sorting is impossible because the actual numbers are replace by a character representation
  • Calling a PL/SQL function in a query can degrade performance
  • the readability of your query gets less

The solution is to apply the formatting using JavaScript. This way the query is not affected and the formatting is done after the sorting.
The formatting is implemented in a After Refresh DA on the report in question:

format_numbers_in_table('#report_tablespaces .t-Report-report');

The function formats all the cells with numeric content.
The parameter to the function should be the selector to the HTML table containing the data to be formatted. In this case the UT Standard Region and Standard Report are used with a static ID tablespaces.

If the report contains a large number of columns or some columns should not be formatted the columns to be formatted can be limited by passing an array of column names as the second parameter:

format_numbers_in_table('#report_tablespaces .t-Report-report',['LAND_SURFACE','POPULATION']);

Only the mentioned columns will be formatted.

Store the following JavaScript functions on the page or seperately in a file. You can also download the code here:

/******************************************************
 * Display numbers readable
 *
 **********************/
function display_number(number)
{
  var sizes = [ {"base":1000,"symbol":"K"}
               ,{"base":1000000,"symbol":"M"}
               ,{"base":1000000000,"symbol":"G"}
               ,{"base":1000000000000,"symbol":"T"}
              ];
  
  var display = number.toString();

  if ( !isNaN(number) ) 
  {
    for ( i in sizes )
    {
      if ( number > sizes[i].base ) 
      {
        num1 = number / sizes[i].base;
        if ( num1  0 && col.innerHTML != ' ' )
      { 
        // if column list has content only format columns for this list
        var header = col.headers;          
        if ( column_list == null || column_list.indexOf(header) >= 0 )
        {
            col.innerHTML = display_number(col.innerHTML);        
        }
      }
       
    }  
  }
}

Happy Apexing

Source Article from http://dickdral.blogspot.com/2016/09/displaying-large-numbers-in-human.html

While looking for a suitable icon for an organization item on the login page I examined the collection of Apex icons. The big difference with the Font Awesome icons is that the Apex icons are less heavy. Therefore they are more suitable to enlarge where Font Awesome icons tend to appear bulky over a certain font size.
I looked for the Workspace Icon ( a database cylinder ), but I could not find it. While inspection showed that it was part of the core.min.css. After an hour of searching I looked at the source files in Firebug. There are two versions of this css file, one in the apex_ui folder and one in the app_ui folder.
I have created a page where both collections of icons are listed:

Press the button above to visit the page.
You can toggle the list between the standard icons or all the icons.

The icons can be used in HTML by adding the classes a-Icon and the class of the specific icon (the text behind the icon on the page):

<span class=”a-Icon icon-find”></span>

The Apex Builder icons can be used by referencing the file apex_icons.css. Put this file on your server or in the static files and reference it on the page with the icons.

Have fun using the icons,
Dick Dral

Source Article from http://dickdral.blogspot.com/2016/06/hidden-treasure-apex-5-icons.html