Wednesday, 12 October 2016

APEX URLs and HTML need not be in your SQL report queries

I've seen a few examples recently where people have been embedding URLs and HTML into their SQL queries. I tend to advocate keeping such things out of the query itself and using APEX functionality such as link target and html expressions (in SQL Query column attributes).

First example, a full page URL embedded into a column like so (conditionally based on some condition):

case when job = 'PRESIDENT'
then 'f?p='||:APP_ID||':2:'||:APP_SESSION||'::::P2_EMPNO:'||empno
else  'f?p='||:APP_ID||':3:'||:APP_SESSION||'::::P3_EMPNO:'||empno
end dest_url

Then on the column attributes, you make it a link by specifying the type as a link and the target as a URL specifying the target as #DEST_URL#




Taking a look at the URL, we can see there is only one bit changing, and that is the page number. So, we can avoid embedding the whole URL in our query by simply adding a column for our destination page:

case when job = 'PRESIDENT'
then 2
else  3
end dest_page

Then, when we specify our target, we use the page in this application option, and pass in the row value #DEST_PAGE#, like so:




Another example it is not uncommon to come across in samples is actually generating much more HTML in the query, for example:

'<button onclick="void(0);" type="button"'
        || ' class="t-Button t-Button--hot t-Button--small actionButton"'
        || ' data-empno="' || empno || '"'
        || ' data-job="' || job || '">'
        || ' <span class="t-Button-label">Click me!<span></button>'
    awesome_btn

After adding this, you also need to set security options to not escape special characters, in order for this to be rendered properly.

But again, it really is not necessary to add all this noise to your query. In a report, every column has a HTML Expression property where you can modify the column/row value to use custom HTML. So, from the previous example, we change the query just to add a new column - if you need a new field, use that, or just add an empty column to put your button in:


Then, in the column attributes, for HTML expression, it's just a matter of specifying that same HTML as from the previous example (less any PL/SQL and SQL bits - and using substitution strings where necessary).

<button 
    onclick="void(0);" 
    type="button" 
    class="t-Button t-Button--hot t-Button--small actionButton" 
    data-empno="#EMPNO#" 
    data-job="#JOB#"> 
    <span class="t-Button-label">
        Click me!(2)
    </span>
</button>

..

Obviously, this will come down to a personal preference on how you deal with such situations. I just prefer to remove unnecessary noise from my queries and use aspects of APEX that are available to me - rather than embedding as much as possible in the query source. 

5 comments:

  1. Hi Trent,

    The above exemple is ok with all the pages in one application but if you have pages accross multiple application then there will be a issue using your method.

    ReplyDelete
    Replies
    1. Why couldn't you specify it in the URL field?

      Delete
    2. No, since you can choose "Page in a different application" and supply the app_id/alias the same way.

      Delete
  2. You are right defining another column as application id in the SQL and refering that in the application URL field.

    ReplyDelete
  3. I think this will be a good reference for frequent forum questions.

    I also like using the link attribute properties to list the class, data- attributes. And from 5.1, this accepts substitution strings.

    ReplyDelete