Friday, February 24, 2017

Overriding the Default Properties of Inline Dialogs

When using inline modal, you can display them using the openModal JavaScript function.

That function is wrapping the jQuery UI Dialog Open method.
/* **********************************************
     From Theme42.js
********************************************** */
window.openModal = function(pDialogId, pDialogTriggerId, pSetFocusId, pClear) {
        $("#" + pDialogId).dialog("open")
    }

What we can do to override the default properties is to set them either on page or right before calling the Open method.

Let's say we would like to have a smaller dialog (e.g. height of 200px)


Option 1

On page load
$('#INLINE_REGION_STATIC_ID').dialog('option', 'height', 200);

Then you can use
openModal('INLINE_REGION_STATIC_ID');
or
$('#INLINE_REGION_STATIC_ID').dialog('open');

Option 2

When openning the Dialog:
$('#INLINE_REGION_STATIC_ID').dialog('option', 'height', 200).dialog('open')

For more information, you can have a look at the Dialog Widget documentation

Friday, February 3, 2017

Using Font Apex in Apex 5.0


Apex 5.1 introduced Font Apex, a new icon library designed to complement Universal Theme and to replace Font Awesome. The same "fa" prefix for the icons was kept so that it's easier to move from Font Awesome to this entirely new icon library.

Font APEX comes with a number of customizations built-in, enabling us to easily control the size, animation, rotation, and even add modifiers on top of icons. You can try customizing your icons using the Icon Builder in the Universal Theme sample application.

What if you are still on Apex 5.0 and would like to use it?

Don't worry you are able to do so.
Here's how you can do it.

First let's get the Font Apex library files.
You can get them from the Apex 5.1 installation file under the "images\libraries\font-apex" folder (or from here)
Then you will need to import these files in your application (let's do it using the Static Application Files for the sake of simplicity, but you could also import them in the Static Workspace Files or copy them on your web server).

Note: zipping the font-apex folder will enable us to upload only that zipped file instead of every single file from the folder using the zip file will also keep the folder structure.




You will end up with the following files:



Then, let's remove the Font Awesome and include the Font Apex.



Notes:
Step 4 removes the Font Awesome reference.
Step 5 uses the Font Apex CSS file reference from above step. Notice that the .min was replaced by #MIN#
From help text:
If you provide a minified version of your file you can use the substitution string #MIN# to include .min or #MIN_DIRECTORY# to include minified/ in your file URL for a regular page view and an empty string if the page is viewed in debug mode. 

At this point, if you try to run your application, you should be able to see most of the Font Apex icons.

There are some tweaks we still need to do so that everything is displayed nicely.
First, there is still a class that uses the "font-family: font-awesome;", which is used by the expand/collapse navigation menu button.

The other thing we need to change is the height of the icons.
Font Awesome uses 14x14 icons whereas Font Apex uses 16x16 icons. Some icons might not be displayed correctly. The expand/collapse navigation menu button is also one of those.

Here's the CSS that is required to fix these.

.t-Icon[class*=' fa-'],.t-Icon[class^=fa-]{
    font-family: font-apex!important;
    font-size: initial;
}

.t-TreeNav .a-TreeView-node--topLevel>.a-TreeView-content .fa{
    font-size: initial;
}

Enjoy Font Apex in your Apex 5.0 applications!

Edit 1: The Custom Prefix Class attribute needs to be set to "fa"

Friday, December 2, 2016

Overlay Side Navigation Menu

In the last couple of weeks, I've been playing with the side navigation menu. By default, the side navigation menu "pushes" the page content back and forth as it expands and collapses.
Which looks just like this:


By overriding the Universal Theme's CSS related to the side navigation menu, I was able to make the menu display as an overlay.

I've also tested the solution on the Apex 5.1 EA2 and noticed that the html markup of the menu changed quite a bit in order to handle RTL applications.

You can retrieve both CSS here:
https://github.com/maxime-tremblay/apex-css-overlay-sidemenu

Then will need to include the corresponding CSS file either in the theme roller's custom CSS attribute or as an external file in your application's CSS files.

Additionally, by default, the side navigation menu remembers the previous state it was in. So if on a page you expand the menu and refresh it, the menu will be rendered as expanded.

What we can do to prevent that from happening is have some JavaScript code execute on page load that is going to collapse the menu if it's expanded.
$('.t-PageBody.js-navExpanded #t_Button_navControl').click();

That code can be executed as a dynamic action on page 0 or in a global JavaScript file so that it's going to affect all pages in the application.

You will get something that looks like this:


If you would like to have the menu be fullscreen you can simply uncomment the fullscreen part at the end of the CSS file.

You can have a look at my Demo Application

Thursday, November 24, 2016

Right Side Column Page and Validation Error Message Region

If you ever used the "Right Side Column" page template, you might have noticed that the validation error message region is displayed under the right side region's expand/collapse trigger button.


As you can see above, the expand/collapse trigger button is on top of the close notification "X" button.

There are two ways to go in order to fix that, both using CSS only.

The first method is to add some right margin to the notification region.

.js-rightExpanded .t-Body-content .t-Body-alert,
.js-rightCollapsed .t-Body-content .t-Body-alert {
    margin-right: 40px; /* Width of the right side region's trigger button */
}

It will then look like this:

The second method is to reposition the notification region on top of the right side region's trigger button.

.js-rightExpanded .t-Body-content .t-Body-alert,
.js-rightCollapsed .t-Body-content .t-Body-alert {
    position: relative; /* Need to position the div for the z-index to work */
    z-index: 500; /* z-index of right side column is 490 */
}

It will then look like this:

Interactive Report Alternating Rows


For classic reports there is a region attribute template option to have the rows have alternating row color.


That template option is not part of the interactive report template options.


We can achieve the same effect in an interactive using once again some CSS.

.customAlternatingRow .a-IRR-table tr:nth-child(odd) td {
    background-color: yellow;
}

.customAlternatingRow .a-IRR-table tr:nth-child(even) td {
    background-color: yellowgreen;
}

The only thing left to do is to add the "customAlternatingRow" class to your region (under Appearance, CSS Classes) or at the page level.

It will then look like this:

The classic report is using   #fcfcfc (very light gray) for the odd rows and nothing for the even rows.

.customAlternatingRow .a-IRR-table tr:nth-child(odd) td {
    background-color: #fcfcfc;
}

Which would look like this:


If you would like to also change the highlighted/hovered row color, you can use the following CSS:

.customRowHighlight .a-IRR-table tr:hover td {
    background-color: #f9f9f9;
}

Note:
If you would like this to be applied on all interactive reports in your application, simply remove the ".customAlternatingRow" and/or ".customRowHighlight" from the CSS.

Browser Support of the :nth-child() Selector (from w3schools)

Selector Chrome IE Firefox Safari Opera
:nth-child() 4.0 9.0 3.5 3.2 9.6


You can have a look at my Demo Application


Monday, November 21, 2016

Auto Publish All Translations When Importing an Application

When working with translated application, once everything is done in the source application, you need to seed all the translations, then translate what needs to be and then publish all the translations.
When migrating the application, you will have two choices.

  1. Export the source application and export all mapped translated applications. Then import all the application in the other environment
  2. Export the source application only including the translations (export preferences attribute). Then import the application in the other environment. Then publish all translations.

I usually go with the second method.
If the person that migrates the application knows their way around Apex, it's not that big of a deal.
But when it's not the developer that migrates the applications (e.g. when it's the DBAs), it can be more complicated to explain them the complete procedure.
Furthermore, it could happen that the person who imports the application simply forgets to publish the translations afterwards.

