Monday Sep 30, 2013

Oracle JHeadstart 11.1.1.5 Now Available

Oracle JHeadstart 11.1.1.5 is now available. This is a maintenance release for JDeveloper 11g R1. Oracle JHeadstart 12c, a new release that will be compatible with JDeveloper 12c is currently planned to become general available later this calendar year. 

This 11.1.1.5 release contains the following new features:

  • UI Tree Checked for Pending Changes: Prior to this release, pending changes were only detected in the model, after the JSF lifecycle phase "Update Model" was executed to update the underlying ADF model bindings. This implied that for menu item commands the immediate property had to be set to false to detect the last changes made by the user that were not yet sent to the server, otherwise the "Update Model" phase was skipped. However, with immediate=false, the end user could not abandon pages with invalid or incomplete data as validation errors occurred before the menu navigation could take place. So, the choice was to either limit the navigation freedom of the end user, or accept the fact that the pending changes alert was not always shown. With this new release this problem is solved. All menu items have immediate=false allowing complete freedom to navigate away, while the latest changes are also detected because JHeadstart now inspects the UI Components in the page UI tree for any changes. The UI Components are always updated with the latest value, also when immediate is set to true because the UI components are updated in JSF lifecycle phase "Apply Request Values" which is always executed, regardless of the setting of the immediate property. The inspection of the UI tree is performed in a new managed bean class PendingChangesVisitCallBack. This class is generated as managed bean in JhsCommon-beans.xml. If for some reason you want to keep the old behavior, and not inspect the UI tree for pending changes, you can add the following property to the ApplicationDefinition.xml file:
      checkUITreePendingChanges="false"
    
    Note that you need to set this property directly in the xml file, it is not visible in the JHeadstart Application Definition editor. If this property is set to false, the PendingChangesVisitCallBack bean is not generated and the menu item commands are generated again with immediate=false.
  • Ability to override generated item properties: The item-level property "Additional Properties" has been renamed to "Additional / Overriding Properties" can now be used as well to override standard generated properties. If you specify a property in "Additional / Overriding Properties" then this property always 'wins', it will override a property by the same name that was generated by the same item template. This signifcantly reduces the need for custom item templates.
  • Support for Skyros Skin: If you wan to use the new Skyros skin introduced in JDeveloper 11.1.1.7, you should change the JHS_PAGE_TEMPLATE setting at application level from default/misc/file/jhsPageTemplate.vm to default/misc/file/jhsPageTemplateSkyros.vm. This new template is optmized for the Skyros skin, and also uses the new af:panelGridLayout component.

See the JHeadstart 11.1.1.5 Release Notes for a list of bugs fixed in this release.

See the support matrix for supported JDeveloper releases.
Customers who own a JHeadstart supplement option license can download it from the Consulting Supplement Option portal. 

For a complete list of all JHeadstart features, use this link. For detailed information on all the features, check out the comprehensive JHeadstart Developer's guide. Want to try JHeadstart yourself? Do the tutorial using the JHeadstart evaluation version that you can install using Help -> Check for Updates functionality in JDeveloper.


Monday May 14, 2012

JHeadstart 11.1.2 Evaluation Version and Updated Tutorial Now Available!

Anybody who is interested  in building ADF applications like the experts do, and at the same time wants to increase developer productivity significantly should take a look at the free downloadable JHeadstart 11.1.2 evaluation version. This evaluation version is compatible with JDeveloper 11.1.2.1.x and 11.1.2.2. The best way to evaluate the immense power of this JHeadstart release is to follow the comprehensive tutorial, that is updated for this latest release. The tutorial includes instructions for installing JHeadstart, and has step-by-step instructions so even people with minimal or no ADF/Java experience can follow along. You can also download the completed tutorial application here, in case you don't have the time to go over the tutorial. To run the tutorial application, you do need to install JHeadstart (see the tutorial for instructions) as JHeadstart comes with a powerful Java runtime library (source code is included!). 

For more information on JHeadstart, visit the JHeadstart Product Center.

Enjoy!

Wednesday Feb 29, 2012

Oracle JHeadstart 11.1.1.4 Now Available

