31 Aug 2014

Really Dynamic Declarative Components

In this short post I am going to focus on ADF dynamic declarative components. I mean a well known ADF tag af:declarativeComponent. It can be used as a pretty convenient way to design a page as a composition of page fragments and components. For example, our page can contain the following code snippet:

 <af:declarativeComponent viewId="PageFragment.jsff" id="dc1">
   <f:facet name="TheFacet">
     <af:button text="button 1" id="b1"/>
   </f:facet>                    
 </af:declarativeComponent>


And the PageFragment.jsff is a usual page fragment like this one:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
  <af:panelGroupLayout id="pgl1">
    <af:outputText value="This is a page fragment. 
                          You can add your content to the following facet:"
                   id="ot1"/>
    <af:facetRef facetName="TheFacet"/>
  </af:panelGroupLayout>
</jsp:root>


If we need to be able to pass some parameters to a page fragment, we can define the fragment as a component:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<af:componentDef var="attrs">
  <af:xmlContent>
    <component xmlns="http://xmlns.oracle.com/adf/faces/rich/component">
      <facet>
        <facet-name>TheFacet</facet-name>
      </facet>
      <attribute>
        <attribute-name>Title</attribute-name>
      </attribute>
    </component>
  </af:xmlContent>
  <af:panelGroupLayout id="pgl1">
    <af:outputText value="This is a component #{attrs.Title}.
                          You can add your content to the following facet:" id="ot1"/>
    <af:facetRef facetName="TheFacet"/>
  </af:panelGroupLayout>
 </af:componentDef> 
</jsp:root>

In this example we can pass the value of the Title attribute as it is shown in this code snippet:

<af:declarativeComponent viewId="ComponentFragment.jsff"
                         id="dc2"
                         Title="Buttom Container">                    
   <f:facet name="TheFacet">
        <af:button text="button 2" id="b2"/>
    </f:facet>                    
</af:declarativeComponent>


And the most cool thing about this technique is that viewId attribute can accept not only static strings, but EL expressions as well:

 <af:declarativeComponent viewId="#{TheBean.fragmentViewID}"
                          id="dc1">
   <f:facet name="TheFacet">
     <af:button text="button 1" id="b1"/>
   </f:facet>                    
 </af:declarativeComponent>


public String getFragmentViewID() {
    return "PageFragment.jsff";
}


Actually that's why this construction is called dynamic, and that's why this feature can be considered as a powerful tool for building well structured, flexible and dynamic UI.

That's it!