23 June, 2011

'Growl' style notification messages for APEX

A question was asked in this thread on the APEX forums that got me itching to do a science experiment.
The basic question was this:

"Is it possible to produce 'Growl' style notifications in place of the standard APEX Success and Failure messages?"
In short the answer is an unequivocal 'Yes', and here's how:

First, unless you're a JavaScript whiz and can write your own, you'll need to search out some sort of JavaScript library that provides the Growl style notification. After a quick Google search I found this page...

http://webtoolkit4.me/2009/08/13/jquery-growl-likenotification-systems/

I chose to search for jQuery related notification systems because of the fact that jQuery is already integrated into APEX 4 and that would mean that there would be less in terms of external JavaScripts for me to load and manage.

After looking at the individual option there, I chose to work with Gritter for a number of reasons.
  1. I liked the look and feel of it's output. To me it felt the most like what I am used to seeing from Growl.
  2. The JavaScript is very light. In total it's about 400 lines long un-minified. Much of that is white space and comments which means that minified it's going to be minute.
  3. It pushes most of the heavy lifting back onto jQuery, where it should be, and the author doesn't try to over engineer the solution.
You can choose what ever library you wish, but in this example I'll be using Gritter.

The first thing you need to do is put the Gritter JavaScript where it can be accessed by APEX. As a general rule of thumb, it's a very bad habit to get into to put your own code into the /i/ directory provided by Oracle. So we create a directory on our web server to hold all of our custom code, normally named /c/. Inside this directory I created a directory to hold the gritter objects. I ended up with the following directory entries:

/c/gritter/js
/c/gritter/css
/c/gritter/images

The next thing to do is to include these scripts into your application. I wanted to see if I could completely replace the standard way APEX handles SUCCESS and FAILURE messages, so I want these scripts to be available on every page. There are two ways I could do this: I could create an After Header region on Page Zero that loads the scripts, or I could edit the page template and insert the script calls there.

To make things as quick and easy as possible to load and troubleshoot, I chose to create a Page Zero region as follows:

Region Name: GRITTER - INCLUDES
Region Type: HTML Text
Template Type: No Template
Display Point: After Header

and include the following code:

<link href="/c/gritter/css/jquery.gritter.css" type="text/css" rel="stylesheet" />
<script src="/c/gritter/js/jquery.gritter.min.js" type="text/javascript"></script>
 
After loading the scripts and doing a few tests, I found out a few things...

  1. You can use JavaScript in the Success and Failure message of any validation or process and it will be executed. News to me and something I'll file away for later use!
  2. This isn't scalable as you'd have to change every message within your application to a JavaScript call.
  3. Because of the way JavaScript deals with nested quotes within strings, life gets extremely interesting when the message you're trying to relay to the end user contains either single or double quotes.
To make this work at the application level without forcing the developer to use JavaScript for every message we need to go a step higher and look at the templates. If you're unfamiliar with APEX templates you may not know that within a page template there are two sub-templates for the Success and Notification (failure) messages. By editing these areas within your page template you can move the handling of the JavaScript up so that the developers don't have to worry about it. They can treat the success and failure messages as they always have.

To alter the template, navigate to the shared components for the application, click on Templates and edit the page template that you’re using throughout your application. In most cases there will probably only be one template that you’re using, but for more complex applications there may be 2 or 3 you need to edit. You really only need to edit the templates that are used on pages you want to use the growl notification. In my case, there was just one.

Once you edit the template, you’ll need to scroll down to the Subtemplate region. This is where the Success Message and and the Notification (Fail) message templates are defined.

In the Picture below you’ll see the code in both regions that replaced the original code included in the template.

PastedGraphic-2011-06-23-15-24.jpg

In both cases, the first thing the code does is create a DIV, giving it an ID that we can grab ahold of later and sets its CSS style to “display:non”. This will keep the DIV from displaying until the Gritter script styles it. The contents of the DIV is the appropriate message template replacement variable, #SUCCESS_MESSAGE# and #MESSAGE#.

The next bit of code is a call to a piece of JavaScript code that we’ll talk about in just a moment. The first call, to growlSuccess takes two parameters. First is the ID for the DIV so the script can get a handle on it, and the second is the duration for how long the notification should be displayed. In this case, 5000 is about 5 seconds. The second call, to growlSticky only takes one parameter, the ID of the DIV. This function creates a “sticky” notification that the user will need to dismiss. The reason I created this one is because you want to make sure the end user sees and acknowledges the any error message.

The last piece of the puzzle is the javascript that kicks off the Gritter script. Again, I chose to implement this on Page Zero.

Region Name: GRITTER - JavaScript
Region Type: HTML Text
Template Type: No Template
Display Point: After Header

And the code in this region is as follows.

<script type="text/javascript">

function growlSuccess(vRegion, vLength){
// Get the message out of the DIV created by the page template
var vMessage = document.getElementById(vRegion).innerHTML;
// Instantiate the gritter message.
$.gritter.add({
// (string | mandatory) the heading of the notification
title: 'SUCCESS',
// (string | mandatory) the text inside the notification
text: vMessage,
// (bool | optional) if you want it to fade out on its own or just sit there
sticky: false,
// (int | optional) the time you want it to be alive for before fading out
time: vLength
});
return false;
}

