Posts

Showing posts from March, 2011

Displaying an edit dialog on double click of a table row

Image
Let me share an interesting use case this time. There is read only table with an 'edit' link enabled for each row. The end user can open up the edit dialog either by clicking on this edit link or by double clicking on the table's row as shown in the following screen shot.


Download

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R1 PS3 + HR Schema]

A glance at the implementation

Implementation of edit dialog and displaying the same on click of <af:commandLink> is straight forward and doesn't need any explanation. Please see the tag doc for <af:popup> if you are looking for a detailed explanation on this. The trickiest part is showing the dialog with the selected row's data when user double clicks on a row. This is done by using <af:clientListener> to invoke javascript method. This client side method queues AdfActionEvent on the commandLink. Thanks to Kamran Kashanian for sharing this tip. Please take a look at the…

Customizing Business Components Error Messages

Image
Customization of business components error messages are well documented in Fusion Developer's Guide 37.8 Customizing Business Components Error Messages. I would like to add a couple of points more here :)

If you want to customize the display of DB level errors such as unique constraint violation, foreign key constraint violation etc by providing your own meaningful messages, then along with the steps mentioned in the Developer's Guide you may need to touch one more guy who is responsible for displaying the classic error messages. I'm talking about the ErrorHandler class (DCErrorHandlerImpl) provided by the binding layer.

To get a clear picture, let us take a step back and see the role of ErrorHandler class at run time. When your business method throws error, binding layer intercepts that and puts the 'configured' ErrorHandler(default is DCErrorHandlerImpl) class in to action. The ErrorHandlerClass is responsible for formatting the exception in a human readable…

<af:setPropertyListener> fails when used with <af:showPopupBehavior> for a button's action !

I've discussed a possible reason for <af:setPropertyListener> not to work on <af:popup> when used along with childCreation="deferred" in one of my previous post. In today's post, I'm again taking you back to yet another unsupported usage of <af:popup> :-). In this case, the popup triggering part looks like as shown in the following page snippet. Apparently, here the expectation is to initialize 'someVariable' before showing the popup.

<af:commandButton text="Show Popup" id="cb6"> <af:setPropertyListener from="#{'something'}" to="#{pageFlowScope.someVariable}" type="action"/> <af:showPopupBehavior popupId="p1"/> </af:commandButton>
However the above fails to initialize the property before showing the popup. Why?

The reason is well documented under 'Cancels Client Events' of the <af:showPopupBehavior> tag doc.

The showPopupB…

How to stretch a column in a dynamically generated <af:table>

I happened to notice an interesting thread in an internal discussion forum on last week. Question was, how to stretch a column in a dynamically generated <af:table>? Andrew Robinson provided an elegant solution for this query. I'm copying the same idea here as well for your reference.

If you want to stretch a column in a dynamically generated table, then one possibility is to use an EL to fix the component ID to an 'Identifier' that changes per forEach iteration. Please see the below given tag snippet to get a more clear picture on the implementation part.

<af:table rows="#{bindings.DynamicVO.rangeSize}" fetchSize="#{bindings.DynamicVO.rangeSize}" emptyText="#{bindings.DynamicVO.viewable ? 'No data to display.' : 'Access Denied.'}" var="row" rowBandingInterval="0" columnStretching="column:clmn1" value="#{bindings.DynamicVO.collectionModel}"…

Programmatically disclosing nodes in a <af:tree>

Image
Programmatically disclosing nodes in a <af:tree> is a very common use case in Rich Inernet Applications. I'm sharing an example (built using ADf Faces) illustrating three different use cases on this topic.

1. Expand all nodes of a <af:tree> component
2. Collapse all nodes of <af:tree> component
3. Expand specific nodes of <af:tree> component


Download

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R1 PS3 + HR Schema]

A glance at the implementation

1. Expand all nodes of a <af:tree>

This disclosed behavior of a tree component is controlled by the DisclosedRowKeys of tree component. The below shown method make use of constructor RowKeySetTreeImpl(boolean addAll) to create instance of RowKeySet having all rowKeys added. Please note that, if the parameter 'addAll' is true, every rowKey is initially added to this RowKeySet. This effectively would result in disclosure of all nodes when the tree is displayed.

public …

Overriding ViewObjectImpl::rowQualifies(...) for in memory filtering of child nodes of a tree component

Image
You can override ViewObjectImpl::rowQualifies(ViewRowImpl vr) for filtering the uncommitted data rows based on some specific business use cases/conditions. This feature is pretty useful if you need to filter the child rows having uncommitted changes while executing the ViewLink(s). I'm sharing a simple example illustrating the usage of ViewObjectImpl::rowQualifies(ViewRowImpl vr) for filtering the rows in memory. Requirement is to not to show the Employee nodes of a 'Department-Employee Tree' component having status='DELETE'(even before committing the transaction). This example overrides rowQualifies(...) to restrict the employee entities with 'DELETED' status from adding to the query result.