Oracle JHeadstart 11.1.1.4 is now available for download (build 11.1.1.4.26).
See the support matrix for supported JDeveloper releases.
Customers who own a JHeadstart supplement option license can download it from the Consulting Supplement Option portal.

This release is mainly a bug fix release. In addition, some small small enhancements have been added: 

  • Enhanced Support for Dynamic Tabs: The implementation of dynamic tabs has been changed and enhanced. There is no longer a dependency on the standard oracle uishell dynamic tabs implementation. A new oracle.jheadstart.view.dyntab.DyntabContext class is now used instead of the oracle.ui.pattern.dynamicShell.TabContext class that supports additional features like updating the document title based on the current tab, setting the maximum number of tabs, and displaying initial tabs.
  • Enhanced Support for Function Keys: New function keys have been added for first row, previous row, next row, and last row, and go to details. In addition when changing a page fragment or tab within a page fragment, the cursor focus will be set on the first item.
  • Control over Generated Value Bindings: At the service level, two new properties have been added. The property Always Generate Form Value Bindings controls whether individual attributeValues bindings are generated for a group that does not have form layout. The property Generate Value Bindings for Hidden Items controls whether a value binding is generated whe the item is hidden. To ensure upwards compatibility the default value of both properties is true, however, if you create a new service definition, both properies are set to false. If one or both if these service-level properties are set to false, you can still force generation of an individual value binding using the two new item properties Generate Form Value Binding and Generate Table Value Binding. Both these new service properties, and new item properties are only visible in advanced mode in the Application Definition Editor.
  • Enhanced Implementation of Dependent Items: In previous releases, dependent items were refreshed using the partialTriggers property. This caused the dependent items to be validated as well as part of the optimized lifecycle, forcing usage of showRequired property rather than the required property to prevent premature client-side validations. In this release, the dependent items are refreshed programtically by adding them as partial target inside the DependsOnItem bean. This means all items can have client-side validations as desired.
  • Enhanced Implementation of Display New Row on Entry: The check whether a new row must be displayed is now performed inside the task flow itself, instead of in the calling task flow. This allows for a proper implementation of the "when no rows found" option in this property.
  • Enhanced Implementation of JHeadstart LOV's: The JHeadstart web-tier LOV implementation has been completely rewritten. The new implementation uses one generic LOV popup per page, with one associated generic LOV task flow binding and one genwric LOV Task flow manager bean. LOV for validation has been implemented using a generic dynamic task flow call (in the task flow template). This new implementation is easier, more robust, and generates significantly less managed beans. The pages will also load faster since every page has only one LOV popup included, instead of separate popups for each and every lov item (which were even repeated for each row in a table)
  • Enhanced Implementation of Custom Properties: Custom properties can now also be accessed using the name of the property (previously labeled description). There are three expression you can now use now, for example for group custom properties you can use:
    • ${JHS.current.group.property1}, this is the existing expression that also works when no name is entered for the property.
    • ${JHS.current.group.getCustomProperty("propertyName")}, where propertyName should be substituted with the name you entered for this property.
    • ${JHS.current.group.propertyName}, where propertyName should be substituted with the name you entered for this property. If you use this expression and the group does not have this custom property defined, you will get an error during generation.
We recommend to use the new second or third expression, these expressions dot not care which custom property number you used to enter the name and value. In addition, if you use the second or third expression, you never run out of custom properties, because you can also enter a comma-delimited list of names and values in the name and value property.

For a complete list of all existing features, use this link. For detailed information on all the features, check out the comprehensive JHeadstart Developer's guide. Want to try JHeadstart yourself? Do the tutorial using the JHeadstart evaluation version.

Friday Feb 10, 2012

Model-based Cascading LOV's For JHeadstart

Written By Peter Koletzke, 8 February, 2012 (posted by Steven)

SCENARIO

While searching for employees, users need to find a department by first finding a location from a City LOV (dropdown list). After selecting a city, the City and Postal Code appear on the screen.  LocationId also returns from the LOV, but is hidden because users should not see the ID.  

Then the user opens a Departments LOV (pop up LOV with query fields), which displays only departments within the selected city. After selecting a department, the Department ID and Department Name are returned to the screen. 

CONCLUSION

