Friday, June 7, 2019

Username Display Fix

This thing is very simple, but it got me confused...so I hope it will help someone.

I was building a small APEX app (in APEX 19.1.*) with a custom authentication scheme (custom plugin) and when I've logged in to the app I've noticed that the username is in lowercase. So the first thing that got to my mind was that there's some problem with my authentication plugin. But that wasn't it.

I'm not 100% sure but I think from APEX 18.1 there's a change how navigation bar looks like. By default when you create an app you'll get username with a nice icon and drop down with Sign Out link. Before, at least in APEX 5.1, by default, there was only a Log Out link. Maybe that's the reason why I didn't notice this thing before.


So, lowercase is actually forced by CSS. So if you want to display your username as it came out from authentication scheme (in my case uppercase) you only need to remove Shared Components > Navigation Bar List > &APP_USER. > List Item CSS Classes property that's by default set to has-username



Tested in APEX 19.1.0.00.15

Enjoy!

Thursday, May 9, 2019

Generate APEX URL in JavaScript

When developers want to generate APEX URL from a JavaScript the thing that most of them will do is to concatenate URL string like this:

But there's one (unfortunately) undocumented feature that you can use to make it easier. It's possible to do it by using apex.util.makeApplicationUrl function that excepts a JavaScript object as the only parameter. In that object, you can define all that is needed to generate an APEX URL.

Here is an example:

Note: the function will not generate the checksum for pages or items with session state protection turned on.

Enjoy!

Tested in APEX 19.1.0.00.15

Monday, December 10, 2018

Don't duplicate your radio items 🧐

A few days ago I've managed to produce a very weird bug that was hard to figure out. Thankfully, it was only in a demo application. I hope this blog post will help somebody to fix it a bit faster.

The problem...

...was that I couldn't click on the second radio group item with label "Accounting".

How I did it

I've created two radio group items. The first one that I've created was P58_RADIO (with label "Radio Group") and the second one was a duplicate of the first one so it was automatically named P58_RADIO_1. After that, I've moved that item before P58_RADIO and suddenly I couldn't click on "Accounting" label of the second radio group item (as shown above).

The problem is how APEX internal engine renders radio group items. This is the code for the radio item named P58_RADIO:


If you take a closer look at input and label HTML tags of radio buttons you can see how APEX is generating the ID and FOR HTML attributes: item name + underscore + sequence (starting from 1). In my case, "Accounting" label had FOR attribute that was equal to the ID of a duplicated item (P58_RADIO_1) and that didn't allow me to click on it.

How to fix it

I don't expect from APEX team to change the way how radio items are rendered so just be careful how you're naming your page items. 

CSS fix for Null Display Value

Also, in APEX 18.2.0.00.12 (and probably in some lower version), there's a UI bug with horizontal radio group items where property "Display Null Value" is turned on. The display value for null values is displayed in a row before other radio group item values. To fix it, use the following CSS:


Enjoy!

Tested in APEX 18.2.0.00.12.

Friday, September 14, 2018

How to set IG default values for email fields when downloading report

Few days ago I've got interesting APEX question (I don't mind that the question was sent by mail, but there's Oracle Community Forum where you can get quicker answer and more people will benefit from it).

..and the question is: how to define default values for fields that are shown when you want to download Interactive Grid report and send it by the e-mail.


Maybe I'm wrong but I think there's no native way to do this so I found a workaround.
You can do this for a specific region/page or globally by using global page (page 0).

First of all you need to create on click dynamic action triggered on checkbox item "Send as Email":