function growlSticky(vRegion){
// Get the message out of the DIV created by the page template
var vMessage = document.getElementById(vRegion).innerHTML;
// Instantiate the gritter message.
$.gritter.add({
// (string | mandatory) the heading of the notification
title: 'MESSAGE',
// (string | mandatory) the text inside the notification
text: vMessage,
// (bool | optional) if you want it to fade out on its own or just sit there
sticky: true,
// An image to place inside the gritter notification
image:'#IMAGE_PREFIX#menu/info_32.gif'
});
return false;
}

</script>

This is the definition of the two functions that we called in the template code. The comments in the code should document what it’s doing fairly well. But the main thing to understand are is the call to gritter.add. This is the “magic” code that creates the Gritter “floating message”.

Referencing the Gritter documentation, you’ll see that there are quite a number of options that I’m not using. I wanted to keep things fairly simple just to make sure I wasn’t fighting against complexity in the early stages. I did go an extra step and put an image inside the sticky message type that is used for Notifications, to differentiate it from the Success Message.

Here’s the end result...

PastedGraphic1-2011-06-23-15-24.jpg

Hopefully this not only answers the question, “Is it possible”, but also shows you that there is way more to APEX than meets the eye. You can use JavaScript in a number of places that you wouldn’t expect. I’m continually pleasantly surprised at the flexibility of APEX.


EDIT (6/24/11) - Patrick Wolfe, completely independently, has created a Dynamic Action plugin that does much the same thing (see the demo here). The reason I went down this path is because the DA Plugin isn’t easily implemented for the APEX Success and Failure message. Anyway. Interesting that two people solved a strikingly similar problem and came up with much the same solution!



22 June, 2011

It's been quiet... Too Quiet!

You have probably noticed that this blog has been very quite for the last few months... Well, there is a reason for that.

Apart from the books that I've been involved in writing, we at Sumneva been working feverishly to put the finishing touches on our first product, sumnevaSERT. And today, we release it into the wild.

And with all of scary security breaches that have happened recently, the release couldn't have come at a better time.

For those of you who aren't familiar, sumnevaSERT is a simple yet powerful tool that outlines potential security risks in any Oracle APEX application and provides recommendations on how to mitigate them. You can the Sumneva news post about it here, and get more information about it here. Or

You can also come and see us at ODTUG KScope11. We'll have a booth in the exhibition hall and will be giving a vendor presentation on securing your APEX applications.

Now that the release is out in the wild, hopefully I'll have a bit more time to finish some half completed blog posts and get back out into the world a bit more.

But keep an eye out, because sumnevaSERT is just the beginning. We plan to continue to support our mission to make developing secure and performant APEX applications even easier.

Watch this space!

10 June, 2011

Oracle Author Podcast.

I recently had the pleasure of co-authoring the APress book, Beginning Oracle Application Express 4. It was both a trying and rewarding experience, but I'm glad I did it.


A couple weeks ago I also participated in creating a Podcast about the book. 


Here's some information about it...


A conversation with Patrick Cimolini, Martin D'Souza, and Doug Gault; Authors of Beginning Oracle Application Express 4.  David Peake, Principal Product Manager for APEX, chats with some of the authors of the book. They will discuss various aspects about the book including the main reason for the book, who the book is focused towards, and some behind the scenes information about it's writing.

 
 

07 May, 2011

APEX 4.1 Early Adopter Available.

The APEX team has once again surpassed expectations and has released the Early Adopter version or APEX 4.1 on http://tryaxpexnow.com.

A list of what's new appears in the Feature Description application, but both Joel Kallman and David Peake warn that there is likely to be more in the final production release.

After having a look at the features, here are some that really stand out to me:

  • Declarative Support for Buttons to Trigger Dynamic Actions - The initial version allows you to use any IMAGE or HTML button to trigger dynamic actions. Theme based buttons will currently only work in Theme 21, but I'm sure that will be expanded for the production release.
  • Dynamic Lists - The ability for a list to be based on a SQL statement or a PL/SQL function returning a SQL statement is huge. This will make it way easier to create menuing  systems (even CSS based tabs) based on dynamic content stored in tables or gleaned from meta data.
  • Improved Error Handling  - The features listed here are two-fold.
    • Settable Error Display Location for Processes - For OnSubmit type page processes you can now set the "Error Message Display Location" to either a "Separate Error Page" or "Inline in Notification".
    • New Error Handling Function - A new function has been provided  that allows developers to modify or log any errors which occur in apex. (I wonder if they used Tyler Muth's Logger Package).  Patrick Wolf is slated to let us know more soon!
  • Plugin Enhancements - There are several plug-in enhancements but the ones that caught my eye were
    • Adding Plug-in Support for Authorization Schemes 
    • Increased number of custom attributes to 15
    • New Plugin Attribute type Checkbox
  • Enhanced Tabular Forms  - APEX 4.0 introduces HUGE leaps forward in Tabular forms and that theme has been continued in APEX 4.1.
    • Validations - Tabular forms now support all validation types. Bind Variable syntax, substitution syntax and Column name are now available depending upon what type of validation you're implementing.
    • Processes   - Processes can now be defined for tabular forms as well. These processes allow for easier processing of the each row's items without having to deal with the apex_application g_f0X arrays.
    • Use of ROWID  - You're now allowed to use ROWID as the primary key for Automatic DML Processing in tabular forms.
  • Consistency of Item Based Buttons - Item based buttons have now been brought in line and now offer the same behavior has Region based buttons.
While I can't wait to get my hands on some of the new features, this also means that there will need to be some updates to our training material... *Sigh*, it never ends!