Monday, February 17, 2014

ADF Faces: How to skin a great looking breadcrumb


Although the default ADF Skin is fine for many UI requirements, there are often special customer needs for specific design. In this short blogpost I am going to show how you can skin a great looking breadcrumb (with plain CSS). The following picture shows what I am talking about:
Usage
Inside ADF Pages it should be is easy to create such a breadcrumb:

<af:panelList id="pl1" styleClass="MyBreadcrumb">
    <af:commandLink text="Home" id="cl1" />
    <af:commandLink text="commandLink 2" id="cl2"/>
    <af:commandLink text="commandLink 3" id="cl3"/>
</af:panelList>

Environment
Created with ADF 11.1.2.4 (but should also work with 11gR1 oder 12c)
Tested with current versions of

  • Safari
  • Chrome
  • Firefox
  • IE 9

How to do it
Create a custom ADF Skin with the following CSS Statements

af|panelList.MyBreadcrumb ul {
    list-style: none;
    overflow: hidden;
    display: block;
    padding-left: 0px;
}

af|panelList.MyBreadcrumb li {
    float: left;
    /*display: list-item;
    text-align: -webkit-match-parent;*/
   
}


af|panelList.MyBreadcrumb li:first-child a {
    padding-left: 10px;
    background: gray;
}

af|panelList.MyBreadcrumb li:first-child a:after {
    border-left-color: gray;
}

af|panelList.MyBreadcrumb li a:hover:after {
    border-left-color: red;
}

/*af|panelList li:nth-child(2) a {
   
}*/
af|panelList.MyBreadcrumb li a span {
    color: white;  
}

af|panelList.MyBreadcrumb li af|commandImageLink {   
    color: white;
    text-decoration: none;
    padding: 4px 0 5px 55px;
    background: #eee;
    position: relative;
    display: block;
    float: left;
}


af|panelList.MyBreadcrumb li af|commandImageLink:text-only,
af|panelList.MyBreadcrumb li a {

    color: white;
    text-decoration: none;
    padding: 10px 0 10px 55px;
    background: #bbb;
    position: relative;
    display: block;
    float: left;
   
}

af|panelList.MyBreadcrumb li a:hover {
    background: red;
    text-decoration: none;
}


af|panelList.MyBreadcrumb li a:before {
    content: " ";
    display: block;
    width: 0;
    height: 0;
    border-top: 50px solid transparent;
    border-bottom: 50px solid transparent;
    border-left: 30px solid white;
    position: absolute;
    top: 50%;
    margin-top: -50px;
    margin-left: 2px;
    left: 100%;
    z-index: 1;
}

af|panelList.MyBreadcrumb li a:after {
    content: " ";
    display: block;
    width: 0;
    height: 0;
    border-top: 50px solid transparent;
    border-bottom: 50px solid transparent;
    border-left: 30px solid #bbb;
    position: absolute;
    top: 50%;
    margin-top: -50px;
    left: 100%;
    z-index: 2;

Hint
I know that the usage of direct HTML Selectors in ADF Skin files is not a good practice because the skin could break if upgrading to a new ADF Version. If you like feel free to improve the CSS.

Download


References

Friday, February 14, 2014

ADF: Handling exceptions from BackingBeans inside bounded Taskflow explained


Scenario 1

Exception is thrown in actionListener Code for a commandButton inside a View of a bounded taskflow based on page fragments.

In our example Test1ViewBean is in Request-Scope and contains an ActionListener method that throws a NullPointerException for demo purposes.

 This ActionListener is called from a command button


The Default behaviour in this scenario is the following:


Of course this is not user friendly (+ may cause side effects) so we should use one of the provided ADF Exception handling mechanisms to fix that.

Solution to scenario 1:

Make a guess: (a) DCErrorHandler (b) BTF-Exception-Handler (c) UTF-Exception-Handler (d) Faces-ExceptionHandler (e) Servlet-Exception Handler

Tam da da dam: Solution is "(c) UTF-Exception-Handler" not "(b) BTF-Exception-Handler" as some of you might expect. 

Let's see how it works. Create a Method-Activity in adfc-config.xml
and mark it as Exception-Handler.


The Method Activity points - by EL -  to the following java method:

  public void handleExceptionShowMessageInPopupDialog() {
    ControllerContext cc = ControllerContext.getInstance();

    Exception ex = cc.getCurrentViewPort().getExceptionData();
    String message = ex.getMessage();


    FacesContext fc = FacesContext.getCurrentInstance();
    FacesMessage facesMessage =
      new FacesMessage(FacesMessage.SEVERITY_ERROR, "UTF: " + message, null);
    fc.addMessage(null, facesMessage);

    cc.getCurrentRootViewPort().clearException();
    fc.renderResponse();

  }
Having this Exception-Handler active on runtime the Exception is catched an displayed in a user friendly inline popup



Why the "(b) BTF-Exception-Handler" is not working in the given scenario?
Well, it is because the action event is handled in the standard JSF Lifecycle (invoke application phase) and not inside the ADF Controller of the bounded taskflow.


Download

In the sample application - based on ADF 11.1.1.7 - you can test the different cases and see how everything works in each scenario. enpit.sample.adf.testExceptionHandling-jdev11117.zip

Further Reading