Implementing a cascading LOV consists mostly of work in the Model project. It is important that you prove that the cascading LOV works in the Model project before implementing it in the ViewController project. A brief list of the special components and settings needed to implement a cascading LOV follows. 

You can access a detailed recipe for this technique here. A sample application that results from this recipe is here.

MODEL PROJECT

  • Base view object for the Employees entity object: EmployeeMaster
  • Read-only view objects for the Locations LOV and Departments LOV queries
  • View criteria on the Departments LOV to represent a WHERE clause for location_id = :bind_variable
  • Locations and Departments added as reference entity objects to EmployeeMaster
  • Calculated attributes in EmployeesMaster as follows. All have Queryable as “true” and Display Hint as “Display.”
    • LocCity (LOCATIONS.CITY)
    • LocPostalCode (LOCATIONS.POSTAL_CODE)
    • LocLocationId (LOCATIONS.LOCATION_ID)
    • DeptDepartmentName (DEPARTMENTS.DEPARTMENT_ID)
  • Locations LOV on the Employees.LocCity attribute, returns city, location ID (hidden), and postal code
  • Departments LOV on the Employees.DepartmentName, returns DepartmentName and DepartmentId, uses DepartmentsLOV view object accessor with the detail LOV view criteria mentioned above (parameter value = LocLocationId)
  • AutoSubmit UI hint set for the two LOV items: LocCity, DeptDepartmentName
  • Dependencies to LocCity from DeptDepartmentName and DepartmentId (so they clear when the city changes)
  • View criteria on EmployeeMaster for a list of attributes needed in Quick Search area. An additional view criteria is needed for the Advanced Search area. LocLocationId is listed in both view criteria, but its UI Hint for Rendered Mode is “Never.” Deselect Show in List on the UI Hints tab.

VIEWCONTROLLER PROJECT

All actions are in the JHS application definition editor unless noted.

  • Set the LocLocationId item so it does not display in the table or in the form.
  • Set Quick Search View criteria and Advanced Search View criteria properties to the names of the appropriate (but separate) view criteria you created for to list attributes in these search sections
  • Set Depends On Item(s) properties for LocPostalCode as “LocCity,” for DepartmentId as “DeptDepartmentName,LocCity” so the LOV return fields on the edit page are set after an LOV selection.
  • Select the Clear/Refresh Value? property for DepartmentId so it clears when the city or department name changes.
  • For JHS 11.1.1.4: select Clear/Refresh? Value for DeptDepartmentName.
  • For JHS 11.1.1.3: edit adf-config-EmployeeMaster.xml after generation to define a depends-on refresh for DeptDepartmentName.


Wednesday Dec 14, 2011

Core ADF11: Building Highly Reusable ADF Task Flows

In this old post in the Core ADF11 series, I explained the various options you have in designing the page and taskflow structure. The preferred approach in my opinion that maximizes flexibility and reusability, is to build the application using bounded taskflows with page fragments. You then have various ways to disclose these task flows to the user. You can use a dynamic region or dynamic tabs, or a human workflow task list, or even have the user add the task flow at runtime using Webcenter Composer. 

To maximize reuse of individual task flows, there are some simple techniques you can apply:

  • Define a set of input parameters that allows you to configure for the various (re)use cases
  • Define a router activity as the default activity to enable reuse-case-based conditional flows
  • Configure use of dynamic iterator binding to use a task flow both as a master region or detail region
  • Configure display properties of UI components based on task flow input parameters so components can be shown/hidden, editable/readOnly, required/optional, etc based on the specific (re)use case

By applying these techniques, you can dramatically reduce the number of task flows you need to build in your project. In this sample application, you can see how you can reuse the same task flow to support the following reuse cases:

  • Show in read-only mode
  • Enable deeplinking from another page to show one specific row 
  • Use as read-only context info in popup
  • Use as master region as well as detail region 
  • Enable deeplinking from external source like e-mail.

Downloads: 

Friday Oct 07, 2011

Core ADF11: UIShell with Dynamic Tabs

Last update on 28-aug-2013 Sample added for JDeveloper 12.1.2, see bottom of post.

