Thursday Feb 21, 2013

Get More From Your Messages

Within ADF Faces we take much goodness and added value for granted.  One such feature came to my attention just the other day. Had you noticed that when you have several errors outstanding on the screen the framework gives you a hyperlink to set focus to that field? See the error on commissionPct below and the hyperlink that you could click to move focus to it in the screen:

 So that's neat and I must confess that although I must have stared this one in the face hundreds of times I never really groked how cool that was. 

Anyway, as is usual, this was not just a random act of attention on my part but rather considering a couple of different user cases which both boiled down to the basic question.  Can we extend these error dialogs in some way to show more detail or carry out some other action in response to the error? So that's what I wanted to work through in this article, because the answer is (of course) yes!

How to make the Messages Interactive?

So let's take a look at how to do this. The clue is in the documentation for the tag which casually mentions that  you can include HTML into your Faces messages or message detail. and one of the examples is the embedding of an anchor tag to embed a hyperlink - something that could indeed be useful in a message.  So it occurred to me that this hyperlink provided the opportunity for  an actionable gesture that the user could make to do stuff within the actual application as well as jump off to another one. However, it's not all plain sailing, you can't just embed any old HTML markup into the messages (I did try!) So no embedding of buttons, and even for an <a> tag you can't wire in JavaScript with an onClick=, that all get stripped out.

However, with a carefully shaped href attribute you can call JavaScript. So for example I've crafted the following message detail string:

<html>Detail for errror <a href=javascript:errorDetailCallback('it1','d1');>here</a></html>

 This renders the word "here" as a link in the message and then when the user clicks on that it calls a JavaScript errorDetailCallback() with a couple of arguments.  This function is included in a script linked onto the page using a standard <af:resource> tag.

The script itself could do anything. In my sample I'm actually making it call back to the server (via an <af:serverListener> defined in the document. Here's the JavaScript function:

 function errorDetailCallback(errorContext, documentComponentId){
    
    var callbackComponent = AdfPage.PAGE.findComponentByAbsoluteId(documentComponentId);
    if (callbackComponent != null) {
        var serverEvent = new AdfCustomEvent(callbackComponent, 
                                             "errorDetailEvent",
                                             {detailKey : errorContext},
                                             true);
        serverEvent.queue(true);
    }
    else{
        AdfLogger.LOGGER.severe("errorDetailCallback: Error unable to locate document component: " 
                                + documentComponentId);
    }  
}

The custom event is wired into the server via the <af:serverListener> tag:

<af:serverListener type="errorDetailEvent" 
                   method="#{indexPageBB.errorDrilldownHandler}"/>

 The server side method (errorDrilldownHandler()) in my case gets the custom event and then shows a popup in response:

 public void errorDrilldownHandler(ClientEvent clientEvent) {
   Map params = clientEvent.getParameters();
   String detailKey = (String)params.get("detailKey");
   if (detailKey != null && _errorDetail.containsKey(detailKey)){
     _lastErrorKey = detailKey;
   }
   else{
     _lastErrorKey = "UNKNOWN";
   }
        
   //Now do what you want. In this case show a popup with a detail message
   RichPopup.PopupHints hints = new RichPopup.PopupHints();
   getDetailPopup().show(hints);
 }

Note that in the above case, the _lastErrorKey  is simply a variable which is used by the getter that populates the text in the popup, it's used as a key into a Map with some further message details in it. However, what you do in this callback routine is of course up to you. 

Wednesday Feb 20, 2013

Using JDeveloper 11.1.1.6 & 11.1.2.3 with Subversion 1.7

This issue has come up a couple of times this week and has also be raised on the OTN JDeveloper Forum, so it seemed to be worth a quick public-service announcement.  

Subversion 1.7 introduces changes (AKA complete re-write) into the way that working copies are stored, the implication of this is that a 1.6 client and a 1.7 client cannot operate again the same working copy on a developer's workstation. 

Current versions of JDeveloper's SVN support contain 1.6 client code, so if you are mixing and matching JDeveloper and SVN / Tortoise command line operations you will run into trouble. 

e.g. The following sequence of operations will fail:

  1. Checkout working copy from the command line with the svn 1.7 client
  2. Make updates and attempt to checkin from JDeveloper 

However, the following should work:

  1. Checkout working copy from JDeveloper 
  2. Make updates and checkin from JDeveloper 

As will:

  1. Checkout working copy from the command line with the svn 1.7 client
  2. Disable the JDeveloper SVN plugin - (Versioning -> Configure -> Uncheck - Versioning Support for Subversion )
  3. Make updates  to existing files only from JDeveloper
  4. Commit / Add / Delete operations from Command line svn 1.7 client. 

Obviously, for convenience and because some operations such as refactoring need to issue SVN commands I'd recommend that, if using a 1.7 repository, you carry out all operations including the initial checkout from within the IDE.  

As a general guidance if you are going to upgrade your repository (and my further advice would be not to upgrade at the moment if your primary client is JDeveloper) I'd recommend that you clean up any outstanding transactions before the upgrade, and then, once the server is up to 1.7, do a clean checkout from JDeveloper and stick to working within that environment.

Monday Feb 18, 2013

MySQL & ADF Business Components - Enum types

A quick guide to effectively mapping and representing MySQL enumeration types through ADF Business Components [Read More]
About

Hawaii, Yes! Duncan has been around Oracle technology way too long but occasionally has interesting things to say. He works in the Development Tools Division at Oracle, but you guessed that right? In his spare time he contributes to the Hudson CI Server Project at Eclipse
Follow DuncanMills on Twitter

Note that comments on this blog are moderated so (1) There may be a delay before it gets published (2) I reserve the right to ignore silly questions and comment spam is not tolerated - it gets deleted so don't even bother, we all have better things to do with our lives.
However, don't be put off, I want to hear what you have to say!

Search

Archives
« February 2013 »
MonTueWedThuFriSatSun
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
19
22
23
24
25
26
27
28
   
       
Today