The Event Scope attribute must be set to Dynamic and if you want to restrict this dynamic action to the specific region you should define Static Container (jQuery Selector) property with static ID of IG region (for example #emp, if static ID of a region is emp).

You also need to create true dynamic action of a type Execute JavaScript Code where you can define items and values that you want to set:



Demo is available here.

Tested in APEX 18.1.0.00.45.

Enjoy!

Friday, August 17, 2018

APEX 18.1: Fix Interactive Grid JS error in translated apps

Recently one of our clients upgraded APEX from 5.1 to 18.1 and all Interactive Grid regions/pages were instantly "broken". There was some strange JS error ("...to few arguments") in the console window.

After some investigation I found out the cause of the error. It's actually reported as a known issue (28202781 - INTERACTIVE GRID IN TRANSLATED APP GIVES ERROR ON UPGRADE). Apparently the text string APEX.IG.SUMMARY was changed in APEX 18.1 to have fewer parameters and if you have translated application it will raise a JS error at runtime. I don't know why APEX raises error in this case and I hope that this will be fixed in some next release, but for now here's the way how you can fix this.

Of course, you can go to APEX builder > Shared Components > Text Messages and translate it there with the new text message that will have exactly two parameters (if you have less than two you'll again get JS error). Original text is Interactive Grid. Report: %0, View: %1.

You can also do it with PL/SQL script:
BEGIN
  FOR i IN (SELECT workspace_id
              FROM apex_workspaces
             WHERE workspace = :WORKSPACE_NAME)
  LOOP          
    apex_util.set_security_group_id(i.workspace_id);
  END LOOP; 
  
  FOR i IN (SELECT *
              FROM apex_application_translations
             WHERE application_id = :APP_ID
               AND translatable_message = 'APEX.IG.SUMMARY')
  LOOP
    apex_lang.update_message(
          p_id           => i.translation_entry_id,
          p_message_text => 'Interactive Grid. Report: %0, View: %1');
    COMMIT;
    EXIT;
  END LOOP;
END;
/

Tested with APEX 18.1.0.00.45

Enjoy!

Wednesday, June 27, 2018

APEX 18.1: No need for configuration tables any more

There's probably no application that doesn't need some kind of configuration table for storing different data across different environments (development/test/production) - like URL to the report server, configuration parameters and stuff like that.

Before APEX 18.1 in most cases I would create some simple key-value configuration table, set procedure and get function...repeating same task over and over again.

From APEX 18.1 you don't have to do that anymore. There's new feature called Application Settings.

There are two ways to manage Application Settings. One is from the Application Builder (Shared Components):


You can define several properties there, but the one I like the most is On Upgrade Keep Value. If set to Yes it will keep the setting value upon application upgrade. That means that you can export your application from the development environment and import it to the other environments without any worries that parameter values will be overridden.

There's also API to control those parameters from PL/SQL. There's new package apex_app_setting with set_value procedure and get_value function. For more info see documentation.

Enjoy!

Friday, June 8, 2018

APEX 18.1: Generate URL checksum outside APEX session

As a follow up to my previous blog post about APEX sessions, there's one more thing that you can do now (in APEX 18.1) by using apex_session package - generate checksum for URLs created outside APEX session - for example in some email notifications created in a DB job.

First of all you need to enable Deep Linking (go to the Application Properties > Security > Session Management and set Deep Linking to Enabled). You can learn more about deep linking in the documentation.

Also, you have to enable Session State Protection for the item that you want to set in URL (in my case P2_DEPTNO):


Before generating URL you have to create session:
begin
  apex_session.create_session(105,1,'MGORICKI');
end;
/
As I said in my previous blog post, to use any of the procedures from the apex_session package you have to run them as application parsing schema, one of schemas assigned to the workspace or one of the users with APEX_ADMINISTRATOR_ROLE role.

After that you should be able to create URL with the checksum by calling apex_page.get_url function:
MGORICKI@db12c.local> begin
  2    dbms_output.put_line(
  3      apex_page.get_url (
  4      p_application => 105,
  5      p_page        => 2,
  6      p_items       => 'P2_DEPTNO',
  7      p_values      => '10') 
  8    );
  9  end;
 10  /
f?p=105:2:::NO::P2_DEPTNO:10

MGORICKI@db12c.local> exec apex_session.create_session(105,1,'MGORICKI');
PL/SQL procedure successfully completed.

MGORICKI@db12c.local> begin
  2    dbms_output.put_line(
  3      apex_page.get_url (
  4      p_application => 105,
  5      p_page        => 2,
  6      p_items       => 'P2_DEPTNO',
  7      p_values      => '10') 
  8    );
  9  end;
 10  /
f?p=105:2:10768192845699::NO::P2_DEPTNO:10&cs=1oFPSPIwCRBbRJ-gn0limWuA1XoCpqism6d38e0-EDXXNyZ8HKLmoJjZNBY7P_rGEL94hPmaZWw1skLp84bPqlg

Enjoy!