Showing posts with label ADF Faces. Show all posts
Showing posts with label ADF Faces. Show all posts

25 May 2011

When disclosureListener of a panelTabbed's showDetailItem is fired?

Interestingly enough someone would expect that the disclosureListener of the tab that was clicked/selected would only be fired/kicked off. This is not true though as described in one more very good post (in Greek) by Serafim Karapatis.
What really happens is that the disclosureListenerof all tabs (panelTabbed's showDetailItems) will be fired. And in order to resolve which tab was selected, you should use disclosureEvent.isExpanded()method.
eg.

public void tabSelected(DisclosureEvent disclosureEvent) {
   if (disclosureEvent.isExpanded()) {
        ...
   }
}

Please check also the documentation of showDetailItem.

28 February 2011

Run your Fusion ADF applications without navigation controls (Back button e.t.c.)

In many cases the Navigation Controls (Back button e.t.c.) can produce problems in a Fusion ADF application.

If you have built you app to use Firefox (yes some ADF Rich Faces do not behave the same under IE), you can check a great add on for Firefox called Firefox Prism. More here.

21 January 2011

Debug ADF Rich Faces

For debugging Rich Faces using Firebug check
"Advanced Javascript debugging with FireBug and analyzing your page with View Source Chart"


The following sections in the Developer's Guide may help you in understanding how the javascripts are generated, and also set up some options for debugging (org.apache.myfaces.trinidad.DEBUG_JAVASCRIPT f.ex.):

1.2.1.2 JavaScript Library Partitioning
http://download.oracle.com/docs/cd/E15523_01/web.1111/b31973/gs_intro.htm#BABJGCAI

A.9 Using JavaScript Library Partitioning
http://download.oracle.com/docs/cd/E15523_01/web.1111/b31973/ap_config.htm#BABCJIDJ

and other documents like:

"Oracle Application Development Framework Performance Tuning" in the "Oracle Fusion Middleware Performance and Tuning Guide"
http://download.oracle.com/docs/cd/E16764_01/core.1111/e10108/adf.htm#CIHHGADG


What is org.apache.myfaces.trinidad.CLIENT_STATE_MAX_TOKENS?


According to "Configuring Apache Trinidad" documentation
 In "token"-based client-side state saving, chooses how many tokens should be preserved at any one time. The default value is 15. When this is exceeded, state will have effectively been "forgotten" for the least recently viewed pages, which can impact users that actively use the Back button or that have multiple windows open simultaneously. Developers building HTML applications that rely heavily on frames will likely need to increase this value.

Also there is an nice explanation found on OTN by Simon Lessard
As for client side vs. server side, using Trinidad, there's little difference. But let me do a small recap:

JSF 1.1
server = a single view saved on the server, extremely back button error prone
client = the whole view is saved on the client, increasing network latency by increased request and response size.

JSF 1.2
server = view is Serialized on the server and identified by a token on the client. Efficient and quite back button safe, unless the user click many times on back then the threshold get busted and ViewExpiredException is thrown.
client = the whole view is saved on the client, increasing network latency by increased request and response size.

ADF Faces
server = a single view saved on the server, extremely back button error prone.
client = view is Serialized on the server and identified by a token on the client. Way more efficient than default client saving, but then again there's a threshold like JSF 1.2 server state saving.

Trinidad 1.2.x
server = a single view saved on the server, extremely back button error prone.
client = depends on org.apache.myfaces.trinidad.CLIENT_STATE_METHOD:

org.apache.myfaces.trinidad.CLIENT_STATE_METHOD:
token (default) = same as server side as of JSF 1.2, but you can control the amount of token with org.apache.myfaces.trinidad.CLIENT_STATE_MAX_TOKENS parameter;
all = default client state saving.

Finally, from Appendix A - ADF Faces Configuration of Oracle® Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework 11g Release,
you can see a wider aspect of state saving in ADF
A.2.3.1 State Saving
You can specify the following state-saving context parameters:
  • org.apache.myfaces.trinidad.CLIENT_STATE_METHODSpecifies the type of client-side state saving to use when client-side state saving is enabled by using javax.faces.STATE_SAVING_METHOD. The values for CLIENT_STATE_METHOD are:
    • token: (Default) Stores the page state in the session, but persists a token to the client. The simple token, which identifies a block of state stored back on the HttpSession object, is stored on the client. This enables ADF Faces to disambiguate the same page appearing multiple times. Failover is supported.
    • all: Stores all state information on the client in a (potentially large) hidden form field. It is useful for developers who do not want to use HttpSession.
    Performance Tip:
    Client-side state saving is recommended. However, because of the potential size of storing all state information, it is recommended that you set client-state saving to token.
  • org.apache.myfaces.trinidad.CLIENT_STATE_MAX_TOKENS: Specifies how many tokens should be stored at any one time per user, when token-based client-side state saving is enabled. The default is 15. When the number of tokens is exceeded, the state is lost for the least recently viewed pages, which affects users who actively use the Back button or who have multiple windows opened at the same time. If you are building HTML applications that rely heavily on frames, you would want to increase this value.


20 January 2011

TROUBLESHOOTING: "Because of inactivity, your session has timed out and is no longer active..."

Last updated: 7/4/2011

Problem
The following error might occur will navigating to your app.


Solution
One of the reason might be that org.apache.myfaces.trinidad.CLIENT_STATE_MAX_TOKENS value is not great enough.

Add the following param in your web.xml and setting according to yourneeds:


Memory consuption
What about memory consuption? See my related pos: Memory consumption of org.apache.myfaces.trinidad.CLIENT_STATE_MAX_TOKENS

Theory
For some theory behind CLIENT_STATE_MAX_TOKENS check my related post "What is org.apache.myfaces.trinidad.CLIENT_STATE_MAX_TOKENS?"





Dig more:

19 January 2011

ADF Faces Memory Scopes

Scopes in the context of pages(jspx)

Scopes in the context of fragments(jsff)


6 Types of Memory Scopes
There are six types of memory scopes in a Fusion web application:


  • Application scope: An application scope object is available for the duration of the application and is shared among users. This scope may be used to hold static objects that are the same for all users.
  • Session scope: The object is available for the duration of the session, which is user instance-specific. A use case for a session scope bean is a user info bean that stores information about a user, which is read from the database or an LDAP server, to avoid unnecessary queries.
  • Page flow scope: A pageFlow scope exists for each task flow instance and has a lifespan between request and session scope. The lifetime of the scope spans across all pages in a bounded task flow.
  • Request scope: The object is available from the time an HTTP request is made until a response is sent back to the client. From another perspective, a request scope starts with a request to be issued from one view to another for navigation cases that don't perform a redirect but a default server-side forward. The scope spans across all non-view activities that follow the view of interest to the next view activity.
  • Backing bean scope: The backing bean scope is comparable to the request scope, with the difference in that it exists for a specific client component. In general, all managed beans used in reusable components should be configured to backingBean scope. For example, bounded task flows that are designed to be regions on a page should use the backingBean scope if more than one instance of the task flow is expected to be on a single page.
  • View scope: The object is available until the view ID for the current view activity changes. This becomes handy when you use partial page rendering. If you have a dependent list box, you might send a server request to refresh the list box. When a response is returned, the request scope will be gone but the view scope will be still there. Therefore, view scope can be used to store data when partial rendering request comes back. The view scope exists not only for views that are rendered by JSPX pages, but also for views rendered by page fragments, as is the case in task flows that are built to execute in a region. The view scope of the parent page is not accessible from components added to a page fragement in a region, and the view scope of a view in a region is not accessible for the parent page.

Dig more:

30 November 2010

Comparison of JSF 2.0 with ADF Faces & JSF 2.0 Adoption Roadmap

Quoting Chris Muir:
Oracle has released documentation around it's future JSF 2.0 support in the future
JDeveloper 11.1.2 release.  You can read the complete whitepaper here:



http://www.oracle.com/technetwork/developer-tools/adf/learnmore/adffaces-jsf20-190927.pdf


src: ADF Enterprise Methodology Group

04 November 2010

Get pageFlowScope instance and set params

1st way (prefered)
Map pfs = AdfFacesContext.getCurrentInstance().getPageFlowScope();
pfs.put("paramName",value);

2nd way 
JSFUtils.setManagedBeanValue("pageFlowScope.paramName", value);

03 November 2010

TROUBLESHOOTING: af:showPopupBehavior raises the popup although the parent action component is disabled

Scenario:
The following will raise the component
eg

< af:commandToolbarButton   ... 
              disabled="true"
              icon="/images/icon.png"
              disabledIcon="/images/disableIcon.png"                
              ... >
               < af:showPopupBehavior popupId="Popup"
                                    triggerType="click" />
</af:commandToolbarButton >     

Note: that the command component will be disable and will be rendered with the disable icon



Solution:
In order to not raise the pop use  triggerType="action"

< af:commandToolbarButton   ... 
              disabled="true"
              icon="/images/icon.png"
              disabledIcon="/images/disableIcon.png"                
              ... >
               < af:showPopupBehavior popupId="Popup"
                                    triggerType="action" />
</af:commandToolbarButton >     


Below is part of the documentation in order to help you understand why. Probably is because of the "the component will still raise the action event."

Client Event Trigger Types

The following table lists component family-specific event types that can be assigned to the triggerType attribute:

Event TypeComponent FamilyDescription
actionCommandFires when user triggers the command component. Owning component's server-side action listeners will be ignored since the event will be canceled.
...

The following table lists input (mouse/keyboard) event types. These events are delivered for all components (though in some cases may be consumed by the peer implementation) and can be assigned to the triggerType attribute:

Event TypeDescription
clickFires when user clicks on component. When the event source is a command family component, the component will still raise the action event.

Links:

02 November 2010

Perform actions each time a row in a table is selected

In page:
Set in the af:table component a custom selection Listener


In backing:
    public void rowSelectionListener(SelectionEvent selectionEvent) {
        //Calling parent method, to make the selection
        String operation = "#{bindings.VO.collectionModel.makeCurrent}";
        JSFUtils.invokeMethodExpression(operation, Object.class,
                                        SelectionEvent.class, selectionEvent);
        //do whatever else you want
    }

15 October 2010

Disable an af:menu when all of its children are disabled


If you have a  requirement that a menu which has all of its children (menu items , go menu items , sub menus) disabled then the menu should also be disabled, then instead of writing the same conditions that you had to the children to the menu (boring and error prone) you can just use the following.


1. 
bind the af:menu to the backing bean, that is the binding prop eg. 
binding="#{myBacking.myMenu}"

2. 
set the disable property of the af:menu to a backing bean property e.g. 
disabled="#{myBacking.myMenuDisabled}"
where the the backing bean method is 
public boolean isMyMenuDisabled() {
return isMenuDisabled(this.myMenu);
}

3.
In the backing property method use the following method (you can decide if it should be placed to a generic class eg Backing beans Super class or in a Utils class as a statis method (e.g. like methods in ADFUtils))
/**

* In order to be disabled ALL children (&&) must be disabled
* @param menu
* @return
*/
protected boolean isMenuDisabled(RichMenu menu) {
 boolean isDisabled = true;
 List children = menu.getChildren();
 logger.debug("parse children ");
 Iterator iter = children.iterator();
 while (iter.hasNext()) {
  Object o = iter.next();
  if (o instanceof RichMenu) {
   RichMenu childMenu = (RichMenu)o;
   logger.trace("Found submenu with id: "+childMenu.getId());
   boolean isChildMenuDisabledProperty = childMenu.isDisabled();
   if (isChildMenuDisabledProperty ) {
    isDisabled = isDisabled &&    isChildMenuDisabledProperty;
    logger.trace("submenu with id:"+childMenu.getId()+" returned  (prop based) : " +
    isChildMenuDisabledProperty);
   }
  else {
   boolean isChildMenuIsDisabled = isMenuDisabled(childMenu);
   isDisabled = isDisabled && isChildMenuIsDisabled;
   logger.trace("submenu with id:"+childMenu.getId()+" returned   (parsed) : " + isChildMenuIsDisabled);
  }
 } else if (o instanceof RichCommandMenuItem) {
   RichCommandMenuItem menuItem = (RichCommandMenuItem)o;
   isDisabled = isDisabled && menuItem.isDisabled();
   logger.debug("Found menuItem with id: " + menuItem.getId() + " and disabled condition: " +
   menuItem.isDisabled());
 } else if (o instanceof RichGoMenuItem) {
   RichGoMenuItem goMenuItem = (RichGoMenuItem)o;
   isDisabled = isDisabled && goMenuItem.isDisabled();
   logger.debug("Found gomenuItem with id: " + goMenuItem.getId() + " and disabled condition: " +
  goMenuItem.isDisabled());
 } else if (o instanceof RichSeparator) {
  logger.debug("separator found. ingnoring...");
 } else {
   logger.info("Not Supported. Menu Item can only have: menu,   menuItem, goMenuItem ot separator.");
   }
  }
 return isDisabled;
}
It supports that the menu can have as its children:
° Sub menus
° menuItems
° goMenuItems

You can check other props also like visible and rendered prop.

PS: this was a repost from my other blog

TROUBLESHOOTING: Reset the values of the UI components in order to get refreshed from model

Problem 
We have a af:popup that its value should be cleared its time it was raised.
The fields of the popup were based on transient attributes of SQL Based VO.
For that reason each time the popup was raise the VO was executed (to take its initial values)
The problem was that in hte popup the values were not cleared.

Solution
 I came across this excellent post
http://adfbits.blogspot.com/2008/11/sticky-popup-values.html
 Using the following method after executing the SQL based VO (below is the function a bit modifying):
public void resetStaleValues(UIComponent rootComponent){
  Iterator iter = rootComponent.getFacetsAndChildren();
  while (iter.hasNext()) {
   UIComponent component = iter.next();
   if (component instanceof UIXEditableValue) {
     UIXEditableValue uiField = (UIXEditableValue)component;
   uiField.resetValue();
   //a little mod here: Also refesh the component
   RequestContext.getCurrentInstance().addPartialTarget(uiField);

  }
   resetStaleValues(component);
}

You can also enrich  your code by including functinality to set value null with methods like:

12 October 2010

Keep Popup open even if you navigate to another page and return or set autocanel prop

Scenario:

You are in a page where you open an af:popup
In the af:popup there is a button that navigates to another TF and
when you returned from the TF you want to have the popup open as you left it

Solution

Use autoCancel=disabled
eg
  <af:popup ... autoCancel="disabled" ... >

You might also like:

Related Posts Plugin for WordPress, Blogger...