/** * Evaluates whether the view row qualifies the view object's row match * and in-memory filter view criteria. * <p> * * This method is invoked on new view rows as well as view rows coming * from query to see if the view row should be add…

Using <af:quickQuery> component for filtering child nodes of a tree

Image
In todays post I'm sharing some tips to intercept the query execution of <af:quickQuery> to generate custom queries for filtering child nodes of a tree component. I do have a screen as shown in the following screen shot. The left pane of panelSplitter displays tree table with Department-Employee hierarchy. The <af:quickQuery> (displayed on top) is built by dragging and dropping the 'All Queriable Attributes' of the Employee View Object instance. The same Employee View Object instance is displayed on right side of the panelSplitter.


Download

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11g R1 PS3 + HR Schema]

A glance at the implementation

This sample uses a custom queryListener method for the <af:quickQuery> to intercept the search action. This custom method executes the associated default search binding. Apart from this part, the method is also responsible for adding the hooks for filtering the child nodes -Employees reco…

ADF Mobile Client extension is now available for public download !

Much awaited ADF Mobile Client extension is now available under the JDeveloper download center(Go to JDeveloper main menu -> Help -> Check for Updates). This extension is built on top of JDeveloper 11.1.1.4.0. Give a try, its really promising stuff !

What you may need to know about pagination support in EJB and JavaBean Data Control

Once you application's business service is in place, you can use JDeveloper to create data controls that provide the information needed to declaratively bind UI components to those service. This meta information is also used by the ADF model layer to invoke the business services at run time. The Data Control act as a Proxy Cum Adaptor for your business services. ADF has built in support for most of the common technologies like EJB, Web services, POJO, ADF BC etc. This means that, you may get consistent development experience across these technologies, and moreover your application's view layer may remain decoupled from the business service implementation. In todays post, I'm discussing pagination support for EJB and JavaBean Data Control.

How to create Data Control?

Please refer Chapter 2 - ADF Model Data BindingJava EE Developer's Guide to learn more if you don't have much idea on this topic. This concept remains same for both EJB and JavaBean Data Controls.

Pag…

Retrieving ViewCriteria from a custom queryListener method

You can leverage the built in functionalities of <af:quickQuery> or <af:query> component to build search functionalities for your screen. Sometimes you may need to intercept the query invocation using queryListener of the query component as shown below.

<af:quickQuery label="Search" id="search" value="#{bean.queryDescriptor}" queryListener="#{someBean.processSomeQuery}"> <f:facet name="end"> <af:commandLink text="Advanced"/> </f:facet> </af:quickQuery>
In today's post I'm sharing some code snippets which may help you to retrieve model part of the </af:quickQuery> component.

public void processSomeQuery(QueryEvent queryEvent) { QueryDescriptor qd = queryEvent.getDescriptor(); AttributeCriterion criterion = qd.getCurrentCriterion(); /** Gets the currently keyed in search …

Initializing the bind variables used for an LOV query

Image
This post is continuation of one of my previous post on LOV run time. Today, I'm sharing another approach for initializing the bind variable used in an LOV query.

This example has an LOV defined for DepartmentId attribute of Employee View Object.


LOV query comes from Department View Object, and the 'where' clause has a bind variable defined as shown below.

SELECT Departments.DEPARTMENT_ID,
Departments.DEPARTMENT_NAME,
Departments.MANAGER_ID,
Departments.LOCATION_ID
FROM DEPARTMENTS Departments
WHERE ( Departments.LOCATION_ID = :bindVarLocId OR :bindVarLocId IS NULL )

How do you set bind variable value in the above case (when used in a LOV query)?

One possibility is to let the bind variable to read the value from User Session Data. In this case, you can supply the bind variable value at run time by putting in to ApplicationModule's User Session Data HashMap as shown in the following code snippet. You may need to expose this method (defined on AM) to the client as w…

Passing dynamic parameters to the Java Script method in a Fusion Web Application

In this post, I'm sharing some tips to pass dynamic parameters values to a Java Script method. The idea is inspired by an example from Frank Nimphius. Solution is to use <af:clientAttribute> to associate the parameter and value with the component which triggers the event. When using af:clientAttribute the parameter can be accessed on the client through AdfUIComponent.getProperty("ParameterName"). The rich client framework takes care of marshaling the attribute value to the client. Also, the below code uses 'closure' in the JavaScript method to ease the coding.

<af:resource type="javascript"> function someMethod(arg) { return function (evt) { var finalArg = evt.getSource().getProperty('SomeDynamicArg') + ' : ' + arg; alert(finalArg); evt.cancel(); } } </af:resource> <af:commandButton text="SomeActionBtn" id="cb1"> <af:clientListener typ…

ADFc: No outcome metadata specified for method call activity 'null' !

Image
While defining task flow method activities by EL binding to a method in managed bean, there are certain things you need to be aware of. These points are well documented in Fusion Developer's Guide under 15.5 Using Method Call Activities.

I'm explaining a very common mistake when you EL bind a manged bean method as method activity for a task flow. In this case, if your method return some status message and you want to control navigation cases based on this outcome, its required to specify 'toString()'[displayed under Outcome group] as 'true' from the drop down list, as shown in the following screen shot.


<method-call id="someMethodCall"> <method>#{backingBeanScope.managedBean1.doSomething}</method> <outcome id="__16"> <to-string/> </outcome> </method-call>
to-string: If specified as true, the outcome is based on calling the toString() method on the Java object returned by the me…

Disclaimer

The views expressed on this blog are my own and do not necessarily reflect the views of my employer.