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. 

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