Controlling the Sizing of the af:messages Dialog

Posted by Duncan Mills on Oracle Blogs See other posts from Oracle Blogs or by Duncan Mills
Published on Wed, 14 Nov 2012 12:18:40 +0000 Indexed on 2012/11/14 17:13 UTC
Read the original article Hit count: 214

Filed under:

Over the last day or so a small change in behaviour between 11.1.2.n releases of ADF and earlier versions has come to my attention. This has concerned the default sizing of the dialog that the framework automatically generates to handle the display of JSF messages being handled by the <af:messages> component. Unlike a normal popup, you don't have a physical <af:dialog> or <af:window> to set the sizing on in your page definition, so you're at the mercy of what the framework provides. In this case the framework now defines a fixed 250x250 pixel content area dialog for these messages, which can look a bit weird if the message is either very short, or very long. Unfortunately this is not something that you can control through the skin, instead you have to be a little more creative.

Here's the solution I've come up with.  Unfortunately, I've not found a supportable way to reset the dialog so as to say  just size yourself based on your contents, it is actually possible to do this by tweaking the correct DOM objects, but I wanted to start with a mostly supportable solution that only uses the best practice of working through the ADF client side APIs.

The Technique

The basic approach I've taken is really very simple.  The af:messages dialog is just a normal richDialog object, it just happens to be one that is pre-defined for you with a particular known name "msgDlg" (which hopefully won't change). Knowing this, you can call the accepted APIs to control the content width and height of that dialog, as our meerkat friends would say, "simples" 1

The JavaScript

For this example I've defined three JavaScript functions.  

  1. The first does all the hard work and is designed to be called from server side Java or from a page load event to set the default.
  2. The second is a utility function used by the first to validate the values you're about to use for height and width.
  3. The final function is one that can be called from the page load event to set an initial default sizing if that's all you need to do.

Function resizeDefaultMessageDialog()

/**
   * Function that actually resets the default message dialog sizing.
   * Note that the width and height supplied define the content area
   * So the actual physical dialog size will be larger to account for
   * the chrome containing the header / footer etc.
   * @param docId Faces component id of the document
   * @param contentWidth - new content width you need 
   * @param contentHeight - new content height
   */
  function resizeDefaultMessageDialog(docId, contentWidth, contentHeight) {
    // Warning this value may change from release to release
    var defMDName = "::msgDlg";
 
    //Find the default messages dialog
    msgDialogComponent = 
      AdfPage.PAGE.findComponentByAbsoluteId(docId + defMDName); 

    // In your version add a check here to ensure we've found the right object!

    // Check the new width is supplied and is a positive number, if so apply it.
    if (dimensionIsValid(contentWidth)){
        msgDialogComponent.setContentWidth(contentWidth);
    }
 
    // Check the new height is supplied and is a positive number, if so apply it.
    if (dimensionIsValid(contentHeight)){
        msgDialogComponent.setContentHeight(contentHeight);
    }
  }

 Function dimensionIsValid()

 /**
 * Simple function to check that sensible numeric values are 
 * being proposed for a dimension
 * @param sampleDimension 
 * @return booolean
 */
function dimensionIsValid(sampleDimension){
    return (!isNaN(sampleDimension) && sampleDimension > 0);
}

Function  initializeDefaultMessageDialogSize()

 /**
 * This function will re-define the default sizing applied by the framework 
 * in 11.1.2.n versions
 * It is designed to be called with the document onLoad event
 */
function initializeDefaultMessageDialogSize(loadEvent){
  //get the configuration information
  var documentId = loadEvent.getSource().getProperty('documentId');
  var newWidth = loadEvent.getSource().getProperty('defaultMessageDialogContentWidth');
  var newHeight = loadEvent.getSource().getProperty('defaultMessageDialogContentHeight');
  resizeDefaultMessageDialog(documentId, newWidth, newHeight);
}

Wiring in the Functions

As usual, the first thing we need to do when using JavaScript with ADF is to define an af:resource  in the document metaContainer facet

<af:document>

   ....  

   <f:facet name="metaContainer">
     <af:resource type="javascript" source="/resources/js/hackMessagedDialog.js"/>
   </f:facet>
</af:document>

This makes the script functions available to call. 

Next if you want to use the option of defining an initial default size for the dialog you use a combination of <af:clientListener> and <af:clientAttribute> tags like this.

<af:document title="MyApp" id="doc1">
   <af:clientListener method="initializeDefaultMessageDialogSize" type="load"/>
   <af:clientAttribute name="documentId" value="doc1"/>
   <af:clientAttribute name="defaultMessageDialogContentWidth" value="400"/>
   <af:clientAttribute name="defaultMessageDialogContentHeight" value="150"/> 
... 

 Just in Time Dialog Sizing 

So  what happens if you have a variety of messages that you might add and in some cases you need a small dialog and an other cases a large one? Well in that case you can re-size these dialogs just before you submit the message. Here's some example Java code:

FacesContext ctx = FacesContext.getCurrentInstance();
        
//reset the default dialog size for this message
ExtendedRenderKitService service = 
             Service.getRenderKitService(ctx, ExtendedRenderKitService.class);
service.addScript(ctx, "resizeDefaultMessageDialog('doc1',100,50);");
        
FacesMessage msg = new FacesMessage("Short message");
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
ctx.addMessage(null, msg); 

So there you have it. This technique should, at least, allow you to control the dialog sizing just enough to stop really objectionable whitespace or scrollbars.

1 Don't worry if you don't get the reference, lest's just say my kids watch too many adverts.

© Oracle Blogs or respective owner

Related posts about /ADF/ADF Faces and UI