In this old post in the Core ADF11 series, I explained the various options you have in designing the page and taskflow structure. The preferred approach in my opinion that maximizes flexibility and reusability, is to build the application using bounded taskflows with page fragments. You then have various ways to disclose these task flows to the user. You can use a dynamic region that displays the taskflow, as described in this post. You can also go for a more advanced user interface pattern that provides multi-tasking capabilities to the end user by dynamically adding tabs that represent independent tasks for the end user. This patterns is described in more detail here and covers more than only the dynamic tabs. Oracle provides a sample implementation named "Oracle Dynamic Tabs Page Template" of this user interface pattern as an extension to JDeveloper  that can be installed through the JDeveloper Help -> Check for Updates option.  While this implementation might be sufficient in your case, I discovered the need for additional related functionality not provided out-of-the-box by this extension, as well as the need for easier customization options. As I started to implement this pattern at various customers I added more and more functionality to my implementation of this pattern that started off with a more or less one-to-one copy from the Oracle extension implementation. The end result is quite different from the Oracle extension, also because I optimized the implementation for JDeveloper 11.1.2, leveraging the new multiregion binding. For my presentation of this topic at Oracle OpenWorld 2011 I created a showcase application that includes all the code and templates for the dynamic tabs implementation and illustrates all the functionalities my customers asked for, including:

  • Open new tabs in various ways: Using a menu, using a global quick search, from within another tab, and conditionally based on a tab unique identifier that is used to check whether there is already a tab open with the same UID.

  • Close a tab in various ways: using the close icon on the tab, using a close tab button inside the tab region, or auto-closing a tab when the user finished the task.
  • Transaction handling: Each tab should have an independent transaction, a tab needs to be marked dirty with a visual indicator indicating the dirty tab state, and a warning should be shown when the user tries to close a tab with pending changes.
  • Miscelleanous requirements: Update browser window/tab title based on currently selected tab, initially display tabs, prevent tabs from being closed automatically, set maximum number of tabs the user is allowed to open, and update of the tab label based on the current data shown in the region.

If you have similar requirements, then this sample application might be useful to you. You can download the application below, feel free to copy and paste the infrastructure classes, templates and declarative components to your own application. For an explanation of the implementation, see the slides of my OOW presentation.

Downloads: 

Update 13-nov-2012: The implementation in the sample applications has been improved. It is no longer needed to define the managed bean for a tab that is initially displayed in view scope rather than request scope. By improving this implementation of initially displayed tabs, the following issues have been fixed:

  • Closing and re-opening an initially displayed tab caused an NPE (11.1.1.x only)
  • It was not possible to launch another tab from within an initially displayed tab

Update 28-aug-2013: Dynamic Tabs Sample For JDeveloper 12.1.2

Initially, I had problems getting the sample to work in JDev 12.1.2. I logged the following bugs against 12.1.2 that could be reproduced when opening  the 11.1.2 sample in 12.1.2:

  • Bug 17158398 - COMMAND COMPONENTS DO NOT WORK WHEN OPENING REGION IN DYNAMIC TAB
  • Bug 17156672 - UI NOT RENDERED CORRECTLY DUE TO CONTEXT PARAM DEFAULT_DIMENSION
  • Bug 17156560 - JAVA.LANG.ILLEGALSTATEEXCEPTION: COULD NOT FIND COMPONENT TO STREAM
  • Bug 17158597 - UPDATES ARE LOST WHEN DEFINING REGIONCONTROLLER IN PAGEDEF CONTROLLERCLASS PROP

Product development has investigated some of these bugs, and this is the result:

  • The behavior described in bug 17156560 was caused by the fixed value specified for the id property in the af:region tag. Unlike JSP, facelets does not ensure uniqueness when stamping out multiple components, in this case multiple regions inside the af:forEach loop. By removing the id property (facelets will then auto-generate a unique id), or making it unique using an EL expression like id="reg_${vs.index}"  the issue was resolved. See this blog post from Duncan Mills for more info.
  • After applying the fix for bug  17156560 , the behavior reported in bugs 17158398 and 17158597 was no longer seen. These bugs are now closed as "not a bug".
  • The work around for bug 17156672 is simple. The top-level af:decorativeBox in the page template should have the dimensionsFrom property set to "parent" when the DEFAULT_DIMENSIONS context param is set to 'auto' in web.xml. However, since JDeveloper should ensure upwards compatibility, it should never automatically add the DEFAULT_DIMENSIONS web.xml context param to an existing application. So, the bug has been changed to a design-time bug to prevent this from happening. 
