27 Mar 2011

Smart List of Values

We can use two wonderful components for working with the lists of values :  Input List Of Values and Input Combobox List of Values. But my users got used to too much comfort and they want to input department's ID manually in one field and see automatic reflection of the department's name in another field. And they want to choose the department's name from some list and to have reflection of its ID automatically.
In order to match this requirement I need to do some trick in my model. I've got EmployeesView VO with DepartmentID and DepartmentName fields. The trick is to create two LOV's on Departmentid and Departmentname as well. The LOV for Departmentid:

 Note, that DepartmentName field is also mapped. And the LOV for DepartmentID:


It uses the same viewaccessor and has mapping for DepartmentID as well.

On my page I'm going to put one InputText for DepartmentID and one ComboBox List of Values for DepartmentName. It's needed to link them with each other as partial targets and mark DepartmentID as an autosubmitted field. 
Both fields are put on a horizontal layout panel within Panel Label and Message:
<af:panelLabelAndMessage label="#{bindings.DepartmentId.label}" id="plam1">
  <af:panelGroupLayout id="pgl1" layout="horizontal">
    <af:inputText value="#{bindings.DepartmentId.inputValue}"
                  required="#{bindings.DepartmentId.hints.mandatory}"
                  columns="#{bindings.DepartmentId.hints.displayWidth}"
                  id="deptid" partialTriggers="departmentNameId"
                  autoSubmit="true" simple="true"/>
    <af:inputComboboxListOfValues id="departmentNameId"
          popupTitle="Search and Select: #{bindings.DepartmentName.hints.label}"
          value="#{bindings.DepartmentName.inputValue}"
          model="#{bindings.DepartmentName.listOfValuesModel}"
          required="#{bindings.DepartmentName.hints.mandatory}"
          columns="#{bindings.DepartmentName.hints.displayWidth}"
          shortDesc="#{bindings.DepartmentName.hints.tooltip}"
          partialTriggers="deptid"
          simple="true">
      <f:validator binding="#{bindings.DepartmentName.validator}"/>
    </af:inputComboboxListOfValues>
  </af:panelGroupLayout>
</af:panelLabelAndMessage>


The working page looks like this:


In my next post I'm going to show how to create ADF declarative component in order to use this approach in your application as a standard one.

7 Mar 2011

Nested Page Templates

We are provided by quite powerful ADF feature "Page templates". The feature allows us to get common "Look and Feel" of our application, to reuse components, page fragments as well as application logic.
Let's say all pages in my application should have some image header on the top and two buttons (Ok, Cancel) on the bottom. In order to match the requirement I'm going to create page template MaintemplateDef.jspx with the following code:


    
      
        
          
                    
          
          
        
      
      
        
                
      
      
        
        
      
    
    
      
        MaintemplateDef
        
          
            centerFacet
          
        
      
    
  

And it looks like this:

Every page built on this template should provide its specific content within facet "centerFacet".
Ok, let's implement additional requirement - some pages should have space for menu on the left (except header on the top and buttons on the bottom).  We have to complicate our template to match new requirement:

    
      
        
          
          
          
          
        
      
      
        
        
        
          
            
            
          
          
                      
            
          
        
        
        
          
          
                     
        
      
      
        
        
      
    
    
      
        MaintemplateDef
        
          
            centerFacet
          
        
        
          
            menuFacet
          
        
        
          
            centermenuFacet
          
        
        
          
            menuVisible
          
          
            java.lang.Boolean
          
          
            false
          
        
      
    
  
I've added boolean attribute menuVisible and switcher showing panelSplitter with facet for menu. Pages with menu should set attribute menuVisible to true and use facets menuFacet and centermenuFacet. Let's imagine we have one more requirement - some pages should have panelTabbed component instead of left menu. Our page template is going to get more complicated, and it's going to keep complicating with every new requirement. Is it cool? No, it isn't! Some more requirements and our page template will be like a mess. It'll be much more difficult to make any changes and support this template. To resolve the problem I wish I had a possibility to create templates of templates or "nested templates".  And actually we have got it!

This is impossible to create nested page template declaratively with JDeveloper. But we can do it manually! And it works! So, let's go back to the first implementation of our template and create new page template in usual way. Let's call it LeftMenutemplateDef.jspx. We will get the following simple code:

    
      
        LeftMenutemplateDef
      
    
  

The trick is to add reference to MaintemplateDef.jspx manually:


    
    
    
  

    
      
        LeftMenutemplateDef
      
    
  

Now, our LeftMenutemplateDef.jspx template is page template built on MaintemplateDef.jspx. It is nested page template. In order to match the requirement with menu on the left we have to add some code:
  
    
        
          
            
            
          
          
            
            
          
        
      
  
    
      
        LeftMenutemplateDef
        
          
            menuFacet
          
        
        
          
            centerFacet
          
        
      
    
  

And now it looks like this:

Every page with menu on the left has to be built on LeftMenutemplateDef template, every page without menu should be built on MaintemplateDef template.