I thought it would be great if the option to include translations when exporting the application also published them when importing the application, but unfortunately, it's not the case.

One thing you can do is to use the apex_lang.publish_application API
http://docs.oracle.com/cd/E59726_01/doc.50/e39149/apex_lang.htm#CHDCBEDE

You can use it just like in the API's documentation example as a script you would need to run after the import process.

But it would be great if that was executed as part of the install process.

Supporting Objects to the rescue!!

Supporting Objects


What we need to do is to create an Installation Script from scratch using the Editor that simply calls the API.







Use below code:

declare
    -- if using apex 5.0+, you can use 'apex_application_install.get_application_id' to retrieve the application id
    -- otherwise, you need to hardcode the application id
    l_app_id number := apex_application_install.get_application_id;
begin
    for i in (select primary_application_id, translated_app_language
                from apex_application_trans_map
               where primary_application_id = l_app_id)
    loop
        apex_lang.publish_application(i.primary_application_id, i.translated_app_language);
    end loop;
end;
/

Then, when you'll export your application, make sure you include the supporting objects and that you export the translations.


Note: Depending on how you will import the application, the "Export Supporting Object Definitions" attribute has to be set to either "Yes" or "Yes and Install on Import Automatically".

Looking at the attribute's help:
  • Yes Includes supporting object definitions in the application export. Does not automatically load supporting objects when invoked from a command line.
  • Yes and Install on Import Automatically Includes supporting object definitions and a call to install supporting objects in the application export. This option is valid only for command line installs. When application imports from the command line, it automatically installs or upgrades the supporting objects.
So, if you import the application from Apex either will work, but if you import from a command line, you should set the attribute to "Yes and Install on Import Automatically".

When you'll import the application, simply choose to install the supporting objects.




Voila, your application's translations will be automatically published as part of the import process.

EDIT: Added a note regarding the "Export Supporting Object Definitions" attribute.

Monday, November 14, 2016

Required Asterisk Left of Item Label

If you ever had a customer asked you to move the required asterisk of the item's label before the item itself, you probably had to copy the existing template and move the span that holds the asterisk before the item itself then you had to go through all you labels to change the template.

Lately, I've been testing my demo application in the EA of Apex 5.1 and looking at the code and how things changed from 5.0 to 5.1.

Among all the changes, I noticed that the Apex team started to use the CSS3 order property.
Definition
The order property specifies the order of a flexible item relative to the rest of the flexible items inside the same container.
Note: If the element is not a flexible item, the order property has no effect.

Basically, this property can reorder items within the same container granted that the container is using the flex property.

To move the asterisk span using only CSS, we can use the following code:
.t-Form-fieldContainer .t-Form-labelContainer {
  display: flex; /* Make sure the container is using flex */
  justify-content: flex-end; /* Keep items right aligned */
}

.t-Form--labelsAbove .t-Form-fieldContainer .t-Form-labelContainer,
.t-Form--leftLabels .t-Form-fieldContainer .t-Form-labelContainer,
.t-Form-fieldContainer.t-Form-fieldContainer--stacked .t-Form-labelContainer {
  justify-content: flex-start; /* Keep items left aligned */
}

.t-Form-fieldContainer .t-Form-labelContainer .t-Form-required{
  order: 1; /* Asterisk as first element */
}

.t-Form-fieldContainer .t-Form-labelContainer .t-Form-label{
  order: 2; /* Label as second element */
}

You can have a look at my Demo Application

EDIT1: Fix an issue with above labels.

EDIT2: Fix an issue with "Blank with Attributes" region template.

EDIT3: Apex 5.1 now handles the required asterisk using CSS only and the position now depends on the label's alignment.
Right aligned: asterisk before
Left aligned: asterisk after