With these fixes, the 12.1.2 sample is now working correctly and can be downloaded here.

Tuesday Sep 13, 2011

How to become an Oracle ADF expert in one week (or in 1 day if you don't have so much time)

Oracle ADF is an extremely powerful framework for developing SOA-based web applications. Once you have grasped the key concepts of ADF, it is a real pleasure to work with ADF, and to experience how fast you can build really sophisticated stuff. But......as with any advanced framework, there is a learning curve involved, and I have to admit the ADF learning curve might be experienced as rather steep at times. I am often asked, "how long does it take to become a good ADF developer?", and I usually answer "something between 3-6 months".  The problem is that most project managers don't allow you this time, so you simply start your first ADF project, and find out along the way that you should have chosen a fundamentally different approach to make you application components truly flexible, easy to maintain, and reusable.

Well, Oracle has a one-time-only-unique-offer that allows you to become an ADF expert in one week, and get your ADF app right the first time: Attend Oracle Open World 2011, 2-6 october in San Francisco! The 2011 version of OOW has been proclaimed by the ADF EMG as "Year of the ADF developer" and with good reason. There are lots of good ADF sessions at OOW 2011, a complete overview of all ADF sessions can be found here.

If your employer does not allow you a whole week off from your project, you can go for the sunday-shortcut to become an ADF expert in even one day. The ADF EMG has put together an impressive list of speakers and topics, who will all present on sunday october in Moscone room 2000. See you there! (And don't forget to attend my own presentations on sunday 2.00 PM and wednesday 10.15 AM )

Thursday Jul 28, 2011

JDev 11.1.2: Differences in Table Behavior

While building a simple ADF application in JDev 11.1.2 I encountered some strange runtime behavior. I built another application with the same behavior in exactly the same way in JDev 11.1.1.4 and there things worked smoothly. However, in JDev 11.1.2, the addRow and deleteRow functions didn't work as expected. In this post I will share my tough journey in founding out what was happening, and discuss the difference in behavior and the changes required to make it work in JDev 11.1.2.

When using the add row button (the green plus icon in the screen shot below) an error message for the required JobId dropdown list was shown immediately.

Some investigation using the Google Chrome Developer tools revealed that two requests instead of one are sent to the server, with apparently the second request causing the validation error to appear. (Although, the validation error is a client-side error, so still not sure how the second request can trigger the error.)

At first I thought this was caused by the partialSubmitproperty on the addRow button, which was set to true. Setting this property to false (or removing this property) fixed this problem, but caused table rendering to hang. Weird, but I didn't investigate that further. I decided to build the same app in JDev 11.1.1.4 which worked smoothly and then opened this app in JDev 11.1.2. After the auto-migration, I ran the app but much to my surprise the "Selection required" message didn't show up. I compared the page and page definition of both apps over and over again, and couldn't see any difference.  Eventually, I started comparing all the files in both projects. This lead me to the adf-config.xml file, located in the .adf directory under the root directory of the application, also visible under the Resources panel. In this file, one property existed in the JDev 11.1.2 application that was not present in the JDev 11.1.1.4 version: changeEventPolicy="ppr".

By removing this property, things started to work again, and only one request was sent again.

Note that the really tricky thing here is that when you upgrade an application from JDev 11.1.1.4 this property does not get added, but new JDev 11.1.2 apps will have this property setting, causing difference in behavior between a migrated app and a new app. At this point, my recommendation is to remove this property (or set it to none) for new JDev 11.1.2 apps. If memory serves me well, in some JDev 11.1.1.x version, dragging and dropping a data a table on a page, added the changeEventPolicy="ppr" property to the iterator binding in the page def. In a later JDev 11.1.1.x release this property was gone again. Looks like it is back in a different form (this time in adf-config.xml), but still with undesirable implications. 

The next error I hit was in the delete confirmation dialog, when trying to delete a row. Regardless of which button I pressed (Yes or No), I got validation errors on the underlying new row, and the dialog was not closed, nor was the row removed.

Now, I think this error has to do with the ADF Faces optimized JSF lifecycle.  Since the table needs to be refreshed when the row is removed by clicking yes in the dialog, the af:table component  requires a partialTrigger property that refers to the af:dialog element. With this partialTrigger property in place the ADF JSF optimized lifecycle causes the table items to be submitted (and validated) as well when clicking the Yes or No button in the dialog. Now,I am speculating here, but may be this wasn't supposed to work at all in JDev 11.1.1.4, but it did because of a bug in the optimized lifecyle code, that has now been fixed in JDev 11.1.2...?

Anyway, what feels like the most logical and easy way for me to solve this issue, is setting the immediate property on the af:dialog to true, so the dialog listener method would skip the JSF validation phase. However, the af:dialog element does not have such a property (logged enhancement request).  Two other solutions remain:

  • No longer use the dialoglistener property, but instead define custom Yes/No buttons using the toolbar facet on the af:dialog. On these buttons I can set the immediate property to true, bypassing client-side and server-side validation.
  • Do not specify the af:dialog as partial trigger on the af:table component, instead, add the table or a surrounding layout container element as partial target programatically after deleting the row. This is the solution I chose, since it only required one line of code in the managed bean class that deletes the row.

Links and references:

Thursday Jul 07, 2011

Core ADF11: UIShell with Menu Driving a Dynamic Region

In this old post in the Core ADF11 series, I explained the various options you have in designing the page and taskflow structure. The preferred approach in my opinion that maximizes flexibility and reusability, is to build the application using bounded taskflows with page fragments. You then have various ways to disclose these task flows to the user. You can use an dynamic tabs as described in this post. You can also embed the taskflows using a dynamic region in a page. The application menu then drives the content of the dynamic region: clicking a menu option will load another taskflow in the dynamic region.

 The initial drawback of this approach is that it adds some additional complexity:

  • You can no longer use standard JSF navigation with your menu, there are no pages to navigate to, only regions
  • The XMLMenuModel, an easy way to define your menu structure in XML, cannot be used as-is. The selected menu entry when using the XMLMenuModel is based on the current page, and in our design, the whole application consists of only one page, the UIShell page.
  • The dynamic region taskflow binding should contain a list of all parameters of all taskflows that can be displayed in the dynamic region.

    This is a rather ugly design, and the developer of the UIShell page would need to know all the parameters of all taskflows that might be displayed in the dynamic region. A cleaner implementation is to use the parameter map property against the taskflow binding. However, when using the parameter map, you need to do the housekeeping of changed parameter values yourself when you want the taskflow to refresh when parameters change. In other words, just specifying Refresh=ifNeeded on the taskflow binding no longer works because ADF does not detect changes in a parameter map.

Fortunately, you can address this complexity quite easily by creating some simple, yet powerful infrastructure classes that hide most of the complexity from your development team. (The full source of these classes can be found in the sample application, download links are at the bottom of this post)

  • A DynamicRegionManager class that keeps track of the current task flow and current parameter map 
  • A TaskFlowConfigBean for each task flow that contains the actual task flow document path, the task flow parameters and a flag whether the parameter values have been changed.
  • A RegionNavigationHandler that subclasses the standard navigation handler to provide JSF-like navigation to a region taskflow.
  • A RegionXMLMenuModel class that subclasses the standard XMLMenuModel class to ensure the proper menu tab is selected based on the currently displayed taskflow in the dynamic region. 

The following picture illustrates how this UIShell concept works at runtime.

The UIShell page (with extension .jsf in JDeveloper 11.1.2 and with extension .jspx in JDeveloper 11.1.1.x) contains a dynamic region. The taskflow binding in the page definition of UIShell gets the currently displayed taskflow from the DynamicRegionManager class that is registered as a managed bean under the name mainRegionManager. The actual task flow id and task flow parameters are supplied by the TaskFlowConfigBean. The DynamicRegionManager manages the current taskflow based on a logical name, for example Jobs. When method setCurrentTaskFlowName is called on the DynamicRegionManager with value Jobs (and we will later see how we use the RegionNavigationHandler to do this), the DynamicRegionManager looks up the corresponding TaskFlowConfigBean by suffixing the Jobs task flow name with TaskFlowConfig.he methods getCurrentTaskFlowId and getCurrentParamMap and currentParamMapChanged then obtain and return the correct values using the JobsTaskFlowConfig bean.

Using this technique, you can configure your dynamic region completely declarative, there is no need to write any Java code. All you need to do is configure the mainRegionManager and task flow config beans, as shown below. 

In this sample, I configured the required managed beans in adfc-config.xml. When using ADF Libraries that contain task flows you want to show in the UIShell dynamic region, it is more elegant to define the TaskFlowConfigBean inside the ADF library. I usually define this bean in the adfc-config file of the task flow itself, below the  <task-flow-definition/> section.  It needs to be outside this section, otherwise the bean cannot be found by the DynamicRegionManager bean that is defined in the unbounded task together with the UIShell page. The advantage of this approach is that the config bean is placed in the same file as the task flow it refers to, the disadvantage is that beans defined outside the </task-flow-definition> section are not visible in the overview tab of a bounded task flow.

To set the current task flow name on the DynamicRegionManager, we use a custom RegionNavigationHandler class that you register in the faces-config.xml.

This class extends the default navigation handler, and overrides the handleNavigation method. The code is shown below. If the outcome contains a colon, the part after the colon contains the task flow name that should be set in the dynamic region.


With this class in place, we can use the action property on command components again to do region navigation, just like we are used to for normal JSF navigation, or navigation between page fragments inside a bounded task flow. The complete flow is as follows:

  • The menu item has the action property set to uishell:Jobs.
  • The region navigation handler set the current task flow name on the Dynamic region manager to Jobs (and navigates to UIShell page if needed) 
  • The dynamic region manager picks up the current task flow id and current parameters from the JobsTaskFlowConfig bean.

The last part of the puzzle is the RegionXMLMenuModel class that subclasses the standard XMLMenuModel class. This class overrides the getFocusRowKey method to return the focus path based on the current task flow region name.

With this class defined in the menu model managed bean, the menu will correctly display the selected tab.   

In a future post I will discuss how the same concepts can be applied to a UIShell page with dynamic tabs.

Downloads:

Thursday Jun 23, 2011

Some More New ADF Features in JDeveloper 11.1.2

The official list of new features in JDeveloper 11.1.2 is documented here. While playing with JDeveloper 11.1.2 and scanning the web user interface developer's guide for 11.1.2, I noticed some additional new features in ADF Faces, small but might come in handy:

  •  You can use the af:formatString and af:formatNamed constructs in EL expressions to use substituation variables. For example: 
    <af:outputText value="#{af:formatString('The current user is: {0}',someBean.currentUser)}"/>
    See section 3.5.2 in web user interface guide for more info.

  • A new ADF Faces Client Behavior tag: af:checkUncommittedDataBehavior. See section 20.3 in web user interface guide for more info. For this tag to work, you also need to set the  uncommittedDataWarning  property on the af:document tag. And this property has quite some issues as you can read here. I did a quick test, the alert is shown for a button that is on the same page, however, if you have a menu in a shell page with dynamic regions, then clicking on another menu item does not raise the alert if you have pending changes in the currently displayed region. For now, the JHeadstart implementation of pending changes still seems the best choice (will blog about that soon).

  • New properties on the af:document tag: smallIconSource creates a so-called favicon that is displayed in front of the URL in the browser address bar. The largeIconSource property specifies the icon used by a mobile device when bookmarking the page to the home page. See section 9.2.5 in web user interface guide for more info. Also notice the failedConnectionText property which I didn't know but was already available in JDeveloper 11.1.1.4.

  • The af:showDetail tag has a new property handleDisclosure which you can set to client for faster rendering.

  • In JDeveloper 11.1.1.x, an expression like #{bindings.JobId.inputValue} would return the internal list index number when JobId was a list binding. To get the actual JobId attribute value, you needed to use #{bindings.JobId.attributeValue}. In JDeveloper 11.1.2 this is no longer needed, the #{bindings.JobId.inputValue} expression will return the attribute value corresponding with the selected index in the choice list.
Did you discover other "hidden" new features? Please add them as comment to this blog post so everybody can benefit. 

Wednesday Mar 16, 2011

Oracle JHeadstart 11.1.1.3 Now Available

[Read More]
About

Java EE Consultants - JHeadstart, ADF, JSF

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today